[Libreoffice-commits] core.git: sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Sep 27 07:23:46 UTC 2019


 sw/qa/extras/ww8import/data/tdf124601.doc |binary
 sw/qa/extras/ww8import/ww8import.cxx      |    8 ++++++++
 sw/source/filter/ww8/ww8graf.cxx          |   21 +++++++++++++++++----
 sw/source/filter/ww8/ww8scan.cxx          |   10 ++++++++++
 sw/source/filter/ww8/ww8scan.hxx          |    2 ++
 5 files changed, 37 insertions(+), 4 deletions(-)

New commits:
commit d630f69d90f15bc652a62648b05ea515de78d16a
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Sep 26 15:28:20 2019 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Sep 27 09:22:31 2019 +0200

    Related: tdf#124601 DOC import: improve fLayoutInCell handling
    
    There were 3 problems here:
    
    First, SwWW8ImplReader::IsObjectLayoutInTableCell() should not use
    m_nProduct to determine the Word version. It depends on an undocumented
    field of the [MS-DOC] format and the bugdoc shows how it interprets a
    Word 2007-produced document as a Word 97 one. Instead, parse the cswNew
    field of the file header, which is a more or less documented way to find
    out if this file was produced by >=2000 or 97.
    
    See e.g.
    <https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-doc/841b5f72-487e-4fe7-8657-ec90d5af8750>
    where the Dop structure maps cswNew values to Word versions.
    
    Second, parse the fLayoutInCell correctly: it's part of a bitfield, with
    two variables: a bool and an other one which decides if the bool should
    be read at all. The bugdoc's case was evaluated as false, so do the
    proper parsing in that case and leave the existing logic as-is for now.
    
    Third, there doesn't seem to be a reason to exclude the wrap-through
    case for the fLayoutInCell -> follows-text-flow mapping. The bugdoc
    shows that Word interprects fLayoutInCell the same way for wrap-though
    objects, too.
    
    Change-Id: Iaddd5e522e0380b731899f32a17c14ce4442ac35
    Reviewed-on: https://gerrit.libreoffice.org/79629
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/ww8import/data/tdf124601.doc b/sw/qa/extras/ww8import/data/tdf124601.doc
new file mode 100644
index 000000000000..f617d4b26702
Binary files /dev/null and b/sw/qa/extras/ww8import/data/tdf124601.doc differ
diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx
index 41b97b098951..363d6b76ee46 100644
--- a/sw/qa/extras/ww8import/ww8import.cxx
+++ b/sw/qa/extras/ww8import/ww8import.cxx
@@ -86,6 +86,14 @@ DECLARE_WW8IMPORT_TEST(testTdf107773, "tdf107773.doc")
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount());
 }
 
+DECLARE_WW8IMPORT_TEST(testTdf124601, "tdf124601.doc")
+{
+    // Without the accompanying fix in place, this test would have failed, as the importer lost the
+    // fLayoutInCell shape property for wrap-though shapes.
+    CPPUNIT_ASSERT(getProperty<bool>(getShapeByName("Grafik 18"), "IsFollowingTextFlow"));
+    CPPUNIT_ASSERT(getProperty<bool>(getShapeByName("Grafik 19"), "IsFollowingTextFlow"));
+}
+
 DECLARE_WW8IMPORT_TEST(testTdf112535, "tdf112535.doc")
 {
     SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index d3c4a102bf40..a49d9dea7054 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -2466,7 +2466,17 @@ bool SwWW8ImplReader::IsObjectLayoutInTableCell( const sal_uInt32 nLayoutInTable
 
     if ( m_bVer8 )
     {
-        const sal_uInt16 nWWVersion = m_xWwFib->m_nProduct & 0xE000;
+        sal_uInt16 nWWVersion = m_xWwFib->m_nProduct & 0xE000;
+        if (nWWVersion == 0)
+        {
+            // 0 nProduct can happen for Word >97 as well, check cswNew in this case instead.
+            if (m_xWwFib->m_cswNew > 0)
+            {
+                // This is Word >=2000.
+                nWWVersion = 0x2000;
+            }
+        }
+
         switch ( nWWVersion )
         {
             case 0x0000: // version 8 aka Microsoft Word 97
@@ -2494,7 +2504,10 @@ bool SwWW8ImplReader::IsObjectLayoutInTableCell( const sal_uInt32 nLayoutInTable
                 }
                 else
                 {
-                    bIsObjectLayoutInTableCell = false;
+                    // Documented in [MS-ODRAW], 2.3.4.44 "Group Shape Boolean Properties".
+                    bool fUsefLayoutInCell = (nLayoutInTableCell & 0x80000000) >> 31;
+                    bool fLayoutInCell = (nLayoutInTableCell & 0x8000) >> 15;
+                    bIsObjectLayoutInTableCell = fUsefLayoutInCell && fLayoutInCell;
                 }
             }
             break;
@@ -2695,8 +2708,8 @@ SwFrameFormat* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
         m_nInTable && IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell );
 
     // #i18732# - Switch on 'follow text flow', if object is laid out
-    // inside table cell and its wrapping isn't 'SURROUND_THROUGH'
-    if (bLayoutInTableCell && eSurround != css::text::WrapTextMode_THROUGH)
+    // inside table cell
+    if (bLayoutInTableCell)
     {
         SwFormatFollowTextFlow aFollowTextFlow( true );
         aFlySet.Put( aFollowTextFlow );
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 4a79345d38eb..80a7bf8ed41c 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -5779,6 +5779,7 @@ WW8Fib::WW8Fib(SvStream& rSt, sal_uInt8 nWantedVersion, sal_uInt32 nOffset):
         // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the
         // above bit-field member initializations can be moved to the class definition
 {
+    // See [MS-DOC] 2.5.15 "How to read the FIB".
     sal_uInt8 aBits1;
     sal_uInt8 aBits2;
     sal_uInt8 aVer8Bits1;    // only used starting with WinWord 8
@@ -5929,6 +5930,15 @@ WW8Fib::WW8Fib(SvStream& rSt, sal_uInt8 nWantedVersion, sal_uInt32 nOffset):
         rSt.ReadInt32( m_fcIslandFirst );
         rSt.ReadInt32( m_fcIslandLim );
         rSt.ReadUInt16( m_cfclcb );
+
+        // Read cswNew to find out if nFib should be ignored.
+        sal_uInt32 nPos = rSt.Tell();
+        rSt.SeekRel(m_cfclcb * 8);
+        if (rSt.good())
+        {
+            rSt.ReadUInt16(m_cswNew);
+        }
+        rSt.Seek(nPos);
     }
 
 // end of the insertion for WW8
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 807d4e6db71e..a2dbffa847e2 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -1232,6 +1232,8 @@ public:
     sal_Int32  m_fcIslandFirst = 0;   // ?
     sal_Int32  m_fcIslandLim = 0;     // ?
     sal_uInt16 m_cfclcb = 0; // Number of fields in the array of FC/LCB pairs.
+    /// Specifies the count of 16-bit values corresponding to fibRgCswNew that follow.
+    sal_uInt16 m_cswNew = 0;
 
     // end of WW8 section
 


More information about the Libreoffice-commits mailing list