summaryrefslogtreecommitdiff
path: root/sw/source/core/text/txtfly.cxx
diff options
context:
space:
mode:
authorCédric Bosdonnat <cedric.bosdonnat.ooo@free.fr>2012-03-14 16:38:43 +0100
committerCédric Bosdonnat <cedric.bosdonnat.ooo@free.fr>2012-03-15 16:57:44 +0100
commit32eed8ac666dc79b038ddc0b14769ae4d4f24587 (patch)
treeb5c1fd29515eda3cb3460ccdb8dc0e94c5d07f76 /sw/source/core/text/txtfly.cxx
parentb1c472c7021ebb85afdc5c4afd0e0fcd74ab15d9 (diff)
Cleanup in txtfly.cxx and translated comments to english there
Diffstat (limited to 'sw/source/core/text/txtfly.cxx')
-rw-r--r--sw/source/core/text/txtfly.cxx1198
1 files changed, 225 insertions, 973 deletions
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index 7336d13c5d67..ec6d09a3b8e6 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -30,27 +30,21 @@
#include <vcl/outdev.hxx>
#include <vcl/virdev.hxx>
-#include "viewsh.hxx"
#include "pagefrm.hxx"
#include "rootfrm.hxx"
-#include "viewimp.hxx" // SwViewImp
#include "pam.hxx" // SwPosition
#include "swregion.hxx" // SwRegionRects
-#include "dcontact.hxx" // SwContact
#include "dflyobj.hxx" // SdrObject
#include "flyfrm.hxx" // SwFlyFrm
#include "frmtool.hxx" // ::DrawGraphic
-#include "porfld.hxx" // SwGrfNumPortion
-#include "txtfrm.hxx" // SwTxtFrm
-#include "itrform2.hxx" // SwTxtFormatter
#include "porfly.hxx" // NewFlyCntPortion
#include "porfld.hxx" // SwGrfNumPortion
#include "txtfly.hxx" // SwTxtFly
#include "txtpaint.hxx" // SwSaveClip
#include "txtatr.hxx" // SwTxtFlyCnt
#include "notxtfrm.hxx"
-#include "flyfrms.hxx"
#include "fmtcnct.hxx" // SwFmtChain
+#include "inftxt.hxx"
#include <pormulti.hxx> // SwMultiPortion
#include <svx/obj3d.hxx>
#include <editeng/txtrange.hxx>
@@ -58,10 +52,8 @@
#include <editeng/ulspitem.hxx>
// #i28701#
#include <editeng/lspcitem.hxx>
-#include <txtflcnt.hxx>
#include <fmtsrnd.hxx>
#include <fmtanchr.hxx>
-#include <fmtflcnt.hxx>
#include <frmfmt.hxx>
#include <pagedesc.hxx> // SwPageDesc
#include <tgrditem.hxx>
@@ -71,9 +63,9 @@
#include <IDocumentLayoutAccess.hxx>
#include <IDocumentSettingAccess.hxx>
#include <svx/svdoedge.hxx>
-#include "doc.hxx"
#ifdef DBG_UTIL
+#include "viewsh.hxx"
#include "viewopt.hxx" // SwViewOptions, only for testing (Test2)
#include "doc.hxx"
#endif
@@ -81,646 +73,287 @@
using namespace ::com::sun::star;
-/*****************************************************************************
- * Description:
- * SwTxtFly's purpose is to be the universal interface between
- * formatting/text output and the possibly overlapping free-flying frames.
- * During formatting the formatter gets the information from SwTxtFly, whether
- * a certain area is present by the attributes of an overlapping frame.
- * Such areas are represented by dummy portions.
- * The whole text output and touch-up is, again, forwarded to a SwTxtFly.
- * This one decides, whether parts of the text need to be clipped and splits
- * the areas for e.g. a DrawRect.
- * Please note that all free-flying frames are located in a PtrArray, sorted
- * by TopLeft.
- * Internally we always use document-global values. The IN and OUT parameters
- * are, however, adjusted to the needs of the LineIter most of the time. That
- * is: they are converted to frame- and window-local coordinates.
- * If multiple frames with wrap attributes are located on the same line, we get
- * the following settings for the text flow:
- *
- * L/R P L R N
- * P -P-P- -P-L -P R- -P N
- * L -L P- -L L -L R- -L N
- * R R-P- R-L R R- R N
- * N N P- N L N R- N N
- *
- * (P=parallel, L=left, R=right, N=no wrap)
- *
- * We can describe the behaviour as follows:
- * Every frame can push away text, with the restriction that it only has influence
- * until the next frame.
- *****************************************************************************/
-
-void SwTxtFormatter::CalcUnclipped( SwTwips& rTop, SwTwips& rBottom )
-{
- OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
- "SwTxtFormatter::CalcUnclipped with unswapped frame" );
-
- long nFlyAsc, nFlyDesc;
- pCurr->MaxAscentDescent( rTop, rBottom, nFlyAsc, nFlyDesc );
- rTop = Y() + GetCurr()->GetAscent();
- rBottom = rTop + nFlyDesc;
- rTop -= nFlyAsc;
-}
-
-/*************************************************************************
- * SwTxtFormatter::UpdatePos()
- * Updates the reference points of the character anchored objects,
- * e.g. after adjusting right-aligned, justified etc.
- * (That's mainly to correct the x position)
- *************************************************************************/
-
-void SwTxtFormatter::UpdatePos( SwLineLayout *pCurrent, Point aStart,
- xub_StrLen nStartIdx, sal_Bool bAllWays ) const
+namespace
{
- OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
- "SwTxtFormatter::UpdatePos with unswapped frame" );
-
- if( GetInfo().IsTest() )
- return;
- SwLinePortion *pFirst = pCurrent->GetFirstPortion();
- SwLinePortion *pPos = pFirst;
- SwTxtPaintInfo aTmpInf( GetInfo() );
- aTmpInf.SetpSpaceAdd( pCurrent->GetpLLSpaceAdd() );
- aTmpInf.ResetSpaceIdx();
- aTmpInf.SetKanaComp( pCurrent->GetpKanaComp() );
- aTmpInf.ResetKanaIdx();
-
- // The frame's size
- aTmpInf.SetIdx( nStartIdx );
- aTmpInf.SetPos( aStart );
-
- long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
- pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
-
- KSHORT nTmpHeight = pCurrent->GetRealHeight();
- KSHORT nAscent = pCurrent->GetAscent() + nTmpHeight - pCurrent->Height();
- objectpositioning::AsCharFlags nFlags = AS_CHAR_ULSPACE;
- if( GetMulti() )
+ // #i68520#
+ struct AnchoredObjOrder
{
- aTmpInf.SetDirection( GetMulti()->GetDirection() );
- if( GetMulti()->HasRotation() )
- {
- nFlags |= AS_CHAR_ROTATE;
- if( GetMulti()->IsRevers() )
- {
- nFlags |= AS_CHAR_REVERSE;
- aTmpInf.X( aTmpInf.X() - nAscent );
- }
- else
- aTmpInf.X( aTmpInf.X() + nAscent );
- }
- else
- {
- if ( GetMulti()->IsBidi() )
- nFlags |= AS_CHAR_BIDI;
- aTmpInf.Y( aTmpInf.Y() + nAscent );
- }
- }
- else
- aTmpInf.Y( aTmpInf.Y() + nAscent );
+ sal_Bool mbR2L;
+ SwRectFn mfnRect;
- while( pPos )
- {
- // We only know one case where changing the position (caused by the
- // adjustment) could be relevant for a portion: We need to SetRefPoint
- // for FlyCntPortions.
- if( ( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
- && ( bAllWays || !IsQuick() ) )
- {
- pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
+ AnchoredObjOrder( const sal_Bool bR2L,
+ SwRectFn fnRect )
+ : mbR2L( bR2L ),
+ mfnRect( fnRect )
+ {}
- if( pPos->IsGrfNumPortion() )
+ bool operator()( const SwAnchoredObject* pListedAnchoredObj,
+ const SwAnchoredObject* pNewAnchoredObj )
+ {
+ const SwRect aBoundRectOfListedObj( pListedAnchoredObj->GetObjRectWithSpaces() );
+ const SwRect aBoundRectOfNewObj( pNewAnchoredObj->GetObjRectWithSpaces() );
+ if ( ( mbR2L &&
+ ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ==
+ (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
+ ( !mbR2L &&
+ ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ==
+ (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
{
- if( !nFlyAsc && !nFlyDesc )
+ SwTwips nTopDiff =
+ (*mfnRect->fnYDiff)( (aBoundRectOfNewObj.*mfnRect->fnGetTop)(),
+ (aBoundRectOfListedObj.*mfnRect->fnGetTop)() );
+ if ( nTopDiff == 0 &&
+ ( ( mbR2L &&
+ ( (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() >
+ (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ) ) ||
+ ( !mbR2L &&
+ ( (aBoundRectOfNewObj.*mfnRect->fnGetRight)() <
+ (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ) ) ) )
{
- nTmpAscent = nAscent;
- nFlyAsc = nAscent;
- nTmpDescent = nTmpHeight - nAscent;
- nFlyDesc = nTmpDescent;
+ return true;
+ }
+ else if ( nTopDiff > 0 )
+ {
+ return true;
}
- ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
- nFlyAsc, nFlyDesc );
}
- else
+ else if ( ( mbR2L &&
+ ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() >
+ (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
+ ( !mbR2L &&
+ ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() <
+ (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
{
- Point aBase( aTmpInf.GetPos() );
- if ( GetInfo().GetTxtFrm()->IsVertical() )
- GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aBase );
-
- ((SwFlyCntPortion*)pPos)->SetBase( *aTmpInf.GetTxtFrm(),
- aBase, nTmpAscent, nTmpDescent, nFlyAsc,
- nFlyDesc, nFlags );
+ return true;
}
- }
- if( pPos->IsMultiPortion() && ((SwMultiPortion*)pPos)->HasFlyInCntnt() )
- {
- OSL_ENSURE( !GetMulti(), "Too much multi" );
- ((SwTxtFormatter*)this)->pMulti = (SwMultiPortion*)pPos;
- SwLineLayout *pLay = &GetMulti()->GetRoot();
- Point aSt( aTmpInf.X(), aStart.Y() );
- if ( GetMulti()->HasBrackets() )
- {
- OSL_ENSURE( GetMulti()->IsDouble(), "Brackets only for doubles");
- aSt.X() += ((SwDoubleLinePortion*)GetMulti())->PreWidth();
- }
- else if( GetMulti()->HasRotation() )
- {
- aSt.Y() += pCurrent->GetAscent() - GetMulti()->GetAscent();
- if( GetMulti()->IsRevers() )
- aSt.X() += GetMulti()->Width();
- else
- aSt.Y() += GetMulti()->Height();
- }
- else if ( GetMulti()->IsBidi() )
- // jump to end of the bidi portion
- aSt.X() += pLay->Width();
-
- xub_StrLen nStIdx = aTmpInf.GetIdx();
- do
- {
- UpdatePos( pLay, aSt, nStIdx, bAllWays );
- nStIdx = nStIdx + pLay->GetLen();
- aSt.Y() += pLay->Height();
- pLay = pLay->GetNext();
- } while ( pLay );
- ((SwTxtFormatter*)this)->pMulti = NULL;
+ return false;
}
- pPos->Move( aTmpInf );
- pPos = pPos->GetPortion();
- }
+ };
}
-/*************************************************************************
- * SwTxtFormatter::AlignFlyInCntBase()
- * If needed, re-adjusts the character anchored objects to the y axis.
- *************************************************************************/
-
-void SwTxtFormatter::AlignFlyInCntBase( long nBaseLine ) const
+SwContourCache::SwContourCache() :
+ nPntCnt( 0 ), nObjCnt( 0 )
{
- OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
- "SwTxtFormatter::AlignFlyInCntBase with unswapped frame" );
-
- if( GetInfo().IsTest() )
- return;
- SwLinePortion *pFirst = pCurr->GetFirstPortion();
- SwLinePortion *pPos = pFirst;
- objectpositioning::AsCharFlags nFlags = AS_CHAR_NOFLAG;
- if( GetMulti() && GetMulti()->HasRotation() )
- {
- nFlags |= AS_CHAR_ROTATE;
- if( GetMulti()->IsRevers() )
- nFlags |= AS_CHAR_REVERSE;
- }
+ memset( (SdrObject**)pSdrObj, 0, sizeof(pSdrObj) );
+ memset( pTextRanger, 0, sizeof(pTextRanger) );
+}
- long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
+SwContourCache::~SwContourCache()
+{
+ for( MSHORT i = 0; i < nObjCnt; delete pTextRanger[ i++ ] )
+ ;
+}
- while( pPos )
- {
- if( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
- {
- pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
+void SwContourCache::ClrObject( MSHORT nPos )
+{
+ OSL_ENSURE( pTextRanger[ nPos ], "ClrObject: Allready cleared. Good Bye!" );
+ nPntCnt -= pTextRanger[ nPos ]->GetPointCount();
+ delete pTextRanger[ nPos ];
+ --nObjCnt;
+ memmove( (SdrObject**)pSdrObj + nPos, pSdrObj + nPos + 1,
+ ( nObjCnt - nPos ) * sizeof( SdrObject* ) );
+ memmove( pTextRanger + nPos, pTextRanger + nPos + 1,
+ ( nObjCnt - nPos ) * sizeof( TextRanger* ) );
+}
- if( pPos->IsGrfNumPortion() )
- ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
- nFlyAsc, nFlyDesc );
- else
+void ClrContourCache( const SdrObject *pObj )
+{
+ if( pContourCache && pObj )
+ for( MSHORT i = 0; i < pContourCache->GetCount(); ++i )
+ if( pObj == pContourCache->GetObject( i ) )
{
- Point aBase;
- if ( GetInfo().GetTxtFrm()->IsVertical() )
- {
- nBaseLine = GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( nBaseLine );
- aBase = Point( nBaseLine, ((SwFlyCntPortion*)pPos)->GetRefPoint().Y() );
- }
- else
- aBase = Point( ((SwFlyCntPortion*)pPos)->GetRefPoint().X(), nBaseLine );
-
- ((SwFlyCntPortion*)pPos)->SetBase( *GetInfo().GetTxtFrm(), aBase, nTmpAscent, nTmpDescent,
- nFlyAsc, nFlyDesc, nFlags );
+ pContourCache->ClrObject( i );
+ break;
}
- }
- pPos = pPos->GetPortion();
- }
}
-/*************************************************************************
- * SwTxtFly::ChkFlyUnderflow()
- * This is called after the real height of the line has been calculated.
- * Therefore it is possible, that more flys from below intersect with the
- * line, or that flys from above do not intersect with the line anymore.
- * We check this and return true, meaning that the line has to be
- * formatted again.
- *************************************************************************/
-
-sal_Bool SwTxtFormatter::ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const
+void ClrContourCache()
{
- OSL_ENSURE( rInf.GetTxtFly()->IsOn(), "SwTxtFormatter::ChkFlyUnderflow: why?" );
- if( GetCurr() )
+ if( pContourCache )
{
- // First we check, whether a fly overlaps with the line.
- // = GetLineHeight()
- const long nHeight = GetCurr()->GetRealHeight();
- SwRect aLine( GetLeftMargin(), Y(), rInf.RealWidth(), nHeight );
-
- SwRect aLineVert( aLine );
- if ( pFrm->IsVertical() )
- pFrm->SwitchHorizontalToVertical( aLineVert );
- SwRect aInter( rInf.GetTxtFly()->GetFrm( aLineVert ) );
- if ( pFrm->IsVertical() )
- pFrm->SwitchVerticalToHorizontal( aInter );
-
- if( !aInter.HasArea() )
- return sal_False;
-
- // We now check every portion that could have lowered for overlapping
- // with the fly.
- const SwLinePortion *pPos = GetCurr()->GetFirstPortion();
- aLine.Pos().Y() = Y() + GetCurr()->GetRealHeight() - GetCurr()->Height();
- aLine.Height( GetCurr()->Height() );
-
- while( pPos )
- {
- aLine.Width( pPos->Width() );
-
- aLineVert = aLine;
- if ( pFrm->IsVertical() )
- pFrm->SwitchHorizontalToVertical( aLineVert );
- aInter = rInf.GetTxtFly()->GetFrm( aLineVert );
- if ( pFrm->IsVertical() )
- pFrm->SwitchVerticalToHorizontal( aInter );
-
- // New flys from below?
- if( !pPos->IsFlyPortion() )
- {
- if( aInter.IsOver( aLine ) )
- {
- aInter._Intersection( aLine );
- if( aInter.HasArea() )
- {
- // To be evaluated during reformat of this line:
- // RealHeight including spacing
- rInf.SetLineHeight( KSHORT(nHeight) );
- // Height without extra spacing
- rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
- return sal_True;
- }
- }
- }
- else
- {
- // The fly portion is not intersected by a fly anymore
- if ( ! aInter.IsOver( aLine ) )
- {
- rInf.SetLineHeight( KSHORT(nHeight) );
- rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
- return sal_True;
- }
- else
- {
- aInter._Intersection( aLine );
-
- // No area means a fly has become invalid because of
- // lowering the line => reformat the line.
- // We also have to reformat the line, if the fly size
- // differs from the intersection interval's size.
- if( ! aInter.HasArea() ||
- ((SwFlyPortion*)pPos)->GetFixWidth() != aInter.Width() )
- {
- rInf.SetLineHeight( KSHORT(nHeight) );
- rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
- return sal_True;
- }
- }
- }
-
- aLine.Left( aLine.Left() + pPos->Width() );
- pPos = pPos->GetPortion();
- }
+ for( MSHORT i = 0; i < pContourCache->GetCount();
+ delete pContourCache->pTextRanger[ i++ ] )
+ ;
+ pContourCache->nObjCnt = 0;
+ pContourCache->nPntCnt = 0;
}
- return sal_False;
}
-/*************************************************************************
- * SwTxtFormatter::CalcFlyWidth()
- * Determines the next object, that reaches into the rest of the line and
- * constructs the appropriate FlyPortion.
- * We use SwTxtFly.GetFrm(..) for that.
- *************************************************************************/
-
-// The right margin can be shortened by Flys.
-
-void SwTxtFormatter::CalcFlyWidth( SwTxtFormatInfo &rInf )
+// #i68520#
+const SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
+ const SwRect &rLine,
+ const SwTxtFrm* pFrm,
+ const long nXPos,
+ const sal_Bool bRight )
{
- if( GetMulti() || rInf.GetFly() )
- return;
-
- SwTxtFly *pTxtFly = rInf.GetTxtFly();
- if( !pTxtFly->IsOn() || rInf.IsIgnoreFly() )
- return;
-
- const SwLinePortion *pLast = rInf.GetLast();
-
- long nAscent;
- long nTop = Y();
- long nHeight;
-
- if( rInf.GetLineHeight() )
+ SwRect aRet;
+ const SwFrmFmt* pFmt = &(pAnchoredObj->GetFrmFmt());
+ if( pFmt->GetSurround().IsContour() &&
+ ( !pAnchoredObj->ISA(SwFlyFrm) ||
+ ( static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower() &&
+ static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower()->IsNoTxtFrm() ) ) )
{
- // Real line height has already been calculated, we only have to
- // search for intersections in the lower part of the strip
- nAscent = pCurr->GetAscent();
- nHeight = rInf.GetLineNettoHeight();
- nTop += rInf.GetLineHeight() - nHeight;
+ aRet = pAnchoredObj->GetObjRectWithSpaces();
+ if( aRet.IsOver( rLine ) )
+ {
+ if( !pContourCache )
+ pContourCache = new SwContourCache;
+
+ aRet = pContourCache->ContourRect(
+ pFmt, pAnchoredObj->GetDrawObj(), pFrm, rLine, nXPos, bRight );
+ }
+ else
+ aRet.Width( 0 );
}
else
{
- nAscent = pLast->GetAscent();
- nHeight = pLast->Height();
-
- // We make a first guess for the line's real height
- if ( ! pCurr->GetRealHeight() )
- CalcRealHeight();
-
- if ( pCurr->GetRealHeight() > nHeight )
- nTop += pCurr->GetRealHeight() - nHeight;
- else
- // Important for fixed space between lines
- nHeight = pCurr->GetRealHeight();
+ aRet = pAnchoredObj->GetObjRectWithSpaces();
}
- const long nLeftMar = GetLeftMargin();
- const long nLeftMin = (rInf.X() || GetDropLeft()) ? nLeftMar : GetLeftMin();
-
- SwRect aLine( rInf.X() + nLeftMin, nTop, rInf.RealWidth() - rInf.X()
- + nLeftMar - nLeftMin , nHeight );
-
- SwRect aLineVert( aLine );
- if ( pFrm->IsRightToLeft() )
- pFrm->SwitchLTRtoRTL( aLineVert );
-
- if ( pFrm->IsVertical() )
- pFrm->SwitchHorizontalToVertical( aLineVert );
- SwRect aInter( pTxtFly->GetFrm( aLineVert ) );
-
- if ( pFrm->IsRightToLeft() )
- pFrm->SwitchRTLtoLTR( aInter );
-
- if ( pFrm->IsVertical() )
- pFrm->SwitchVerticalToHorizontal( aInter );
+ return aRet;
+}
- if( aInter.IsOver( aLine ) )
+const SwRect SwContourCache::ContourRect( const SwFmt* pFmt,
+ const SdrObject* pObj, const SwTxtFrm* pFrm, const SwRect &rLine,
+ const long nXPos, const sal_Bool bRight )
+{
+ SwRect aRet;
+ MSHORT nPos = 0; // Suche im Cache ...
+ while( nPos < GetCount() && pObj != pSdrObj[ nPos ] )
+ ++nPos;
+ if( GetCount() == nPos ) // nicht gefunden
{
- aLine.Left( rInf.X() + nLeftMar );
- sal_Bool bForced = sal_False;
- if( aInter.Left() <= nLeftMin )
- {
- SwTwips nFrmLeft = GetTxtFrm()->Frm().Left();
- if( GetTxtFrm()->Prt().Left() < 0 )
- nFrmLeft += GetTxtFrm()->Prt().Left();
- if( aInter.Left() < nFrmLeft )
- aInter.Left( nFrmLeft );
-
- long nAddMar = 0;
- if ( pFrm->IsRightToLeft() )
- {
- nAddMar = pFrm->Frm().Right() - Right();
- if ( nAddMar < 0 )
- nAddMar = 0;
- }
- else
- nAddMar = nLeftMar - nFrmLeft;
-
- aInter.Width( aInter.Width() + nAddMar );
- // For a negative first line indent, we set this flag to show
- // that the indentation/margin has been moved.
- // This needs to be respected by the DefaultTab at the zero position.
- if( IsFirstTxtLine() && HasNegFirst() )
- bForced = sal_True;
- }
- aInter.Intersection( aLine );
- if( !aInter.HasArea() )
- return;
-
- const sal_Bool bFullLine = aLine.Left() == aInter.Left() &&
- aLine.Right() == aInter.Right();
-
- // Although no text is left, we need to format another line,
- // because also empty lines need to avoid a Fly with no wrapping.
- if( bFullLine && rInf.GetIdx() == rInf.GetTxt().Len() )
+ if( nObjCnt == POLY_CNT )
{
- rInf.SetNewLine( sal_True );
- // 8221: We know that for dummies, it holds ascent == height
- pCurr->SetDummy(sal_True);
+ nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
+ delete pTextRanger[ nObjCnt ];
}
+ ::basegfx::B2DPolyPolygon aPolyPolygon;
+ ::basegfx::B2DPolyPolygon* pPolyPolygon = 0L;
- // aInter becomes frame-local
- aInter.Pos().X() -= nLeftMar;
- SwFlyPortion *pFly = new SwFlyPortion( aInter );
- if( bForced )
+ if ( pObj->ISA(SwVirtFlyDrawObj) )
{
- pCurr->SetForcedLeftMargin( sal_True );
- rInf.ForcedLeftMargin( (sal_uInt16)aInter.Width() );
+ // Vorsicht #37347: Das GetContour() fuehrt zum Laden der Grafik,
+ // diese aendert dadurch ggf. ihre Groesse, ruft deshalb ein
+ // ClrObject() auf.
+ PolyPolygon aPoly;
+ if( !((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetContour( aPoly ) )
+ aPoly = PolyPolygon( ((SwVirtFlyDrawObj*)pObj)->
+ GetFlyFrm()->Frm().SVRect() );
+ aPolyPolygon.clear();
+ aPolyPolygon.append(aPoly.getB2DPolyPolygon());
}
-
- if( bFullLine )
+ else
{
- // 8110: In order to properly flow around Flys with different
- // wrapping attributes, we need to increase by units of line height.
- // The last avoiding line should be adjusted in height, so that
- // we don't get a frame spacing effect.
- // 8221: It is important that ascent == height, because the FlyPortion
- // values are transferred to pCurr in CalcLine and IsDummy() relies
- // on this behaviour.
- // To my knowledge we only have two places where DummyLines can be
- // created: here and in MakeFlyDummies.
- // IsDummy() is evaluated in IsFirstTxtLine(), when moving lines
- // and in relation with DropCaps.
- pFly->Height( KSHORT(aInter.Height()) );
-
- // nNextTop now contains the margin's bottom edge, which we avoid
- // or the next margin's top edge, which we need to respect.
- // That means we can comfortably grow up to this value; that's how
- // we save a few empty lines.
- long nNextTop = pTxtFly->GetNextTop();
- if ( pFrm->IsVertical() )
- nNextTop = pFrm->SwitchVerticalToHorizontal( nNextTop );
- if( nNextTop > aInter.Bottom() )
+ if( !pObj->ISA( E3dObject ) )
{
- SwTwips nH = nNextTop - aInter.Top();
- if( nH < KSHRT_MAX )
- pFly->Height( KSHORT( nH ) );
+ aPolyPolygon = pObj->TakeXorPoly();
}
- if( nAscent < pFly->Height() )
- pFly->SetAscent( KSHORT(nAscent) );
- else
- pFly->SetAscent( pFly->Height() );
+
+ ::basegfx::B2DPolyPolygon aContourPoly(pObj->TakeContour());
+ pPolyPolygon = new ::basegfx::B2DPolyPolygon(aContourPoly);
}
- else
+ const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
+ const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
+ memmove( pTextRanger + 1, pTextRanger, nObjCnt * sizeof( TextRanger* ) );
+ memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nObjCnt++ * sizeof( SdrObject* ) );
+ pSdrObj[ 0 ] = pObj; // Wg. #37347 darf das Object erst nach dem
+ // GetContour() eingetragen werden.
+ pTextRanger[ 0 ] = new TextRanger( aPolyPolygon, pPolyPolygon, 20,
+ (sal_uInt16)rLRSpace.GetLeft(), (sal_uInt16)rLRSpace.GetRight(),
+ pFmt->GetSurround().IsOutside(), sal_False, pFrm->IsVertical() );
+ pTextRanger[ 0 ]->SetUpper( rULSpace.GetUpper() );
+ pTextRanger[ 0 ]->SetLower( rULSpace.GetLower() );
+
+ delete pPolyPolygon;
+ // UPPER_LOWER_TEST
+#ifdef DBG_UTIL
+ const ViewShell* pTmpViewShell = pFmt->GetDoc()->GetCurrentViewShell();
+ if( pTmpViewShell )
{
- if( rInf.GetIdx() == rInf.GetTxt().Len() )
- {
- // Don't use nHeight, or we have a huge descent
- pFly->Height( pLast->Height() );
- pFly->SetAscent( pLast->GetAscent() );
- }
- else
+ sal_Bool bT2 = pTmpViewShell->GetViewOptions()->IsTest2();
+ sal_Bool bT6 = pTmpViewShell->GetViewOptions()->IsTest6();
+ if( bT2 || bT6 )
{
- pFly->Height( KSHORT(aInter.Height()) );
- if( nAscent < pFly->Height() )
- pFly->SetAscent( KSHORT(nAscent) );
+ if( bT2 )
+ pTextRanger[ 0 ]->SetFlag7( sal_True );
else
- pFly->SetAscent( pFly->Height() );
+ pTextRanger[ 0 ]->SetFlag6( sal_True );
}
}
-
- rInf.SetFly( pFly );
-
- if( pFly->Fix() < rInf.Width() )
- rInf.Width( pFly->Fix() );
-
- GETGRID( pFrm->FindPageFrm() )
- if ( pGrid )
+#endif
+ nPntCnt += pTextRanger[ 0 ]->GetPointCount();
+ while( nPntCnt > POLY_MAX && nObjCnt > POLY_MIN )
{
- const SwPageFrm* pPageFrm = pFrm->FindPageFrm();
- const SwLayoutFrm* pBody = pPageFrm->FindBodyCont();
-
- SWRECTFN( pPageFrm )
-
- const long nGridOrigin = pBody ?
- (pBody->*fnRect->fnGetPrtLeft)() :
- (pPageFrm->*fnRect->fnGetPrtLeft)();
-
- const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
- const sal_uInt16 nGridWidth = GETGRIDWIDTH( pGrid, pDoc); // For textgrid refactor
-
- SwTwips nStartX = GetLeftMargin();
- if ( bVert )
- {
- Point aPoint( nStartX, 0 );
- pFrm->SwitchHorizontalToVertical( aPoint );
- nStartX = aPoint.Y();
- }
-
- const SwTwips nOfst = nStartX - nGridOrigin;
- const SwTwips nTmpWidth = rInf.Width() + nOfst;
-
- const sal_uLong i = nTmpWidth / nGridWidth + 1;
-
- const long nNewWidth = ( i - 1 ) * nGridWidth - nOfst;
- if ( nNewWidth > 0 )
- rInf.Width( (sal_uInt16)nNewWidth );
- else
- rInf.Width( 0 );
+ nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
+ delete pTextRanger[ nObjCnt ];
}
}
-}
-
-/*****************************************************************************
- * SwTxtFormatter::NewFlyCntPortion
- * Creates a new portion for a character anchored object.
- *****************************************************************************/
-
-SwFlyCntPortion *SwTxtFormatter::NewFlyCntPortion( SwTxtFormatInfo &rInf,
- SwTxtAttr *pHint ) const
-{
- SwFlyCntPortion *pRet = 0;
- const SwFrm *pFrame = (SwFrm*)pFrm;
-
- SwFlyInCntFrm *pFly;
- SwFrmFmt* pFrmFmt = ((SwTxtFlyCnt*)pHint)->GetFlyCnt().GetFrmFmt();
- if( RES_FLYFRMFMT == pFrmFmt->Which() )
- pFly = ((SwTxtFlyCnt*)pHint)->GetFlyFrm(pFrame);
- else
- pFly = NULL;
- // aBase is the document-global position, from which the new extra portion is placed
- // aBase.X() = Offset in in the line after the current position
- // aBase.Y() = LineIter.Y() + Ascent of the current position
-
- long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
- // OD 08.01.2004 #i11859# - use new method <SwLineLayout::MaxAscentDescent(..)>
- //SwLinePortion *pPos = pCurr->GetFirstPortion();
- //lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
- pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
-
- // If the ascent of the frame is larger than the ascent of the current position,
- // we use this one when calculating the base, or the frame would be positioned
- // too much to the top, sliding down after all causing a repaint in an area
- // he actually never was in.
- KSHORT nAscent = 0;
-
- const bool bTxtFrmVertical = GetInfo().GetTxtFrm()->IsVertical();
-
- const bool bUseFlyAscent = pFly && pFly->GetValidPosFlag() &&
- 0 != ( bTxtFrmVertical ?
- pFly->GetRefPoint().X() :
- pFly->GetRefPoint().Y() );
-
- if ( bUseFlyAscent )
- nAscent = static_cast<sal_uInt16>( Abs( int( bTxtFrmVertical ?
- pFly->GetRelPos().X() :
- pFly->GetRelPos().Y() ) ) );
-
- // Check if we prefer to use the ascent of the last portion:
- if ( IsQuick() ||
- !bUseFlyAscent ||
- nAscent < rInf.GetLast()->GetAscent() )
+ else if( nPos )
{
- nAscent = rInf.GetLast()->GetAscent();
+ const SdrObject* pTmpObj = pSdrObj[ nPos ];
+ TextRanger* pTmpRanger = pTextRanger[ nPos ];
+ memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nPos * sizeof( SdrObject* ) );
+ memmove( pTextRanger + 1, pTextRanger, nPos * sizeof( TextRanger* ) );
+ pSdrObj[ 0 ] = pTmpObj;
+ pTextRanger[ 0 ] = pTmpRanger;
}
- else if( nAscent > nFlyAsc )
- nFlyAsc = nAscent;
+ SWRECTFN( pFrm )
+ long nTmpTop = (rLine.*fnRect->fnGetTop)();
+ // fnGetBottom is top + height
+ long nTmpBottom = (rLine.*fnRect->fnGetBottom)();
- Point aBase( GetLeftMargin() + rInf.X(), Y() + nAscent );
- objectpositioning::AsCharFlags nMode = IsQuick() ? AS_CHAR_QUICK : 0;
- if( GetMulti() && GetMulti()->HasRotation() )
- {
- nMode |= AS_CHAR_ROTATE;
- if( GetMulti()->IsRevers() )
- nMode |= AS_CHAR_REVERSE;
- }
+ Range aRange( Min( nTmpTop, nTmpBottom ), Max( nTmpTop, nTmpBottom ) );
- Point aTmpBase( aBase );
- if ( GetInfo().GetTxtFrm()->IsVertical() )
- GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
+ LongDqPtr pTmp = pTextRanger[ 0 ]->GetTextRanges( aRange );
- if( pFly )
+ MSHORT nCount;
+ if( 0 != ( nCount = pTmp->size() ) )
{
- pRet = new SwFlyCntPortion( *GetInfo().GetTxtFrm(), pFly, aTmpBase,
- nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
- // We need to make sure that our font is set again in the OutputDevice
- // It could be that the FlyInCnt was added anew and GetFlyFrm() would
- // in turn cause, that it'd be created anew again.
- // This one's frames get formatted right away, which change the font and
- // we have a bug (3322).
- rInf.SelectFont();
- if( pRet->GetAscent() > nAscent )
+ MSHORT nIdx = 0;
+ while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos )
+ ++nIdx;
+ sal_Bool bOdd = (nIdx % 2) ? sal_True : sal_False;
+ sal_Bool bSet = sal_True;
+ if( bOdd )
+ --nIdx; // innerhalb eines Intervalls
+ else if( ! bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) )
{
- aBase.Y() = Y() + pRet->GetAscent();
- nMode |= AS_CHAR_ULSPACE;
- if( !rInf.IsTest() )
- aTmpBase = aBase;
- if ( GetInfo().GetTxtFrm()->IsVertical() )
- GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
-
- pRet->SetBase( *rInf.GetTxtFrm(), aTmpBase, nTmpAscent,
- nTmpDescent, nFlyAsc, nFlyDesc, nMode );
+ if( nIdx )
+ nIdx -= 2; // ein Intervall nach links gehen
+ else
+ bSet = sal_False; // vor dem erstem Intervall
+ }
+
+ if( bSet && nIdx < nCount )
+ {
+ (aRet.*fnRect->fnSetTopAndHeight)( (rLine.*fnRect->fnGetTop)(),
+ (rLine.*fnRect->fnGetHeight)() );
+ (aRet.*fnRect->fnSetLeft)( (*pTmp)[ nIdx ] );
+ (aRet.*fnRect->fnSetRight)( (*pTmp)[ nIdx + 1 ] + 1 );
}
}
- else
- {
- pRet = new SwFlyCntPortion( *rInf.GetTxtFrm(), (SwDrawContact*)pFrmFmt->FindContactObj(),
- aTmpBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
- }
- return pRet;
+ return aRet;
}
+SwTxtFly::SwTxtFly() :
+ pPage(0),
+ mpCurrAnchoredObj(0),
+ pCurrFrm(0),
+ pMaster(0),
+ mpAnchoredObjList(0),
+ nMinBottom(0),
+ nNextTop(0),
+ nIndex(0)
+{
+}
-/*************************************************************************
- * SwTxtFly::SwTxtFly()
- *************************************************************************/
+SwTxtFly::SwTxtFly( const SwTxtFrm *pFrm )
+{
+ CtorInitTxtFly( pFrm );
+}
SwTxtFly::SwTxtFly( const SwTxtFly& rTxtFly )
{
@@ -748,6 +381,11 @@ SwTxtFly::SwTxtFly( const SwTxtFly& rTxtFly )
mbIgnoreObjsInHeaderFooter = rTxtFly.mbIgnoreObjsInHeaderFooter;
}
+SwTxtFly::~SwTxtFly()
+{
+ delete mpAnchoredObjList;
+}
+
void SwTxtFly::CtorInitTxtFly( const SwTxtFrm *pFrm )
{
mbIgnoreCurrentFrame = sal_False;
@@ -774,16 +412,6 @@ void SwTxtFly::CtorInitTxtFly( const SwTxtFrm *pFrm )
nIndex = ULONG_MAX;
}
-/*************************************************************************
- * SwTxtFly::_GetFrm()
- *
- * IN: document-global (rRect)
- * OUT: frame-local (return value)
- *
- * This method is called during formatting of LineIter in order to:
- * 1. prepare the next FlyPortion
- * 2. remember new overlappings after changes to the line height
- *************************************************************************/
SwRect SwTxtFly::_GetFrm( const SwRect &rRect, sal_Bool bTop ) const
{
@@ -804,15 +432,6 @@ SwRect SwTxtFly::_GetFrm( const SwRect &rRect, sal_Bool bTop ) const
return aRet;
}
-/*************************************************************************
- * SwTxtFly::IsAnyFrm()
- *
- * IN: document-global
- * for the print area of the current frame
- *
- * Is used to disable the SwTxtFly if no objects overlap (relax)
- *
- *************************************************************************/
sal_Bool SwTxtFly::IsAnyFrm() const
{
@@ -827,16 +446,6 @@ sal_Bool SwTxtFly::IsAnyFrm() const
return bRet;
}
-/*************************************************************************
- * SwTxtFly::IsAnyObj()
- *
- * IN: document-global
- * OUT: sal_True If a frame or DrawObj needs to be respected
- *
- * Only if this method returns sal_False, we can use optimizations like
- * Paint/FormatEmpty for empty paragraphs and also the virtual OutputDevice.
- *************************************************************************/
-
sal_Bool SwTxtFly::IsAnyObj( const SwRect &rRect ) const
{
OSL_ENSURE( bOn, "SwTxtFly::IsAnyObj: Who's knocking?" );
@@ -876,17 +485,6 @@ const SwCntntFrm* SwTxtFly::_GetMaster()
return pMaster;
}
-/*************************************************************************
- * SwTxtFly::DrawTextOpaque()
- *
- * IN: document-global
- *
- * DrawTextOpaque() is called by DrawText().
- * The ClipRegions are placed int a way, that only those parts are displayed
- * which are not within the areas of FlyFrms which are opaque and above the
- * current Frame.
- * DrawText() takes over the on optimization!
- *************************************************************************/
sal_Bool SwTxtFly::DrawTextOpaque( SwDrawTextInfo &rInf )
{
@@ -1011,14 +609,6 @@ sal_Bool SwTxtFly::DrawTextOpaque( SwDrawTextInfo &rInf )
return sal_True;
}
-/*************************************************************************
- * SwTxtFly::DrawFlyRect()
- *
- * IN: window-local
- * We need to keep two subtelties in mind:
- * 1) DrawRect() above the ClipRect are allowed!
- * 2) FlyToRect() returns larger values than the frame data!
- *************************************************************************/
void SwTxtFly::DrawFlyRect( OutputDevice* pOut, const SwRect &rRect,
const SwTxtPaintInfo &rInf, sal_Bool bNoGraphic )
@@ -1284,61 +874,6 @@ sal_Bool SwTxtFly::GetTop( const SwAnchoredObject* _pAnchoredObj,
}
return sal_False;
}
-// #i68520#
-struct AnchoredObjOrder
-{
- sal_Bool mbR2L;
- SwRectFn mfnRect;
-
- AnchoredObjOrder( const sal_Bool bR2L,
- SwRectFn fnRect )
- : mbR2L( bR2L ),
- mfnRect( fnRect )
- {}
-
- bool operator()( const SwAnchoredObject* pListedAnchoredObj,
- const SwAnchoredObject* pNewAnchoredObj )
- {
- const SwRect aBoundRectOfListedObj( pListedAnchoredObj->GetObjRectWithSpaces() );
- const SwRect aBoundRectOfNewObj( pNewAnchoredObj->GetObjRectWithSpaces() );
- if ( ( mbR2L &&
- ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ==
- (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
- ( !mbR2L &&
- ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ==
- (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
- {
- SwTwips nTopDiff =
- (*mfnRect->fnYDiff)( (aBoundRectOfNewObj.*mfnRect->fnGetTop)(),
- (aBoundRectOfListedObj.*mfnRect->fnGetTop)() );
- if ( nTopDiff == 0 &&
- ( ( mbR2L &&
- ( (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() >
- (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ) ) ||
- ( !mbR2L &&
- ( (aBoundRectOfNewObj.*mfnRect->fnGetRight)() <
- (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ) ) ) )
- {
- return true;
- }
- else if ( nTopDiff > 0 )
- {
- return true;
- }
- }
- else if ( ( mbR2L &&
- ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() >
- (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
- ( !mbR2L &&
- ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() <
- (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
- {
- return true;
- }
-
- return false;
- }
-};
// #i68520#
SwAnchoredObjList* SwTxtFly::InitAnchoredObjList()
@@ -1503,234 +1038,6 @@ SwTwips SwTxtFly::CalcMinBottom() const
return nRet;
}
-/*************************************************************************
- * Hier erfolgt die Berechnung der Kontur ...
- * CalcBoundRect(..) und andere
- *************************************************************************/
-
-/*************************************************************************
- * class SwContourCache
- *************************************************************************/
-
-SwContourCache::SwContourCache() :
- nPntCnt( 0 ), nObjCnt( 0 )
-{
- memset( (SdrObject**)pSdrObj, 0, sizeof(pSdrObj) );
- memset( pTextRanger, 0, sizeof(pTextRanger) );
-}
-
-SwContourCache::~SwContourCache()
-{
- for( MSHORT i = 0; i < nObjCnt; delete pTextRanger[ i++ ] )
- ;
-}
-
-void SwContourCache::ClrObject( MSHORT nPos )
-{
- OSL_ENSURE( pTextRanger[ nPos ], "ClrObject: Allready cleared. Good Bye!" );
- nPntCnt -= pTextRanger[ nPos ]->GetPointCount();
- delete pTextRanger[ nPos ];
- --nObjCnt;
- memmove( (SdrObject**)pSdrObj + nPos, pSdrObj + nPos + 1,
- ( nObjCnt - nPos ) * sizeof( SdrObject* ) );
- memmove( pTextRanger + nPos, pTextRanger + nPos + 1,
- ( nObjCnt - nPos ) * sizeof( TextRanger* ) );
-}
-
-void ClrContourCache( const SdrObject *pObj )
-{
- if( pContourCache && pObj )
- for( MSHORT i = 0; i < pContourCache->GetCount(); ++i )
- if( pObj == pContourCache->GetObject( i ) )
- {
- pContourCache->ClrObject( i );
- break;
- }
-}
-
-void ClrContourCache()
-{
- if( pContourCache )
- {
- for( MSHORT i = 0; i < pContourCache->GetCount();
- delete pContourCache->pTextRanger[ i++ ] )
- ;
- pContourCache->nObjCnt = 0;
- pContourCache->nPntCnt = 0;
- }
-}
-
-/*************************************************************************
- * SwContourCache::CalcBoundRect
- * berechnet das Rechteck, welches vom Objekt in der angegebenen Zeile
- * ueberdeckt wird.
- * Bei _nicht_ konturumflossenen Objekten ist dies einfach die Ueber-
- * lappung von BoundRect (inkl. Abstand!) und Zeile,
- * bei Konturumfluss wird das Polypolygon des Objekts abgeklappert
- *************************************************************************/
-// #i68520#
-const SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
- const SwRect &rLine,
- const SwTxtFrm* pFrm,
- const long nXPos,
- const sal_Bool bRight )
-{
- SwRect aRet;
- const SwFrmFmt* pFmt = &(pAnchoredObj->GetFrmFmt());
- if( pFmt->GetSurround().IsContour() &&
- ( !pAnchoredObj->ISA(SwFlyFrm) ||
- ( static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower() &&
- static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower()->IsNoTxtFrm() ) ) )
- {
- aRet = pAnchoredObj->GetObjRectWithSpaces();
- if( aRet.IsOver( rLine ) )
- {
- if( !pContourCache )
- pContourCache = new SwContourCache;
-
- aRet = pContourCache->ContourRect(
- pFmt, pAnchoredObj->GetDrawObj(), pFrm, rLine, nXPos, bRight );
- }
- else
- aRet.Width( 0 );
- }
- else
- {
- aRet = pAnchoredObj->GetObjRectWithSpaces();
- }
-
- return aRet;
-}
-
-const SwRect SwContourCache::ContourRect( const SwFmt* pFmt,
- const SdrObject* pObj, const SwTxtFrm* pFrm, const SwRect &rLine,
- const long nXPos, const sal_Bool bRight )
-{
- SwRect aRet;
- MSHORT nPos = 0; // Suche im Cache ...
- while( nPos < GetCount() && pObj != pSdrObj[ nPos ] )
- ++nPos;
- if( GetCount() == nPos ) // nicht gefunden
- {
- if( nObjCnt == POLY_CNT )
- {
- nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
- delete pTextRanger[ nObjCnt ];
- }
- ::basegfx::B2DPolyPolygon aPolyPolygon;
- ::basegfx::B2DPolyPolygon* pPolyPolygon = 0L;
-
- if ( pObj->ISA(SwVirtFlyDrawObj) )
- {
- // Vorsicht #37347: Das GetContour() fuehrt zum Laden der Grafik,
- // diese aendert dadurch ggf. ihre Groesse, ruft deshalb ein
- // ClrObject() auf.
- PolyPolygon aPoly;
- if( !((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetContour( aPoly ) )
- aPoly = PolyPolygon( ((SwVirtFlyDrawObj*)pObj)->
- GetFlyFrm()->Frm().SVRect() );
- aPolyPolygon.clear();
- aPolyPolygon.append(aPoly.getB2DPolyPolygon());
- }
- else
- {
- if( !pObj->ISA( E3dObject ) )
- {
- aPolyPolygon = pObj->TakeXorPoly();
- }
-
- ::basegfx::B2DPolyPolygon aContourPoly(pObj->TakeContour());
- pPolyPolygon = new ::basegfx::B2DPolyPolygon(aContourPoly);
- }
- const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
- const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
- memmove( pTextRanger + 1, pTextRanger, nObjCnt * sizeof( TextRanger* ) );
- memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nObjCnt++ * sizeof( SdrObject* ) );
- pSdrObj[ 0 ] = pObj; // Wg. #37347 darf das Object erst nach dem
- // GetContour() eingetragen werden.
- pTextRanger[ 0 ] = new TextRanger( aPolyPolygon, pPolyPolygon, 20,
- (sal_uInt16)rLRSpace.GetLeft(), (sal_uInt16)rLRSpace.GetRight(),
- pFmt->GetSurround().IsOutside(), sal_False, pFrm->IsVertical() );
- pTextRanger[ 0 ]->SetUpper( rULSpace.GetUpper() );
- pTextRanger[ 0 ]->SetLower( rULSpace.GetLower() );
-
- delete pPolyPolygon;
- // UPPER_LOWER_TEST
-#ifdef DBG_UTIL
- const ViewShell* pTmpViewShell = pFmt->GetDoc()->GetCurrentViewShell();
- if( pTmpViewShell )
- {
- sal_Bool bT2 = pTmpViewShell->GetViewOptions()->IsTest2();
- sal_Bool bT6 = pTmpViewShell->GetViewOptions()->IsTest6();
- if( bT2 || bT6 )
- {
- if( bT2 )
- pTextRanger[ 0 ]->SetFlag7( sal_True );
- else
- pTextRanger[ 0 ]->SetFlag6( sal_True );
- }
- }
-#endif
- nPntCnt += pTextRanger[ 0 ]->GetPointCount();
- while( nPntCnt > POLY_MAX && nObjCnt > POLY_MIN )
- {
- nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
- delete pTextRanger[ nObjCnt ];
- }
- }
- else if( nPos )
- {
- const SdrObject* pTmpObj = pSdrObj[ nPos ];
- TextRanger* pTmpRanger = pTextRanger[ nPos ];
- memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nPos * sizeof( SdrObject* ) );
- memmove( pTextRanger + 1, pTextRanger, nPos * sizeof( TextRanger* ) );
- pSdrObj[ 0 ] = pTmpObj;
- pTextRanger[ 0 ] = pTmpRanger;
- }
- SWRECTFN( pFrm )
- long nTmpTop = (rLine.*fnRect->fnGetTop)();
- // fnGetBottom is top + height
- long nTmpBottom = (rLine.*fnRect->fnGetBottom)();
-
- Range aRange( Min( nTmpTop, nTmpBottom ), Max( nTmpTop, nTmpBottom ) );
-
- LongDqPtr pTmp = pTextRanger[ 0 ]->GetTextRanges( aRange );
-
- MSHORT nCount;
- if( 0 != ( nCount = pTmp->size() ) )
- {
- MSHORT nIdx = 0;
- while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos )
- ++nIdx;
- sal_Bool bOdd = (nIdx % 2) ? sal_True : sal_False;
- sal_Bool bSet = sal_True;
- if( bOdd )
- --nIdx; // innerhalb eines Intervalls
- else if( ! bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) )
- {
- if( nIdx )
- nIdx -= 2; // ein Intervall nach links gehen
- else
- bSet = sal_False; // vor dem erstem Intervall
- }
-
- if( bSet && nIdx < nCount )
- {
- (aRet.*fnRect->fnSetTopAndHeight)( (rLine.*fnRect->fnGetTop)(),
- (rLine.*fnRect->fnGetHeight)() );
- (aRet.*fnRect->fnSetLeft)( (*pTmp)[ nIdx ] );
- (aRet.*fnRect->fnSetRight)( (*pTmp)[ nIdx + 1 ] + 1 );
- }
- }
- return aRet;
-}
-
-/*************************************************************************
- * SwTxtFly::ForEach()
- *
- * sucht nach dem ersten Objekt, welches mit dem Rechteck ueberlappt
- *
- *************************************************************************/
sal_Bool SwTxtFly::ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const
{
@@ -1817,11 +1124,6 @@ sal_Bool SwTxtFly::ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid
return bRet;
}
-/*************************************************************************
- * SwTxtFly::GetPos()
- *
- * liefert die Position im sorted Array zurueck
- *************************************************************************/
// #i68520#
SwAnchoredObjList::size_type SwTxtFly::GetPos( const SwAnchoredObject* pAnchoredObj ) const
@@ -1833,14 +1135,6 @@ SwAnchoredObjList::size_type SwTxtFly::GetPos( const SwAnchoredObject* pAnchored
return nRet;
}
-/*************************************************************************
- * SwTxtFly::CalcRightMargin()
- *
- * pObj ist das Object, der uns gerade ueberlappt.
- * pCurrFrm ist der aktuelle Textframe, der ueberlappt wird.
- * Der rechte Rand ist der rechte Rand oder
- * er wird durch das naechste Object, welches in die Zeile ragt, bestimmt.
- *************************************************************************/
// #i68520#
void SwTxtFly::CalcRightMargin( SwRect &rFly,
SwAnchoredObjList::size_type nFlyPos,
@@ -1932,14 +1226,6 @@ void SwTxtFly::CalcRightMargin( SwRect &rFly,
(rFly.*fnRect->fnSetRight)( nRight );
}
-/*************************************************************************
- * SwTxtFly::CalcLeftMargin()
- *
- * pFly ist der FlyFrm, der uns gerade ueberlappt.
- * pCurrFrm ist der aktuelle Textframe, der ueberlappt wird.
- * Der linke Rand ist der linke Rand der aktuellen PrintArea oder
- * er wird durch den vorigen FlyFrm, der in die Zeile ragt, bestimmt.
- *************************************************************************/
// #i68520#
void SwTxtFly::CalcLeftMargin( SwRect &rFly,
SwAnchoredObjList::size_type nFlyPos,
@@ -2006,15 +1292,6 @@ void SwTxtFly::CalcLeftMargin( SwRect &rFly,
}
// #i68520#
-/**
- Computes the bounds of an anchored object. This takes the
- object wrapping and contour into account.
-
- @param pAnchoredObj the object for which to get the bounds
- @param rLine the bounds of the line to format
-
- @return the flying object bounds
- */
SwRect SwTxtFly::AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj,
const SwRect &rLine ) const
{
@@ -2070,27 +1347,11 @@ SwRect SwTxtFly::AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj,
}
// #i68520#
-// new method <_GetSurroundForTextWrap(..)> replaces methods
-// <CalcSmart(..)> and <GetOrder(..)>
-/*************************************************************************
- * SwTxtFly::CalcSmart()
- *
- * CalcSmart() liefert die Umlaufform zurueck.
- *
- * Auf beiden Seiten ist weniger als 2 cm Platz fuer den Text
- * => kein Umlauf ( SURROUND_NONE )
- * Auf genau einer Seite ist mehr als 2 cm Platz
- * => Umlauf auf dieser Seite ( SURROUND_LEFT / SURROUND_RIGHT )
- * Auf beiden Seiten ist mehr als 2 cm Platz, das Objekt ist breiter als 1,5 cm
- * => Umlauf auf der breiteren Seite ( SURROUND_LEFT / SURROUND_RIGHT )
- * Auf beiden Seiten ist mehr als 2 cm Platz, das Objekt ist schmaler als 1,5 cm
- * => beidseitiger Umlauf ( SURROUND_PARALLEL )
- *
- *************************************************************************/
-// Umfluss nur auf Seiten mit mindestens 2 cm Platz fuer den Text
+// Wrap only on sides with at least 2cm space for the text
#define TEXT_MIN 1134
-// Beidseitiger Umfluss bis zu einer Rahmenbreite von maximal 1,5 cm
+
+// Wrap on both sides up to a frame width of 1.5cm
#define FRAME_MAX 850
SwSurround SwTxtFly::_GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const
@@ -2160,15 +1421,6 @@ SwSurround SwTxtFly::_GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredO
return eSurroundForTextWrap;
}
-/*************************************************************************
- * SwTxtFly::IsAnyFrm( SwRect )
- *
- * IN: document-global
- *
- * dient zum Abschalten des SwTxtFly, wenn keine Objekte ueberlappen (Relax)
- *
- *************************************************************************/
-
sal_Bool SwTxtFly::IsAnyFrm( const SwRect &rLine ) const
{