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.kagan...@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 <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Reviewed-on: https://gerrit.libreoffice.org/42216 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Mike Kaganski <mike.kagan...@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()))) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits