From e9485fb5c5453618a39c8b64f607346c77aabad6 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 13 May 2013 11:24:58 +0200 Subject: bnc#816603, fdo#61594 SwWW8ImplReader::StartApo: don't always start a frame Word supports floating tables, Writer does not. We can map floating tables to fly frames, containing just a table, but then those can't span over multiple pages. We could avoid creating frames in case the table is of multiple pages, but that's hard to determine. One easy case is when the table width is >= the text area with, in that case we can be sure that no wrapping would be performed anyway, so we can avoid putting the table to a frame. Two more related problems: 1) When we need to decide if a frame should be created or not, we typically don't know yet the table width. That's why TestApo() has to always succeed (in case the paragraphs are wrapped), and then we always enter StartApo(), where we can avoid creating the frame, if necessary. 2) Even if we decide that we don't create a frame, floating and non-floating table rows are different, so a separate table should be created for such rows. By doing all the StartApo() / StopApo(), we are safe here. (cherry picked from commit c2cf03e02b1c942645aea6988112028e13dd0c89) Change-Id: Ifc0e0e2f7320c3784698d0ff278031b46864e2e5 --- sw/source/filter/ww8/ww8par6.cxx | 37 +++++++++++++++++++++++++++++-------- sw/source/filter/ww8/ww8struc.hxx | 1 + 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx index a74c4d0692c8..220a7e50afec 100644 --- a/sw/source/filter/ww8/ww8par6.cxx +++ b/sw/source/filter/ww8/ww8par6.cxx @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include // SwTxtNode, siehe unten: JoinNode() @@ -2172,6 +2173,8 @@ SwTwips SwWW8ImplReader::MoveOutsideFly(SwFrmFmt *pFlyFmt, const SwPosition &rPos, bool bTableJoin) { SwTwips nRetWidth = 0; + if (!pFlyFmt) + return nRetWidth; // Alle Attribute schliessen, da sonst Attribute entstehen koennen, // die aus Flys rausragen WW8DupProperties aDup(rDoc,pCtrlStck); @@ -2322,10 +2325,15 @@ bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo, WW8FlySet aFlySet(*this, pWFlyPara, pSFlyPara, false); - pSFlyPara->pFlyFmt = rDoc.MakeFlySection( pSFlyPara->eAnchor, - pPaM->GetPoint(), &aFlySet ); - OSL_ENSURE(pSFlyPara->pFlyFmt->GetAnchor().GetAnchorId() == - pSFlyPara->eAnchor, "Not the anchor type requested!"); + if (pTabPos && pTabPos->bNoFly) + pSFlyPara->pFlyFmt = 0; + else + { + pSFlyPara->pFlyFmt = rDoc.MakeFlySection( pSFlyPara->eAnchor, + pPaM->GetPoint(), &aFlySet ); + OSL_ENSURE(pSFlyPara->pFlyFmt->GetAnchor().GetAnchorId() == + pSFlyPara->eAnchor, "Not the anchor type requested!"); + } if (pSFlyPara->pFlyFmt) { @@ -2336,7 +2344,7 @@ bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo, pWWZOrder->InsertTextLayerObject(pOurNewObject); } - if (FLY_AS_CHAR != pSFlyPara->eAnchor) + if (FLY_AS_CHAR != pSFlyPara->eAnchor && pSFlyPara->pFlyFmt) { pAnchorStck->AddAnchor(*pPaM->GetPoint(),pSFlyPara->pFlyFmt); } @@ -2350,7 +2358,8 @@ bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo, pSFlyPara->pOldAnchorStck = pAnchorStck; pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags); - MoveInsideFly(pSFlyPara->pFlyFmt); + if (pSFlyPara->pFlyFmt) + MoveInsideFly(pSFlyPara->pFlyFmt); // 1) ReadText() wird nicht wie beim W4W-Reader rekursiv aufgerufen, // da die Laenge des Apo zu diesen Zeitpunkt noch nicht feststeht, @@ -2453,7 +2462,8 @@ void SwWW8ImplReader::StopApo() pNd->JoinNext(); } - pSFlyPara->pFlyFmt->SetFmtAttr(SvxBrushItem(aBg, RES_BACKGROUND)); + if (pSFlyPara->pFlyFmt) + pSFlyPara->pFlyFmt->SetFmtAttr(SvxBrushItem(aBg, RES_BACKGROUND)); DeleteAnchorStk(); pAnchorStck = pSFlyPara->pOldAnchorStck; @@ -2477,7 +2487,7 @@ void SwWW8ImplReader::StopApo() #i27204# Added AutoWidth setting. Left the old CalculateFlySize in place so that if the user unselects autowidth, the width doesn't max out */ - else if( !pWFlyPara->nSp28 ) + else if( !pWFlyPara->nSp28 && pSFlyPara->pFlyFmt) { using namespace sw::util; SfxItemSet aFlySet( pSFlyPara->pFlyFmt->GetAttrSet() ); @@ -4824,6 +4834,17 @@ bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap) pTabPos->nLoMgn = SVBT16ToShort(pRes); bRet = true; } + if (0 != (pRes = pPap->HasSprm(NS_sprm::LN_TDefTable))) + { + WW8TabBandDesc aDesc; + aDesc.ReadDef(false, pRes); + int nTableWidth = aDesc.nCenter[aDesc.nWwCols] - aDesc.nCenter[0]; + int nTextAreaWidth = maSectionManager.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. + pTabPos->bNoFly = nTableWidth >= nTextAreaWidth; + } return bRet; } diff --git a/sw/source/filter/ww8/ww8struc.hxx b/sw/source/filter/ww8/ww8struc.hxx index 98dff63a9d8a..5bda23530186 100644 --- a/sw/source/filter/ww8/ww8struc.hxx +++ b/sw/source/filter/ww8/ww8struc.hxx @@ -803,6 +803,7 @@ struct WW8_TablePos sal_Int16 nLoMgn; sal_uInt8 nSp29; sal_uInt8 nSp37; + bool bNoFly; }; struct WW8_FSPA -- cgit