src/lib/MSPUBCollector.cpp | 160 ++++++++++++++++++++++++++++++++------------- src/lib/MSPUBParser.cpp | 7 + 2 files changed, 124 insertions(+), 43 deletions(-)
New commits: commit 82f18199d17bb4da46b2728f7dfc477eac984bc2 Author: David Tardon <[email protected]> Date: Sun Dec 28 14:05:49 2014 +0100 BIPU handling of tables Change-Id: I99b127f651c20d7024a3f7db881b386424f334d0 diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp index 53ef937..04f5b6c 100644 --- a/src/lib/MSPUBCollector.cpp +++ b/src/lib/MSPUBCollector.cpp @@ -150,6 +150,8 @@ void MSPUBCollector::setShapeTableInfo(unsigned seqNum, const TableInfo &ti) { m_shapeInfosBySeqNum[seqNum].m_tableInfo = ti; + if (!m_tableCellTextEndsVector.empty()) + m_shapeInfosBySeqNum[seqNum].m_tableCellTextEnds = m_tableCellTextEndsVector.back(); } void MSPUBCollector::setShapeNumColumns(unsigned seqNum, @@ -482,6 +484,7 @@ boost::function<void(void)> MSPUBCollector::paintShape(const ShapeInfo &info, co bool hasFill = fill != "none"; boost::optional<std::vector<TextParagraph> > maybeText = getShapeText(info); bool hasText = bool(maybeText); + const bool isTable = bool(info.m_tableInfo); bool makeLayer = hasBorderArt || (hasStroke && hasFill) || (hasStroke && hasText) || (hasFill && hasText); if (makeLayer) @@ -863,57 +866,128 @@ boost::function<void(void)> MSPUBCollector::paintShape(const ShapeInfo &info, co { props.insert("librevenge:rotate", textRotation * 180 / M_PI); } - Margins margins = info.m_margins.get_value_or(Margins()); - props.insert("fo:padding-left", (double)margins.m_left / EMUS_IN_INCH); - props.insert("fo:padding-top", (double)margins.m_top / EMUS_IN_INCH); - props.insert("fo:padding-right", (double)margins.m_right / EMUS_IN_INCH); - props.insert("fo:padding-bottom", (double)margins.m_bottom / EMUS_IN_INCH); - if (bool(info.m_verticalAlign)) + + if (isTable) { - switch (info.m_verticalAlign.get()) + m_painter->startTableObject(props); + + std::vector<unsigned> tableCellTextEnds; + if (bool(info.m_tableCellTextEnds)) + tableCellTextEnds = get(info.m_tableCellTextEnds); + unsigned row = 0; + unsigned column = 0; + unsigned para = 0; + unsigned offset = 1; + for (unsigned cell = 0; cell != get(info.m_tableInfo).m_numColumns * get(info.m_tableInfo).m_numRows; ++cell) { - default: - case TOP: - props.insert("draw:textarea-vertical-align", "top"); - break; - case MIDDLE: - props.insert("draw:textarea-vertical-align", "middle"); - break; - case BOTTOM: - props.insert("draw:textarea-vertical-align", "bottom"); - break; + assert(row < get(info.m_tableInfo).m_numRows); + assert(column < get(info.m_tableInfo).m_numColumns); + + if (column == 0) + m_painter->openTableRow(librevenge::RVNGPropertyList()); + + librevenge::RVNGPropertyList cellProps; + cellProps.insert("librevenge:column", int(column)); + cellProps.insert("librevenge:row", int(row)); + m_painter->openTableCell(cellProps); + + if (cell < tableCellTextEnds.size()) + { + const unsigned cellEnd = tableCellTextEnds[cell]; + while ((para < text.size()) && (offset < cellEnd)) + { + librevenge::RVNGPropertyList paraProps = getParaStyleProps(text[para].style, text[para].style.m_defaultCharStyleIndex); + m_painter->openParagraph(paraProps); + for (unsigned i_spans = 0; (i_spans < text[para].spans.size()) && (offset < cellEnd); ++i_spans) + { + librevenge::RVNGString textString; + appendCharacters(textString, text[para].spans[i_spans].chars, + getCalculatedEncoding()); + offset += textString.len(); + // TODO: why do we not drop these during parse already? + if ((i_spans == text[para].spans.size() - 1) && (textString == "\r")) + continue; + librevenge::RVNGPropertyList charProps = getCharStyleProps(text[para].spans[i_spans].style, text[para].style.m_defaultCharStyleIndex); + m_painter->openSpan(charProps); + separateSpacesAndInsertText(m_painter, textString); + m_painter->closeSpan(); + } + + if (offset > cellEnd) + { + MSPUB_DEBUG_MSG(("cell text ends in the middle of a span!\n")); + } + m_painter->closeParagraph(); + ++para; + } + } + + m_painter->closeTableCell(); + ++column; + if (column == get(info.m_tableInfo).m_numColumns) + { + m_painter->closeTableRow(); + ++row; + column = 0; + } } + + m_painter->endTableObject(); } - if (info.m_numColumns) - { - unsigned ncols = info.m_numColumns.get_value_or(0); - if (ncols > 0) - props.insert("fo:column-count", (int)ncols); - } - if (info.m_columnSpacing) - { - unsigned ngap = info.m_columnSpacing; - if (ngap > 0) - props.insert("fo:column-gap", (double)ngap / EMUS_IN_INCH); - } - m_painter->startTextObject(props); - for (unsigned i_lines = 0; i_lines < text.size(); ++i_lines) + else // a text object { - librevenge::RVNGPropertyList paraProps = getParaStyleProps(text[i_lines].style, text[i_lines].style.m_defaultCharStyleIndex); - m_painter->openParagraph(paraProps); - for (unsigned i_spans = 0; i_spans < text[i_lines].spans.size(); ++i_spans) + Margins margins = info.m_margins.get_value_or(Margins()); + props.insert("fo:padding-left", (double)margins.m_left / EMUS_IN_INCH); + props.insert("fo:padding-top", (double)margins.m_top / EMUS_IN_INCH); + props.insert("fo:padding-right", (double)margins.m_right / EMUS_IN_INCH); + props.insert("fo:padding-bottom", (double)margins.m_bottom / EMUS_IN_INCH); + if (bool(info.m_verticalAlign)) { - librevenge::RVNGString textString; - appendCharacters(textString, text[i_lines].spans[i_spans].chars, - getCalculatedEncoding()); - librevenge::RVNGPropertyList charProps = getCharStyleProps(text[i_lines].spans[i_spans].style, text[i_lines].style.m_defaultCharStyleIndex); - m_painter->openSpan(charProps); - separateSpacesAndInsertText(m_painter, textString); - m_painter->closeSpan(); + switch (info.m_verticalAlign.get()) + { + default: + case TOP: + props.insert("draw:textarea-vertical-align", "top"); + break; + case MIDDLE: + props.insert("draw:textarea-vertical-align", "middle"); + break; + case BOTTOM: + props.insert("draw:textarea-vertical-align", "bottom"); + break; + } + } + if (info.m_numColumns) + { + unsigned ncols = info.m_numColumns.get_value_or(0); + if (ncols > 0) + props.insert("fo:column-count", (int)ncols); + } + if (info.m_columnSpacing) + { + unsigned ngap = info.m_columnSpacing; + if (ngap > 0) + props.insert("fo:column-gap", (double)ngap / EMUS_IN_INCH); + } + m_painter->startTextObject(props); + for (unsigned i_lines = 0; i_lines < text.size(); ++i_lines) + { + librevenge::RVNGPropertyList paraProps = getParaStyleProps(text[i_lines].style, text[i_lines].style.m_defaultCharStyleIndex); + m_painter->openParagraph(paraProps); + for (unsigned i_spans = 0; i_spans < text[i_lines].spans.size(); ++i_spans) + { + librevenge::RVNGString textString; + appendCharacters(textString, text[i_lines].spans[i_spans].chars, + getCalculatedEncoding()); + librevenge::RVNGPropertyList charProps = getCharStyleProps(text[i_lines].spans[i_spans].style, text[i_lines].style.m_defaultCharStyleIndex); + m_painter->openSpan(charProps); + separateSpacesAndInsertText(m_painter, textString); + m_painter->closeSpan(); + } + m_painter->closeParagraph(); } - m_painter->closeParagraph(); + m_painter->endTextObject(); } - m_painter->endTextObject(); } if (makeLayer) { commit 58ad1f151731706d450b64d00e1ce12653396cf6 Author: David Tardon <[email protected]> Date: Sun Dec 28 12:57:58 2014 +0100 handle text content of a table Change-Id: I7eec32aeff3b6ac109b6abae9fcb61f46efb27bb diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp index deba5b2..9b56db8 100644 --- a/src/lib/MSPUBParser.cpp +++ b/src/lib/MSPUBParser.cpp @@ -660,6 +660,7 @@ bool MSPUBParser::parseShape(librevenge::RVNGInputStream *input, boost::optional<unsigned> numRows; boost::optional<unsigned> numCols; boost::optional<unsigned> rowcolArrayOffset; + boost::optional<unsigned> textId; while (stillReading(input, pos + length)) { MSPUBBlockInfo info = parseBlock(input, true); @@ -687,6 +688,10 @@ bool MSPUBParser::parseShape(librevenge::RVNGInputStream *input, { rowcolArrayOffset = info.dataOffset; } + else if (info.id == SHAPE_TEXT_ID) + { + textId = info.data; + } } if (bool(cellsSeqNum) && bool(numRows) && bool(numCols) && bool(rowcolArrayOffset)) { @@ -760,6 +765,8 @@ bool MSPUBParser::parseShape(librevenge::RVNGInputStream *input, ti.m_rowOffsetsInEmu = rowOffsetsInEmu; ti.m_columnOffsetsInEmu = columnOffsetsInEmu; m_collector->setShapeTableInfo(chunk.seqNum, ti); + if (bool(textId)) + m_collector->addTextShape(get(textId), chunk.seqNum); return true; } return false; _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
