diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-09-26 15:28:20 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2019-09-27 09:22:31 +0200 |
commit | d630f69d90f15bc652a62648b05ea515de78d16a (patch) | |
tree | 8283f5dfcb86bc9c907f561c66724c12c03bd80a | |
parent | b38a9a3e59df0b6c014b907bbe2b42e4ce7ed255 (diff) |
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@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/extras/ww8import/data/tdf124601.doc | bin | 0 -> 62976 bytes | |||
-rw-r--r-- | sw/qa/extras/ww8import/ww8import.cxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8graf.cxx | 21 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8scan.cxx | 10 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8scan.hxx | 2 |
5 files changed, 37 insertions, 4 deletions
diff --git a/sw/qa/extras/ww8import/data/tdf124601.doc b/sw/qa/extras/ww8import/data/tdf124601.doc Binary files differnew file mode 100644 index 000000000000..f617d4b26702 --- /dev/null +++ b/sw/qa/extras/ww8import/data/tdf124601.doc 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 |