sw/qa/extras/ww8import/data/tdf107773.doc |binary
 sw/qa/extras/ww8import/ww8import.cxx      |    8 ++++++
 sw/source/filter/ww8/ww8par.cxx           |   25 +++++++++++++++++++
 sw/source/filter/ww8/ww8par.hxx           |    2 +
 sw/source/filter/ww8/ww8par2.cxx          |   39 ++++++++++++++++++++++++++++++
 5 files changed, 74 insertions(+)

New commits:
commit 6aba29576df7a2a40e54040d4dd09d94d6594741
Author: Miklos Vajna <vmik...@collabora.co.uk>
Date:   Thu May 11 17:38:40 2017 +0200

    tdf#107773 DOC import: consider page breaks for multi-page floattables
    
    See commit 8fe8bd6c3b5b1a539b7370f8c457fa69c061d2de (Related: fdo#61594
    SwWW8ImplReader::StartApo: don't always start a frame, 2013-05-13) for
    the context, this is one more case where having a multi-page floattable
    as a multi-page one is a better option.
    
    The additional condition is that in case there is a break right after
    the table, then always import the table as a non-floating one, as there
    won't be any wrapping anyway (due to the break).
    
    Change-Id: I3dd4174226cfc1e825c00607221feeed51b7133f
    Reviewed-on: https://gerrit.libreoffice.org/37513
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    Tested-by: Jenkins <c...@libreoffice.org>

diff --git a/sw/qa/extras/ww8import/data/tdf107773.doc 
b/sw/qa/extras/ww8import/data/tdf107773.doc
new file mode 100644
index 000000000000..31c7b7c5c121
Binary files /dev/null and b/sw/qa/extras/ww8import/data/tdf107773.doc differ
diff --git a/sw/qa/extras/ww8import/ww8import.cxx 
b/sw/qa/extras/ww8import/ww8import.cxx
index 1a2ec45af6fb..4c2c83499405 100644
--- a/sw/qa/extras/ww8import/ww8import.cxx
+++ b/sw/qa/extras/ww8import/ww8import.cxx
@@ -59,6 +59,14 @@ DECLARE_WW8IMPORT_TEST(testFloatingTableSectionColumns, 
"floating-table-section-
     CPPUNIT_ASSERT( tableWidth.toInt32() > 10000 );
 }
 
+DECLARE_WW8IMPORT_TEST(testTdf107773, "tdf107773.doc")
+{
+    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage = 
xDrawPageSupplier->getDrawPage();
+    // This was 1, multi-page table was imported as a floating one.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount());
+}
+
 DECLARE_WW8IMPORT_TEST(testTdf106291, "tdf106291.doc")
 {
     // Table cell was merged vertically instead of horizontally -> had 
incorrect dimensions
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 2de85b49bdbd..3b9c9c54231c 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -2597,6 +2597,31 @@ bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, 
WW8_CP nStartCp)
             if (bHasRowEnd && ParseTabPos(&aTabPos,pPap))
                 pTabPos = &aTabPos;
 
+            if (pTabPos && !pTabPos->bNoFly && SearchTableEnd(pPap))
+            {
+                // Table is considered to be imported into a fly frame and we
+                // know where the end of the table is.
+                bool bIsUnicode;
+                WW8_FC nFc = m_pSBase->WW8Cp2Fc(pPap->Where(), &bIsUnicode);
+                sal_uInt64 nPos = m_pStrm->Tell();
+                m_pStrm->Seek(nFc);
+                sal_uInt16 nUChar = 0;
+                if (bIsUnicode)
+                    m_pStrm->ReadUInt16(nUChar);
+                else
+                {
+                    sal_uInt8 nChar = 0;
+                    m_pStrm->ReadUChar(nChar);
+                    nUChar = nChar;
+                }
+                m_pStrm->Seek(nPos);
+                if (nUChar == 0xc)
+                    // The pap after the table starts with a page break, so
+                    // there will be no wrapping around the float-table.
+                    // Request no fly in this case, so the table can properly
+                    // be a multi-page one if necessary.
+                    pTabPos->bNoFly = true;
+            }
             m_pPlcxMan->GetPap()->Restore( aSave );
         }
 
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 43974de5952d..fdec37c9bd7a 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1849,6 +1849,8 @@ public:     // really private, but can only be done public
     short ImportSprm(const sal_uInt8* pPos, sal_Int32 nMemLen, sal_uInt16 nId 
= 0);
 
     bool SearchRowEnd(WW8PLCFx_Cp_FKP* pPap,WW8_CP &rStartCp, int nLevel) 
const;
+    /// Seek to the end of the table with pPap, returns true on success.
+    bool SearchTableEnd(WW8PLCFx_Cp_FKP* pPap) const;
 
     const WW8Fib& GetFib() const    { return *m_pWwFib; }
     SwDoc& GetDoc() const           { return m_rDoc; }
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index bfba17ff98f6..efa5ecaa985e 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -509,6 +509,45 @@ bool SwWW8ImplReader::SearchRowEnd(WW8PLCFx_Cp_FKP* pPap, 
WW8_CP &rStartCp,
     return false;
 }
 
+bool SwWW8ImplReader::SearchTableEnd(WW8PLCFx_Cp_FKP* pPap) const
+{
+    if (m_bVer67)
+        // The below SPRM is for WW8 only.
+        return false;
+
+    WW8PLCFxDesc aRes;
+    aRes.pMemPos = nullptr;
+    aRes.nEndPos = pPap->Where();
+    bool bReadRes(false);
+    WW8PLCFxDesc aPrevRes;
+
+    while (pPap->HasFkp() && pPap->Where() != WW8_CP_MAX)
+    {
+        // See if the current pap is outside the table.
+        SprmResult aSprmRes = pPap->HasSprm(NS_sprm::sprmPFInTable);
+        const sal_uInt8* pB = aSprmRes.pSprm;
+        if (!pB || aSprmRes.nRemainingData < 1 || *pB != 1)
+            // Yes, this is the position after the end of the table.
+            return true;
+
+        // It is, so seek to the next pap.
+        aRes.nStartPos = aRes.nEndPos;
+        aRes.pMemPos = nullptr;
+        if (!pPap->SeekPos(aRes.nStartPos))
+            return false;
+
+        // Read the sprms and make sure we moved forward to avoid infinite 
loops.
+        pPap->GetSprms(&aRes);
+        if (bReadRes && aRes.nEndPos == aPrevRes.nEndPos && aRes.nStartPos == 
aPrevRes.nStartPos)
+            return false;
+
+        bReadRes = true;
+        aPrevRes = aRes;
+    }
+
+    return false;
+}
+
 ApoTestResults SwWW8ImplReader::TestApo(int nCellLevel, bool bTableRowEnd,
     const WW8_TablePos *pTabPos)
 {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to