summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/qa/extras/ww8import/data/tdf112346.docbin0 -> 27648 bytes
-rw-r--r--sw/qa/extras/ww8import/ww8import.cxx8
-rw-r--r--sw/source/filter/ww8/ww8par.cxx103
-rw-r--r--sw/source/filter/ww8/ww8par.hxx1
-rw-r--r--sw/source/filter/ww8/ww8par6.cxx15
-rw-r--r--writerfilter/source/dmapper/PropertyMap.cxx11
6 files changed, 97 insertions, 41 deletions
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
--- /dev/null
+++ b/sw/qa/extras/ww8import/data/tdf112346.doc
Binary files differ
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;
}
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 6ba8e6c20084..36fd67761a4b 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -1010,6 +1010,13 @@ void SectionPropertyMap::HandleMarginsHeaderFooter( bool bFirstPage, DomainMappe
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.
@@ -1063,9 +1070,9 @@ bool SectionPropertyMap::FloatingTableConversion( DomainMapper_Impl& rDM_Impl, F
// 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())))