[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3' - sw/qa sw/source writerfilter/source

Mike Kaganski mike.kaganski at collabora.com
Tue Sep 12 17:08:45 UTC 2017


 sw/qa/extras/ww8import/data/tdf112346.doc   |binary
 sw/qa/extras/ww8import/ww8import.cxx        |    8 ++
 sw/source/filter/ww8/ww8par.cxx             |  103 +++++++++++++++++++++-------
 sw/source/filter/ww8/ww8par.hxx             |    1 
 sw/source/filter/ww8/ww8par6.cxx            |   14 ---
 writerfilter/source/dmapper/PropertyMap.cxx |   11 ++
 6 files changed, 97 insertions(+), 40 deletions(-)

New commits:
commit 21f73d47e949ef2732b778bd1ebe123473edf231
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Tue Sep 12 13:54:26 2017 +0300

    tdf#112346: take Word no-wrap limit into account also for ww8
    
    This also makes ww8 floating-table conversion decision heuristics
    somewhat closer to OOXML code.
    
    Change-Id: I29ca2ebabd1758ad98e02aaf560cf2f44daec3a8
    Reviewed-on: https://gerrit.libreoffice.org/42196
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Reviewed-on: https://gerrit.libreoffice.org/42216
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/sw/qa/extras/ww8import/data/tdf112346.doc b/sw/qa/extras/ww8import/data/tdf112346.doc
new file mode 100644
index 000000000000..af0cca219acf
Binary files /dev/null and b/sw/qa/extras/ww8import/data/tdf112346.doc differ
diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx
index 751006a4a553..eb45c8172e36 100644
--- a/sw/qa/extras/ww8import/ww8import.cxx
+++ b/sw/qa/extras/ww8import/ww8import.cxx
@@ -88,6 +88,14 @@ DECLARE_WW8IMPORT_TEST(testTdf106799, "tdf106799.doc")
         }
 }
 
+DECLARE_WW8IMPORT_TEST(testTdf112346, "tdf112346.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());
+}
+
 // tests should only be added to ww8IMPORT *if* they fail round-tripping in ww8EXPORT
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 88f4f4f3d22c..45c22d149874 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -91,6 +91,7 @@
 #include <charfmt.hxx>
 #include <unocrsr.hxx>
 #include <IDocumentSettingAccess.hxx>
+#include <sprmids.hxx>
 
 #include <fltini.hxx>
 
@@ -2592,6 +2593,83 @@ void SwWW8ImplReader::EndSpecial()
     OSL_ENSURE(!m_nInTable, "unclosed table!");
 }
 
+bool SwWW8ImplReader::FloatingTableConversion(WW8PLCFx_Cp_FKP* pPap)
+{
+    // This is ww8 version of the code deciding if the table needs to be
+    // in a floating frame.
+    // For OOXML code, see SectionPropertyMap::FloatingTableConversion in
+    // writerfilter/source/dmapper/PropertyMap.cxx
+    // The two should do ~same, so if you make changes here, please check
+    // that the other is in sync.
+
+    // Note that this is just a list of heuristics till sw core can have a
+    // table that is floating and can span over multiple pages at the same
+    // time.
+
+    bool bResult = true;
+
+    const sal_uInt8 *pRes = pPap->HasSprm(NS_sprm::LN_TDefTable);
+    if (nullptr != pRes)
+    {
+        bResult = false;
+        WW8TabBandDesc aDesc;
+        aDesc.ReadDef(false, pRes);
+        int nTextAreaWidth = m_aSectionManager.GetTextAreaWidth();
+        int nTableWidth = aDesc.nCenter[aDesc.nWwCols] - aDesc.nCenter[0];
+
+        // It seems Word has a limit here, so that in case the table width is quite
+        // close to the text area width, then it won't perform a wrapping, even in
+        // case the content (e.g. an empty paragraph) would fit. The magic constant
+        // here represents this limit.
+        const int nMagicNumber = 469;
+
+        // If the table is wider than the text area, then don't create a fly
+        // for the table: no wrapping will be performed anyway, but multi-page
+        // tables will be broken.
+        if ((nTableWidth + nMagicNumber) < nTextAreaWidth)
+            bResult = true;
+
+        // If there are columns, do create a fly, as the flow of the columns
+        // would otherwise restrict the table.
+        if (!bResult && (m_aSectionManager.CurrentSectionColCount() >= 2))
+            bResult = true;
+    }
+
+    if (bResult)
+    {
+        WW8PLCFxSave1 aSave;
+        pPap->Save(aSave);
+        if (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.
+                bResult = false;
+        }
+        pPap->Restore(aSave);
+    }
+
+    return bResult;
+}
+
 bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
 {
     // Frame/Table/Anl
@@ -2665,31 +2743,6 @@ 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 600cb409b263..3de77f914409 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1851,6 +1851,7 @@ public:     // really private, but can only be done public
     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;
+    bool FloatingTableConversion(WW8PLCFx_Cp_FKP* pPap);
 
     const WW8Fib& GetFib() const    { return *m_pWwFib; }
     SwDoc& GetDoc() const           { return m_rDoc; }
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index f86eb4c80819..bfe724c2f8ca 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -5067,21 +5067,9 @@ bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap)
             pTabPos->nUpMgn = SVBT16ToShort(pRes);
         if (nullptr != (pRes = pPap->HasSprm(0x941F)))
             pTabPos->nLoMgn = SVBT16ToShort(pRes);
+        pTabPos->bNoFly = !FloatingTableConversion(pPap);
         bRet = true;
     }
-    if (nullptr != (pRes = pPap->HasSprm(NS_sprm::LN_TDefTable)))
-    {
-        WW8TabBandDesc aDesc;
-        aDesc.ReadDef(false, pRes);
-        int nTableWidth = aDesc.nCenter[aDesc.nWwCols] - aDesc.nCenter[0];
-        int nTextAreaWidth = m_aSectionManager.GetTextAreaWidth();
-        // If the table is wider than the text area, then don't create a fly
-        // for the table: no wrapping will be performed anyway, but multi-page
-        // tables will be broken.
-        // If there are columns, do create a fly, as the flow of the columns
-        // would otherwise restrict the table.
-        pTabPos->bNoFly = nTableWidth >= nTextAreaWidth  && m_aSectionManager.CurrentSectionColCount() < 2;
-    }
     return bRet;
 }
 
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 8b84e318bc67..6ff4d05c1476 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -1054,6 +1054,13 @@ void SectionPropertyMap::HandleMarginsHeaderFooter(bool bFirstPage, DomainMapper
 
 bool SectionPropertyMap::FloatingTableConversion(DomainMapper_Impl& rDM_Impl, FloatingTableInfo& rInfo)
 {
+    // This is OOXML version of the code deciding if the table needs to be
+    // in a floating frame.
+    // For ww8 code, see SwWW8ImplReader::FloatingTableConversion in
+    // sw/source/filter/ww8/ww8par.cxx
+    // The two should do the same, so if you make changes here, please check
+    // that the other is in sync.
+
     // Note that this is just a list of heuristics till sw core can have a
     // table that is floating and can span over multiple pages at the same
     // time.
@@ -1107,9 +1114,9 @@ bool SectionPropertyMap::FloatingTableConversion(DomainMapper_Impl& rDM_Impl, Fl
 
     // If the position is relative to the edge of the page, then we need to check the whole
     // page width to see whether text can fit next to the table.
-    if ( rInfo.getPropertyValue( "HoriOrientRelation" ) == text::RelOrientation::PAGE_FRAME )
+    if ( nHoriOrientRelation == text::RelOrientation::PAGE_FRAME )
     {
-        // If the table is wide enough to that no text fits next to it, then don't create a fly
+        // If the table is wide enough so that no text fits next to it, then don't create a fly
         // for the table: no wrapping will be performed anyway, but multi-page
         // tables will be broken.
         if ((nTableWidth + nMagicNumber) < (nPageWidth - std::min(GetLeftMargin(), GetRightMargin())))


More information about the Libreoffice-commits mailing list