diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2017-09-12 13:54:26 +0300 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-09-12 14:28:23 +0200 |
commit | a952d1f59f4f84380b82f1eb9e550b8f69c4be5d (patch) | |
tree | b1ea98ccf222a73ecd395c9517d2b9d895b68ed5 /sw | |
parent | 83748e50026bff56aaa1c2f7bfb0b1557344d72c (diff) |
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@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/ww8import/data/tdf112346.doc | bin | 0 -> 27648 bytes | |||
-rw-r--r-- | sw/qa/extras/ww8import/ww8import.cxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.cxx | 103 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.hxx | 1 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par6.cxx | 15 |
5 files changed, 88 insertions, 39 deletions
diff --git a/sw/qa/extras/ww8import/data/tdf112346.doc b/sw/qa/extras/ww8import/data/tdf112346.doc Binary files differnew file mode 100644 index 000000000000..af0cca219acf --- /dev/null +++ b/sw/qa/extras/ww8import/data/tdf112346.doc diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx index 5ea85cc7360b..907fe47ebcff 100644 --- a/sw/qa/extras/ww8import/ww8import.cxx +++ b/sw/qa/extras/ww8import/ww8import.cxx @@ -131,6 +131,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 a135234ee669..196e8c7fcad8 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -93,6 +93,7 @@ #include <charfmt.hxx> #include <unocrsr.hxx> #include <IDocumentSettingAccess.hxx> +#include <sprmids.hxx> #include <fltini.hxx> @@ -2501,6 +2502,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; + + SprmResult aRes = pPap->HasSprm(NS_sprm::sprmTDefTable); + if (nullptr != aRes.pSprm) + { + bResult = false; + WW8TabBandDesc aDesc; + aDesc.ReadDef(false, aRes.pSprm); + 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_xSBase->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 @@ -2575,31 +2653,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_xSBase->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_xPlcxMan->GetPap()->Restore( aSave ); } diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index a0d54fcdbbfd..cfb3ed81ad89 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -1867,6 +1867,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_xWwFib; } SwDoc& GetDoc() const { return m_rDoc; } diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx index 6be1868af08a..2130cdc25f39 100644 --- a/sw/source/filter/ww8/ww8par6.cxx +++ b/sw/source/filter/ww8/ww8par6.cxx @@ -5099,22 +5099,9 @@ bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap) aRes = pPap->HasSprm(0x941F); if (aRes.pSprm && aRes.nRemainingData >= 2) pTabPos->nLoMgn = SVBT16ToShort(aRes.pSprm); + pTabPos->bNoFly = !FloatingTableConversion(pPap); bRet = true; } - aRes = pPap->HasSprm(NS_sprm::sprmTDefTable); - if (nullptr != aRes.pSprm) - { - WW8TabBandDesc aDesc; - aDesc.ReadDef(false, aRes.pSprm); - 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; } |