[Libreoffice-commits] libmspub.git: 2 commits - src/lib

David Tardon dtardon at redhat.com
Mon Dec 29 10:23:53 PST 2014


 src/lib/MSPUBCollector.cpp |  101 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 74 insertions(+), 27 deletions(-)

New commits:
commit b3ac66dd7a7a4d9d1ed92ffc34a456fef695127e
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Dec 29 19:18:49 2014 +0100

    cells are not always saved in L->R T->B order
    
    As an additional bonus, this simplifies the output loop.
    
    Change-Id: I2ae1eab52d3681c02e790af950c82a7f01d3aa11

diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp
index c157b33..5bc7e62 100644
--- a/src/lib/MSPUBCollector.cpp
+++ b/src/lib/MSPUBCollector.cpp
@@ -108,11 +108,13 @@ static void separateSpacesAndInsertText(librevenge::RVNGDrawingInterface *iface,
 struct TableLayoutCell
 {
   TableLayoutCell()
-    : m_rowSpan(0)
+    : m_cell(0)
+    , m_rowSpan(0)
     , m_colSpan(0)
   {
   }
 
+  unsigned m_cell;
   unsigned m_rowSpan;
   unsigned m_colSpan;
 };
@@ -173,11 +175,66 @@ void createTableLayout(const std::vector<CellInfo> &cells, TableLayout &tableLay
     }
 
     TableLayoutCell &layoutCell = tableLayout[it->m_startRow][it->m_startColumn];
+    layoutCell.m_cell = unsigned(int(it - cells.begin()));
     layoutCell.m_rowSpan = rowSpan;
     layoutCell.m_colSpan = colSpan;
   }
 }
 
+typedef std::vector<std::pair<unsigned, unsigned> > ParagraphToCellMap_t;
+typedef std::vector<librevenge::RVNGString> SpanTexts_t;
+typedef std::vector<SpanTexts_t> ParagraphTexts_t;
+
+void mapTableTextToCells(
+  const std::vector<TextParagraph> &text,
+  const std::vector<unsigned> &tableCellTextEnds,
+  const char *const encoding,
+  ParagraphToCellMap_t &paraToCellMap,
+  ParagraphTexts_t &paraTexts
+)
+{
+  assert(paraToCellMap.empty());
+  assert(paraTexts.empty());
+
+  paraToCellMap.reserve(tableCellTextEnds.size());
+  paraTexts.reserve(tableCellTextEnds.size());
+
+  unsigned firstPara = 0;
+  unsigned offset = 1;
+  for (unsigned para = 0; para != text.size(); ++para)
+  {
+    paraTexts.push_back(SpanTexts_t());
+    paraTexts.back().reserve(text[para].spans.size());
+
+    for (unsigned i_spans = 0; i_spans != text[para].spans.size(); ++i_spans)
+    {
+      librevenge::RVNGString textString;
+      appendCharacters(textString, text[para].spans[i_spans].chars, encoding);
+      offset += textString.len();
+      // TODO: why do we not drop these during parse already?
+      if ((i_spans == text[para].spans.size() - 1) && (textString == "\r"))
+        continue;
+      paraTexts.back().push_back(textString);
+    }
+
+    assert(paraTexts.back().size() <= text[para].spans.size());
+
+    if ((paraToCellMap.size() < tableCellTextEnds.size()))
+    {
+      if (offset > tableCellTextEnds[paraToCellMap.size()])
+      {
+        MSPUB_DEBUG_MSG(("text of cell %u ends in the middle of a paragraph!\n", unsigned(paraToCellMap.size())));
+      }
+
+      paraToCellMap.push_back(std::make_pair(firstPara, para));
+      firstPara = para + 1;
+    }
+  }
+
+  assert(paraTexts.size() == text.size());
+  assert(paraToCellMap.size() <= tableCellTextEnds.size());
+}
+
 } // anonymous namespace
 
 void MSPUBCollector::addEOTFont(const librevenge::RVNGString &name, const librevenge::RVNGBinaryData &data)
@@ -949,12 +1006,14 @@ boost::function<void(void)> MSPUBCollector::paintShape(const ShapeInfo &info, co
       std::vector<unsigned> tableCellTextEnds;
       if (bool(info.m_tableCellTextEnds))
         tableCellTextEnds = get(info.m_tableCellTextEnds);
+
       TableLayout tableLayout(boost::extents[get(info.m_tableInfo).m_numRows][get(info.m_tableInfo).m_numColumns]);
       createTableLayout(get(info.m_tableInfo).m_cells, tableLayout);
 
-      unsigned cell = 0;
-      unsigned para = 0;
-      unsigned offset = 1;
+      ParagraphToCellMap_t paraToCellMap;
+      ParagraphTexts_t paraTexts;
+      mapTableTextToCells(text, tableCellTextEnds, getCalculatedEncoding(), paraToCellMap, paraTexts);
+
       for (unsigned row = 0; row != tableLayout.shape()[0]; ++row)
       {
         m_painter->openTableRow(librevenge::RVNGPropertyList());
@@ -978,38 +1037,26 @@ boost::function<void(void)> MSPUBCollector::paintShape(const ShapeInfo &info, co
 
             m_painter->openTableCell(cellProps);
 
-            if (cell < tableCellTextEnds.size())
+            if (tableLayout[row][col].m_cell < paraToCellMap.size())
             {
-              const unsigned cellEnd = tableCellTextEnds[cell];
-              while ((para < text.size()) && (offset < cellEnd))
+              const std::pair<unsigned, unsigned> &cellParas = paraToCellMap[tableLayout[row][col].m_cell];
+              for (unsigned para = cellParas.first; para <= cellParas.second; ++para)
               {
                 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)
+
+                for (unsigned i_spans = 0; i_spans < paraTexts[para].size(); ++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);
+                  separateSpacesAndInsertText(m_painter, paraTexts[para][i_spans]);
                   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->closeParagraph();
               }
             }
 
-            ++cell;
             m_painter->closeTableCell();
           }
         }
commit 04b14a279a51a1ab88e304cabf776a060e1f19b5
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Dec 29 18:13:19 2014 +0100

    fix debug build
    
    Change-Id: I651c495d21f4c6869bb0ecb01a7b6f02f3dcbf3f

diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp
index 7f8cc84..c157b33 100644
--- a/src/lib/MSPUBCollector.cpp
+++ b/src/lib/MSPUBCollector.cpp
@@ -135,7 +135,7 @@ void createTableLayout(const std::vector<CellInfo> &cells, TableLayout &tableLay
                         "cell %u (rows %u to %u, columns %u to %u) overflows the table, ignoring\n",
                         unsigned(int(it - cells.begin())),
                         it->m_startRow, it->m_endRow,
-                        it->m_startColumn, it->m_endColumn,
+                        it->m_startColumn, it->m_endColumn
                       ));
       continue;
     }
@@ -144,7 +144,7 @@ void createTableLayout(const std::vector<CellInfo> &cells, TableLayout &tableLay
       MSPUB_DEBUG_MSG((
                         "cell %u (rows %u to %u) has got negative row span, ignoring\n",
                         unsigned(int(it - cells.begin())),
-                        it->m_startRow, it->m_endRow,
+                        it->m_startRow, it->m_endRow
                       ));
       continue;
     }
@@ -153,7 +153,7 @@ void createTableLayout(const std::vector<CellInfo> &cells, TableLayout &tableLay
       MSPUB_DEBUG_MSG((
                         "cell %u (columns %u to %u) has got negative column span, ignoring\n",
                         unsigned(int(it - cells.begin())),
-                        it->m_startColumn, it->m_endColumn,
+                        it->m_startColumn, it->m_endColumn
                       ));
       continue;
     }
@@ -167,7 +167,7 @@ void createTableLayout(const std::vector<CellInfo> &cells, TableLayout &tableLay
                         "cell %u (rows %u to %u, columns %u to %u) has got 0 span in one dimension, ignoring\n",
                         unsigned(int(it - cells.begin())),
                         it->m_startRow, it->m_endRow,
-                        it->m_startColumn, it->m_endColumn,
+                        it->m_startColumn, it->m_endColumn
                       ));
       continue;
     }


More information about the Libreoffice-commits mailing list