Kaydet (Commit) a952d1f5 authored tarafından Mike Kaganski's avatar Mike Kaganski Kaydeden (comit) Miklos Vajna

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/42196Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
üst 83748e50
This diff was suppressed by a .gitattributes entry.
......@@ -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();
......
......@@ -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 );
}
......
......@@ -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; }
......
......@@ -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;
}
......
......@@ -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())))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment