summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2019-09-26 15:28:20 +0200
committerMike Kaganski <mike.kaganski@collabora.com>2019-10-08 11:15:35 +0200
commitea3a53adcb39b55fa1793136a3c579d774bc1354 (patch)
tree8368d3f2446e1c70bf7c552104ddef4a3a4bcadb
parenttdf#127958 crash adding 2 or more files into writer master document (diff)
downloadcore-ea3a53adcb39b55fa1793136a3c579d774bc1354.tar.gz
core-ea3a53adcb39b55fa1793136a3c579d774bc1354.zip
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. (cherry picked from commit d630f69d90f15bc652a62648b05ea515de78d16a) Change-Id: Iaddd5e522e0380b731899f32a17c14ce4442ac35 Reviewed-on: https://gerrit.libreoffice.org/80346 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--sw/qa/extras/ww8import/data/tdf124601.docbin0 -> 62976 bytes
-rw-r--r--sw/qa/extras/ww8import/ww8import.cxx8
-rw-r--r--sw/source/filter/ww8/ww8graf.cxx21
-rw-r--r--sw/source/filter/ww8/ww8scan.cxx10
-rw-r--r--sw/source/filter/ww8/ww8scan.hxx2
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
new file mode 100644
index 000000000000..f617d4b26702
--- /dev/null
+++ b/sw/qa/extras/ww8import/data/tdf124601.doc
Binary files 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 58f72514f147..050d2fae53e9 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -2464,7 +2464,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
@@ -2492,7 +2502,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;
@@ -2693,8 +2706,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 19e0d81e7850..8d6e42303503 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -5778,6 +5778,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
@@ -5928,6 +5929,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 d22a32180dbf..1c1d9d148476 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -1239,6 +1239,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