Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/outdev.hxx>
31 : : #include <vcl/virdev.hxx>
32 : :
33 : : #include "pagefrm.hxx"
34 : : #include "rootfrm.hxx"
35 : : #include "pam.hxx" // SwPosition
36 : : #include "swregion.hxx" // SwRegionRects
37 : : #include "dflyobj.hxx" // SdrObject
38 : : #include "flyfrm.hxx" // SwFlyFrm
39 : : #include "frmtool.hxx" // ::DrawGraphic
40 : : #include "porfly.hxx" // NewFlyCntPortion
41 : : #include "porfld.hxx" // SwGrfNumPortion
42 : : #include "txtfly.hxx" // SwTxtFly
43 : : #include "txtpaint.hxx" // SwSaveClip
44 : : #include "txtatr.hxx" // SwTxtFlyCnt
45 : : #include "notxtfrm.hxx"
46 : : #include "fmtcnct.hxx" // SwFmtChain
47 : : #include "inftxt.hxx"
48 : : #include <pormulti.hxx> // SwMultiPortion
49 : : #include <svx/obj3d.hxx>
50 : : #include <editeng/txtrange.hxx>
51 : : #include <editeng/lrspitem.hxx>
52 : : #include <editeng/ulspitem.hxx>
53 : : // #i28701#
54 : : #include <editeng/lspcitem.hxx>
55 : : #include <fmtsrnd.hxx>
56 : : #include <fmtanchr.hxx>
57 : : #include <frmfmt.hxx>
58 : : #include <pagedesc.hxx> // SwPageDesc
59 : : #include <tgrditem.hxx>
60 : : #include <sortedobjs.hxx>
61 : : #include <layouter.hxx>
62 : : #include <IDocumentDrawModelAccess.hxx>
63 : : #include <IDocumentLayoutAccess.hxx>
64 : : #include <IDocumentSettingAccess.hxx>
65 : : #include <svx/svdoedge.hxx>
66 : :
67 : : #ifdef DBG_UTIL
68 : : #include "viewsh.hxx"
69 : : #include "viewopt.hxx" // SwViewOptions, only for testing (Test2)
70 : : #include "doc.hxx"
71 : : #endif
72 : :
73 : :
74 : : using namespace ::com::sun::star;
75 : :
76 : : namespace
77 : : {
78 : : // #i68520#
79 : : struct AnchoredObjOrder
80 : : {
81 : : sal_Bool mbR2L;
82 : : SwRectFn mfnRect;
83 : :
84 : 1095 : AnchoredObjOrder( const sal_Bool bR2L,
85 : : SwRectFn fnRect )
86 : : : mbR2L( bR2L ),
87 : 1095 : mfnRect( fnRect )
88 : 1095 : {}
89 : :
90 : 386 : bool operator()( const SwAnchoredObject* pListedAnchoredObj,
91 : : const SwAnchoredObject* pNewAnchoredObj )
92 : : {
93 [ + - ]: 386 : const SwRect aBoundRectOfListedObj( pListedAnchoredObj->GetObjRectWithSpaces() );
94 [ + - ]: 386 : const SwRect aBoundRectOfNewObj( pNewAnchoredObj->GetObjRectWithSpaces() );
95 [ # # ][ + - ]: 772 : if ( ( mbR2L &&
[ + + ][ + + ]
[ - + ]
96 [ # # ][ # # ]: 0 : ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ==
97 [ # # ][ # # ]: 0 : (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
98 : 386 : ( !mbR2L &&
99 [ + - ][ + - ]: 386 : ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ==
100 [ + - ][ + - ]: 386 : (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
101 : : {
102 : : SwTwips nTopDiff =
103 : 201 : (*mfnRect->fnYDiff)( (aBoundRectOfNewObj.*mfnRect->fnGetTop)(),
104 [ + - ][ + - ]: 67 : (aBoundRectOfListedObj.*mfnRect->fnGetTop)() );
[ + - ][ + - ]
[ + - ]
105 [ + + ][ - + ]: 125 : if ( nTopDiff == 0 &&
[ # # ][ + - ]
[ - + ][ - + ]
106 : : ( ( mbR2L &&
107 [ # # ][ # # ]: 0 : ( (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() >
108 [ # # ][ # # ]: 0 : (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ) ) ||
109 : 58 : ( !mbR2L &&
110 [ + - ][ + - ]: 58 : ( (aBoundRectOfNewObj.*mfnRect->fnGetRight)() <
111 [ + - ][ + - ]: 58 : (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ) ) ) )
112 : : {
113 : 0 : return true;
114 : : }
115 [ + + ]: 67 : else if ( nTopDiff > 0 )
116 : : {
117 : 9 : return true;
118 : : }
119 : : }
120 [ - + ][ # # ]: 638 : else if ( ( mbR2L &&
[ + - ][ + + ]
[ + + ]
121 [ # # ][ # # ]: 0 : ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() >
122 [ # # ][ # # ]: 0 : (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
123 : 319 : ( !mbR2L &&
124 [ + - ][ + - ]: 319 : ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() <
125 [ + - ][ + - ]: 319 : (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
126 : : {
127 : 147 : return true;
128 : : }
129 : :
130 : 386 : return false;
131 : : }
132 : : };
133 : : }
134 : :
135 : 2 : SwContourCache::SwContourCache() :
136 : 2 : nPntCnt( 0 ), nObjCnt( 0 )
137 : : {
138 : 2 : memset( (SdrObject**)pSdrObj, 0, sizeof(pSdrObj) );
139 : 2 : memset( pTextRanger, 0, sizeof(pTextRanger) );
140 : 2 : }
141 : :
142 : 2 : SwContourCache::~SwContourCache()
143 : : {
144 [ # # ][ - + ]: 2 : for( MSHORT i = 0; i < nObjCnt; delete pTextRanger[ i++ ] )
145 : : ;
146 : 2 : }
147 : :
148 : 16 : void SwContourCache::ClrObject( MSHORT nPos )
149 : : {
150 : : OSL_ENSURE( pTextRanger[ nPos ], "ClrObject: Allready cleared. Good Bye!" );
151 : 16 : nPntCnt -= pTextRanger[ nPos ]->GetPointCount();
152 [ + - ]: 16 : delete pTextRanger[ nPos ];
153 : 16 : --nObjCnt;
154 : 16 : memmove( (SdrObject**)pSdrObj + nPos, pSdrObj + nPos + 1,
155 : 32 : ( nObjCnt - nPos ) * sizeof( SdrObject* ) );
156 : 16 : memmove( pTextRanger + nPos, pTextRanger + nPos + 1,
157 : 32 : ( nObjCnt - nPos ) * sizeof( TextRanger* ) );
158 : 16 : }
159 : :
160 : 1275 : void ClrContourCache( const SdrObject *pObj )
161 : : {
162 [ + + ][ + - ]: 1275 : if( pContourCache && pObj )
163 [ + + ]: 57 : for( MSHORT i = 0; i < pContourCache->GetCount(); ++i )
164 [ + - ]: 16 : if( pObj == pContourCache->GetObject( i ) )
165 : : {
166 : 16 : pContourCache->ClrObject( i );
167 : 16 : break;
168 : : }
169 : 1275 : }
170 : :
171 : 1299 : void ClrContourCache()
172 : : {
173 [ + + ]: 1299 : if( pContourCache )
174 : : {
175 [ # # ][ - + ]: 82 : for( MSHORT i = 0; i < pContourCache->GetCount();
176 : 0 : delete pContourCache->pTextRanger[ i++ ] )
177 : : ;
178 : 82 : pContourCache->nObjCnt = 0;
179 : 82 : pContourCache->nPntCnt = 0;
180 : : }
181 : 1299 : }
182 : :
183 : : // #i68520#
184 : 1365 : const SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
185 : : const SwRect &rLine,
186 : : const SwTxtFrm* pFrm,
187 : : const long nXPos,
188 : : const sal_Bool bRight )
189 : : {
190 : 1365 : SwRect aRet;
191 : 1365 : const SwFrmFmt* pFmt = &(pAnchoredObj->GetFrmFmt());
192 [ + + ][ + + : 1509 : if( pFmt->GetSurround().IsContour() &&
+ - + - +
- ]
193 : 48 : ( !pAnchoredObj->ISA(SwFlyFrm) ||
194 [ + - ]: 48 : ( static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower() &&
195 [ + - ]: 48 : static_cast<const SwFlyFrm*>(pAnchoredObj)->Lower()->IsNoTxtFrm() ) ) )
196 : : {
197 : 48 : aRet = pAnchoredObj->GetObjRectWithSpaces();
198 [ + - ]: 48 : if( aRet.IsOver( rLine ) )
199 : : {
200 [ + + ]: 48 : if( !pContourCache )
201 : 2 : pContourCache = new SwContourCache;
202 : :
203 : : aRet = pContourCache->ContourRect(
204 : 48 : pFmt, pAnchoredObj->GetDrawObj(), pFrm, rLine, nXPos, bRight );
205 : : }
206 : : else
207 : 0 : aRet.Width( 0 );
208 : : }
209 : : else
210 : : {
211 : 1317 : aRet = pAnchoredObj->GetObjRectWithSpaces();
212 : : }
213 : :
214 : 1365 : return aRet;
215 : : }
216 : :
217 : 48 : const SwRect SwContourCache::ContourRect( const SwFmt* pFmt,
218 : : const SdrObject* pObj, const SwTxtFrm* pFrm, const SwRect &rLine,
219 : : const long nXPos, const sal_Bool bRight )
220 : : {
221 : 48 : SwRect aRet;
222 : 48 : MSHORT nPos = 0; // Suche im Cache ...
223 [ + + ][ - + ]: 48 : while( nPos < GetCount() && pObj != pSdrObj[ nPos ] )
[ - + ]
224 : 0 : ++nPos;
225 [ + + ]: 48 : if( GetCount() == nPos ) // nicht gefunden
226 : : {
227 [ - + ]: 16 : if( nObjCnt == POLY_CNT )
228 : : {
229 : 0 : nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
230 [ # # ][ # # ]: 0 : delete pTextRanger[ nObjCnt ];
231 : : }
232 [ + - ]: 16 : ::basegfx::B2DPolyPolygon aPolyPolygon;
233 : 16 : ::basegfx::B2DPolyPolygon* pPolyPolygon = 0L;
234 : :
235 [ + - ][ + - ]: 16 : if ( pObj->ISA(SwVirtFlyDrawObj) )
[ + - ]
236 : : {
237 : : // GetContour() causes the graphic to be loaded, which may cause
238 : : // the graphic to change its size, call ClrObject()
239 [ + - ]: 16 : PolyPolygon aPoly;
240 [ + - ][ + - ]: 16 : if( !((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetContour( aPoly ) )
241 : : aPoly = PolyPolygon( ((SwVirtFlyDrawObj*)pObj)->
242 [ + - ][ + - ]: 16 : GetFlyFrm()->Frm().SVRect() );
[ + - ][ + - ]
[ + - ][ + - ]
243 [ + - ]: 16 : aPolyPolygon.clear();
244 [ + - ][ + - ]: 16 : aPolyPolygon.append(aPoly.getB2DPolyPolygon());
[ + - ][ + - ]
245 : : }
246 : : else
247 : : {
248 [ # # ][ # # ]: 0 : if( !pObj->ISA( E3dObject ) )
[ # # ]
249 : : {
250 [ # # ][ # # ]: 0 : aPolyPolygon = pObj->TakeXorPoly();
[ # # ]
251 : : }
252 : :
253 [ # # ]: 0 : ::basegfx::B2DPolyPolygon aContourPoly(pObj->TakeContour());
254 [ # # ][ # # ]: 0 : pPolyPolygon = new ::basegfx::B2DPolyPolygon(aContourPoly);
[ # # ]
255 : : }
256 [ + - ]: 16 : const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
257 [ + - ]: 16 : const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
258 : 16 : memmove( pTextRanger + 1, pTextRanger, nObjCnt * sizeof( TextRanger* ) );
259 : 16 : memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nObjCnt++ * sizeof( SdrObject* ) );
260 : 16 : pSdrObj[ 0 ] = pObj; // due to #37347 the Object must be entered only
261 : : // after GetContour()
262 : : pTextRanger[ 0 ] = new TextRanger( aPolyPolygon, pPolyPolygon, 20,
263 : 16 : (sal_uInt16)rLRSpace.GetLeft(), (sal_uInt16)rLRSpace.GetRight(),
264 [ + - ][ + - ]: 16 : pFmt->GetSurround().IsOutside(), sal_False, pFrm->IsVertical() );
[ + - ][ + - ]
265 : 16 : pTextRanger[ 0 ]->SetUpper( rULSpace.GetUpper() );
266 : 16 : pTextRanger[ 0 ]->SetLower( rULSpace.GetLower() );
267 : :
268 [ # # ][ - + ]: 16 : delete pPolyPolygon;
269 : : // UPPER_LOWER_TEST
270 : : #ifdef DBG_UTIL
271 : : const ViewShell* pTmpViewShell = pFmt->GetDoc()->GetCurrentViewShell();
272 : : if( pTmpViewShell )
273 : : {
274 : : sal_Bool bT2 = pTmpViewShell->GetViewOptions()->IsTest2();
275 : : sal_Bool bT6 = pTmpViewShell->GetViewOptions()->IsTest6();
276 : : if( bT2 || bT6 )
277 : : {
278 : : if( bT2 )
279 : : pTextRanger[ 0 ]->SetFlag7( sal_True );
280 : : else
281 : : pTextRanger[ 0 ]->SetFlag6( sal_True );
282 : : }
283 : : }
284 : : #endif
285 : 16 : nPntCnt += pTextRanger[ 0 ]->GetPointCount();
286 [ - + ][ # # ]: 16 : while( nPntCnt > POLY_MAX && nObjCnt > POLY_MIN )
[ - + ]
287 : : {
288 : 0 : nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount();
289 [ # # ][ # # ]: 0 : delete pTextRanger[ nObjCnt ];
290 [ + - ]: 16 : }
291 : : }
292 [ - + ]: 32 : else if( nPos )
293 : : {
294 : 0 : const SdrObject* pTmpObj = pSdrObj[ nPos ];
295 : 0 : TextRanger* pTmpRanger = pTextRanger[ nPos ];
296 : 0 : memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nPos * sizeof( SdrObject* ) );
297 : 0 : memmove( pTextRanger + 1, pTextRanger, nPos * sizeof( TextRanger* ) );
298 : 0 : pSdrObj[ 0 ] = pTmpObj;
299 : 0 : pTextRanger[ 0 ] = pTmpRanger;
300 : : }
301 [ + - ][ - + ]: 48 : SWRECTFN( pFrm )
[ # # ][ # # ]
[ - + ]
302 [ + - ][ + - ]: 48 : long nTmpTop = (rLine.*fnRect->fnGetTop)();
303 : : // fnGetBottom is top + height
304 [ + - ][ + - ]: 48 : long nTmpBottom = (rLine.*fnRect->fnGetBottom)();
305 : :
306 : 48 : Range aRange( Min( nTmpTop, nTmpBottom ), Max( nTmpTop, nTmpBottom ) );
307 : :
308 [ + - ]: 48 : LongDqPtr pTmp = pTextRanger[ 0 ]->GetTextRanges( aRange );
309 : :
310 : : MSHORT nCount;
311 [ + - ]: 48 : if( 0 != ( nCount = pTmp->size() ) )
312 : : {
313 : 48 : MSHORT nIdx = 0;
314 [ + - ][ + - ]: 48 : while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos )
[ - + ][ - + ]
315 : 0 : ++nIdx;
316 : 48 : sal_Bool bOdd = (nIdx % 2) ? sal_True : sal_False;
317 : 48 : sal_Bool bSet = sal_True;
318 [ - + ]: 48 : if( bOdd )
319 : 0 : --nIdx; // within interval
320 [ - + ][ # # ]: 48 : else if( ! bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) )
[ # # ][ # # ]
[ - + ]
321 : : {
322 [ # # ]: 0 : if( nIdx )
323 : 0 : nIdx -= 2; // an interval to the left
324 : : else
325 : 0 : bSet = sal_False; // before the first interval
326 : : }
327 : :
328 [ + - ][ + - ]: 48 : if( bSet && nIdx < nCount )
329 : : {
330 : 96 : (aRet.*fnRect->fnSetTopAndHeight)( (rLine.*fnRect->fnGetTop)(),
331 [ + - ][ + - ]: 48 : (rLine.*fnRect->fnGetHeight)() );
[ + - ][ + - ]
[ + - ][ + - ]
332 [ + - ][ + - ]: 48 : (aRet.*fnRect->fnSetLeft)( (*pTmp)[ nIdx ] );
[ + - ]
333 [ + - ][ + - ]: 48 : (aRet.*fnRect->fnSetRight)( (*pTmp)[ nIdx + 1 ] + 1 );
[ + - ]
334 : : }
335 : : }
336 : 48 : return aRet;
337 : : }
338 : :
339 : :
340 : 28680 : SwTxtFly::SwTxtFly() :
341 : : pPage(0),
342 : : mpCurrAnchoredObj(0),
343 : : pCurrFrm(0),
344 : : pMaster(0),
345 : : mpAnchoredObjList(0),
346 : : nMinBottom(0),
347 : : nNextTop(0),
348 : 28680 : nIndex(0)
349 : : {
350 : 28680 : }
351 : :
352 : 9769 : SwTxtFly::SwTxtFly( const SwTxtFrm *pFrm )
353 : : {
354 : 9769 : CtorInitTxtFly( pFrm );
355 : 9769 : }
356 : :
357 : 17545 : SwTxtFly::SwTxtFly( const SwTxtFly& rTxtFly )
358 : : {
359 : 17545 : pPage = rTxtFly.pPage;
360 : 17545 : mpCurrAnchoredObj = rTxtFly.mpCurrAnchoredObj;
361 : 17545 : pCurrFrm = rTxtFly.pCurrFrm;
362 : 17545 : pMaster = rTxtFly.pMaster;
363 [ + + ]: 17545 : if( rTxtFly.mpAnchoredObjList )
364 : : {
365 [ + - ]: 4169 : mpAnchoredObjList = new SwAnchoredObjList( *(rTxtFly.mpAnchoredObjList) );
366 : : }
367 : : else
368 : : {
369 : 13376 : mpAnchoredObjList = NULL;
370 : : }
371 : :
372 : 17545 : bOn = rTxtFly.bOn;
373 : 17545 : bLeftSide = rTxtFly.bLeftSide;
374 : 17545 : bTopRule = rTxtFly.bTopRule;
375 : 17545 : nMinBottom = rTxtFly.nMinBottom;
376 : 17545 : nNextTop = rTxtFly.nNextTop;
377 : 17545 : nIndex = rTxtFly.nIndex;
378 : 17545 : mbIgnoreCurrentFrame = rTxtFly.mbIgnoreCurrentFrame;
379 : 17545 : mbIgnoreContour = rTxtFly.mbIgnoreContour;
380 : 17545 : mbIgnoreObjsInHeaderFooter = rTxtFly.mbIgnoreObjsInHeaderFooter;
381 : 17545 : }
382 : :
383 : 55994 : SwTxtFly::~SwTxtFly()
384 : : {
385 [ + + ]: 55994 : delete mpAnchoredObjList;
386 : 55994 : }
387 : :
388 : 38449 : void SwTxtFly::CtorInitTxtFly( const SwTxtFrm *pFrm )
389 : : {
390 : 38449 : mbIgnoreCurrentFrame = sal_False;
391 : 38449 : mbIgnoreContour = sal_False;
392 : : // #118809#
393 : 38449 : mbIgnoreObjsInHeaderFooter = sal_False;
394 : 38449 : pPage = pFrm->FindPageFrm();
395 : 38449 : const SwFlyFrm* pTmp = pFrm->FindFlyFrm();
396 : : // #i68520#
397 [ + + ]: 38449 : mpCurrAnchoredObj = pTmp;
398 : 38449 : pCurrFrm = pFrm;
399 [ + + ]: 38449 : pMaster = pCurrFrm->IsFollow() ? NULL : pCurrFrm;
400 : : // #i68520#
401 : 38449 : mpAnchoredObjList = NULL;
402 : : // If we're not overlapped by a frame or if a FlyCollection does not exist
403 : : // at all, we switch off forever.
404 : : // It could be, however, that a line is added while formatting, that
405 : : // extends into a frame.
406 : : // That's why we do not optimize for: bOn = pSortedFlys && IsAnyFrm();
407 : 38449 : bOn = pPage->GetSortedObjs() != 0;
408 : 38449 : bTopRule = sal_True;
409 : 38449 : bLeftSide = sal_False;
410 : 38449 : nMinBottom = 0;
411 : 38449 : nIndex = ULONG_MAX;
412 : 38449 : }
413 : :
414 : :
415 : 3299 : SwRect SwTxtFly::_GetFrm( const SwRect &rRect, sal_Bool bTop ) const
416 : : {
417 : 3299 : SwRect aRet;
418 [ + + ]: 3299 : if( ForEach( rRect, &aRet, sal_True ) )
419 : : {
420 [ - + ][ # # ]: 1230 : SWRECTFN( pCurrFrm )
[ # # ][ - + ]
421 [ + - ]: 1230 : if( bTop )
422 [ + - ][ + - ]: 1230 : (aRet.*fnRect->fnSetTop)( (rRect.*fnRect->fnGetTop)() );
423 : :
424 : : // 8110: Do not always adapt the bottom
425 [ + - ]: 1230 : const SwTwips nRetBottom = (aRet.*fnRect->fnGetBottom)();
426 [ + - ]: 1230 : const SwTwips nRectBottom = (rRect.*fnRect->fnGetBottom)();
427 [ + + ]: 1525 : if ( (*fnRect->fnYDiff)( nRetBottom, nRectBottom ) > 0 ||
[ + + - + ]
428 [ + - ]: 295 : (aRet.*fnRect->fnGetHeight)() < 0 )
429 [ + - ]: 935 : (aRet.*fnRect->fnSetBottom)( nRectBottom );
430 : : }
431 : 3299 : return aRet;
432 : : }
433 : :
434 : :
435 : 1147 : sal_Bool SwTxtFly::IsAnyFrm() const
436 : : {
437 [ + - ][ - + ]: 1147 : SWAP_IF_SWAPPED( pCurrFrm )
[ # # ][ - + ]
[ # # ]
438 : :
439 : : OSL_ENSURE( bOn, "IsAnyFrm: Why?" );
440 : 1147 : SwRect aRect( pCurrFrm->Frm().Pos() + pCurrFrm->Prt().Pos(),
441 : 2294 : pCurrFrm->Prt().SSize() );
442 : :
443 [ + - ]: 1147 : const sal_Bool bRet = ForEach( aRect, NULL, sal_False );
444 [ - + ][ # # ]: 1147 : UNDO_SWAP( pCurrFrm )
445 : 1147 : return bRet;
446 : : }
447 : :
448 : 574 : sal_Bool SwTxtFly::IsAnyObj( const SwRect &rRect ) const
449 : : {
450 : : OSL_ENSURE( bOn, "SwTxtFly::IsAnyObj: Who's knocking?" );
451 : :
452 : 574 : SwRect aRect( rRect );
453 [ + - ]: 574 : if ( aRect.IsEmpty() )
454 : 574 : aRect = SwRect( pCurrFrm->Frm().Pos() + pCurrFrm->Prt().Pos(),
455 : 1148 : pCurrFrm->Prt().SSize() );
456 : :
457 : 574 : const SwSortedObjs *pSorted = pPage->GetSortedObjs();
458 [ + - ]: 574 : if( pSorted ) // bOn actually makes sure that we have objects on the side,
459 : : // but who knows who deleted somehting in the meantime?
460 : : {
461 [ + - ][ + + ]: 1044 : for ( MSHORT i = 0; i < pSorted->Count(); ++i )
462 : : {
463 [ + - ]: 766 : const SwAnchoredObject* pObj = (*pSorted)[i];
464 : :
465 [ + - ]: 766 : const SwRect aBound( pObj->GetObjRectWithSpaces() );
466 : :
467 : : // Optimization
468 [ + + ][ + - ]: 766 : if( pObj->GetObjRect().Left() > aRect.Right() )
469 : 91 : continue;
470 : :
471 : : // #i68520#
472 [ + + ][ + - ]: 675 : if( mpCurrAnchoredObj != pObj && aBound.IsOver( aRect ) )
[ + + ][ + + ]
473 : 675 : return sal_True;
474 : : }
475 : : }
476 : 574 : return sal_False;
477 : : }
478 : :
479 : 1708 : const SwCntntFrm* SwTxtFly::_GetMaster()
480 : : {
481 : 1708 : pMaster = pCurrFrm;
482 [ + - ][ + + ]: 3744 : while( pMaster && pMaster->IsFollow() )
[ + + ]
483 : 2036 : pMaster = (SwCntntFrm*)pMaster->FindMaster();
484 : 1708 : return pMaster;
485 : : }
486 : :
487 : :
488 : 206 : sal_Bool SwTxtFly::DrawTextOpaque( SwDrawTextInfo &rInf )
489 : : {
490 [ + - ]: 206 : SwSaveClip aClipSave( rInf.GetpOut() );
491 : 206 : SwRect aRect( rInf.GetPos(), rInf.GetSize() );
492 [ - + ]: 206 : if( rInf.GetSpace() )
493 : : {
494 : 0 : xub_StrLen nTmpLen = STRING_LEN == rInf.GetLen() ? rInf.GetText().Len() :
495 [ # # ]: 0 : rInf.GetLen();
496 [ # # ]: 0 : if( rInf.GetSpace() > 0 )
497 : : {
498 : 0 : xub_StrLen nSpaceCnt = 0;
499 : 0 : const xub_StrLen nEndPos = rInf.GetIdx() + nTmpLen;
500 [ # # ]: 0 : for( xub_StrLen nPos = rInf.GetIdx(); nPos < nEndPos; ++nPos )
501 : : {
502 [ # # ]: 0 : if( CH_BLANK == rInf.GetText().GetChar( nPos ) )
503 : 0 : ++nSpaceCnt;
504 : : }
505 [ # # ]: 0 : if( nSpaceCnt )
506 : 0 : aRect.Width( aRect.Width() + nSpaceCnt * rInf.GetSpace() );
507 : : }
508 : : else
509 : 0 : aRect.Width( aRect.Width() - nTmpLen * rInf.GetSpace() );
510 : : }
511 : :
512 [ + + ][ + - ]: 206 : if( aClipSave.IsOn() && rInf.GetOut().IsClipRegion() )
[ + + ]
513 : : {
514 [ + - ][ + - ]: 105 : SwRect aClipRect( rInf.GetOut().GetClipRegion().GetBoundRect() );
[ + - ][ + - ]
515 [ + - ]: 105 : aRect.Intersection( aClipRect );
516 : : }
517 : :
518 [ + - ]: 206 : SwRegionRects aRegion( aRect );
519 : :
520 : 206 : sal_Bool bOpaque = sal_False;
521 : : // #i68520#
522 : : const sal_uInt32 nCurrOrd = mpCurrAnchoredObj
523 [ # # ]: 0 : ? mpCurrAnchoredObj->GetDrawObj()->GetOrdNum()
524 [ - + ][ # # ]: 206 : : SAL_MAX_UINT32;
525 : : OSL_ENSURE( !bTopRule, "DrawTextOpaque: Wrong TopRule" );
526 : :
527 : : // #i68520#
528 [ + - ][ + - ]: 206 : SwAnchoredObjList::size_type nCount( bOn ? GetAnchoredObjList()->size() : 0 );
529 [ + - ][ + - ]: 206 : if ( bOn && nCount > 0 )
530 : : {
531 [ + - ][ + - ]: 206 : MSHORT nHellId = pPage->getRootFrm()->GetCurrShell()->getIDocumentDrawModelAccess()->GetHellId();
532 [ + + ]: 479 : for( MSHORT i = 0; i < nCount; ++i )
533 : : {
534 : : // #i68520#
535 [ + - ]: 273 : const SwAnchoredObject* pTmpAnchoredObj = (*mpAnchoredObjList)[i];
536 [ + - ][ + - ]: 546 : if( dynamic_cast<const SwFlyFrm*>(pTmpAnchoredObj) &&
[ + + ]
537 [ + + ]: 273 : mpCurrAnchoredObj != pTmpAnchoredObj )
538 : : {
539 : : // #i68520#
540 [ - + ]: 237 : const SwFlyFrm* pFly = dynamic_cast<const SwFlyFrm*>(pTmpAnchoredObj);
541 [ + - ][ - + ]: 237 : if( aRegion.GetOrigin().IsOver( pFly->Frm() ) )
542 : : {
543 [ # # ]: 0 : const SwFrmFmt *pFmt = pFly->GetFmt();
544 [ # # ]: 0 : const SwFmtSurround &rSur = pFmt->GetSurround();
545 [ # # ]: 0 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
546 : : // Only the ones who are opaque and more to the top
547 [ # # ][ # # : 0 : if( !( pFly->IsBackgroundTransparent()
# # # # ]
[ # # # #
# # ][ # # ]
[ # # ][ # # ]
548 [ # # ][ # # ]: 0 : || pFly->IsShadowTransparent() ) &&
549 : 0 : SURROUND_THROUGHT == rSur.GetSurround() &&
550 : 0 : ( !rSur.IsAnchorOnly() ||
551 : : // #i68520#
552 [ # # ][ # # ]: 0 : GetMaster() == pFly->GetAnchorFrm() ||
553 : 0 : ((FLY_AT_PARA != rAnchor.GetAnchorId()) &&
554 : 0 : (FLY_AT_CHAR != rAnchor.GetAnchorId())
555 : : )
556 : : ) &&
557 : : // #i68520#
558 [ # # ][ # # ]: 0 : pTmpAnchoredObj->GetDrawObj()->GetLayer() != nHellId &&
559 [ # # ][ # # ]: 0 : nCurrOrd < pTmpAnchoredObj->GetDrawObj()->GetOrdNum()
560 : : )
561 : : {
562 : : // Except for the content is transparent
563 : : const SwNoTxtFrm *pNoTxt =
564 : 0 : pFly->Lower() && pFly->Lower()->IsNoTxtFrm()
565 : 0 : ? (SwNoTxtFrm*)pFly->Lower()
566 [ # # # # ]: 0 : : 0;
567 [ # # ]: 0 : if ( !pNoTxt ||
[ # # # # ]
[ # # ]
568 [ # # ]: 0 : (!pNoTxt->IsTransparent() && !rSur.IsContour()) )
569 : : {
570 : 0 : bOpaque = sal_True;
571 [ # # ]: 0 : aRegion -= pFly->Frm();
572 : : }
573 : : }
574 : : }
575 : : }
576 : : }
577 : : }
578 : :
579 : 206 : Point aPos( rInf.GetPos().X(), rInf.GetPos().Y() + rInf.GetAscent() );
580 : 206 : const Point &rOld = rInf.GetPos();
581 : 206 : rInf.SetPos( aPos );
582 : :
583 [ + - ]: 206 : if( !bOpaque )
584 : : {
585 [ - + ]: 206 : if( rInf.GetKern() )
586 [ # # ]: 0 : rInf.GetFont()->_DrawStretchText( rInf );
587 : : else
588 [ + - ]: 206 : rInf.GetFont()->_DrawText( rInf );
589 : 206 : rInf.SetPos( rOld );
590 : 206 : return sal_False;
591 : : }
592 [ # # ]: 0 : else if( !aRegion.empty() )
593 : : {
594 : : // What a huge effort ...
595 [ # # ]: 0 : SwSaveClip aClipVout( rInf.GetpOut() );
596 [ # # ]: 0 : for( MSHORT i = 0; i < aRegion.size(); ++i )
597 : : {
598 : 0 : SwRect &rRect = aRegion[i];
599 [ # # ]: 0 : if( rRect != aRegion.GetOrigin() )
600 [ # # ]: 0 : aClipVout.ChgClip( rRect );
601 [ # # ]: 0 : if( rInf.GetKern() )
602 [ # # ]: 0 : rInf.GetFont()->_DrawStretchText( rInf );
603 : : else
604 [ # # ]: 0 : rInf.GetFont()->_DrawText( rInf );
605 [ # # ]: 0 : }
606 : : }
607 : 0 : rInf.SetPos( rOld );
608 [ + - ]: 206 : return sal_True;
609 : : }
610 : :
611 : :
612 : 80 : void SwTxtFly::DrawFlyRect( OutputDevice* pOut, const SwRect &rRect,
613 : : const SwTxtPaintInfo &rInf, sal_Bool bNoGraphic )
614 : : {
615 [ + - ]: 80 : SwRegionRects aRegion( rRect );
616 : : OSL_ENSURE( !bTopRule, "DrawFlyRect: Wrong TopRule" );
617 : : // #i68520#
618 [ + - ][ + - ]: 80 : SwAnchoredObjList::size_type nCount( bOn ? GetAnchoredObjList()->size() : 0 );
619 [ + - ][ + - ]: 80 : if ( bOn && nCount > 0 )
620 : : {
621 [ + - ][ + - ]: 80 : MSHORT nHellId = pPage->getRootFrm()->GetCurrShell()->getIDocumentDrawModelAccess()->GetHellId();
622 [ + + ]: 196 : for( MSHORT i = 0; i < nCount; ++i )
623 : : {
624 : : // #i68520#
625 [ + - ]: 116 : const SwAnchoredObject* pAnchoredObjTmp = (*mpAnchoredObjList)[i];
626 [ + - ][ + - ]: 232 : if( mpCurrAnchoredObj != pAnchoredObjTmp &&
[ + - ]
627 [ + - ]: 116 : dynamic_cast<const SwFlyFrm*>(pAnchoredObjTmp) )
628 : : {
629 : : // #i68520#
630 [ + - ][ + - ]: 116 : const SwFmtSurround& rSur = pAnchoredObjTmp->GetFrmFmt().GetSurround();
631 : :
632 : : // OD 24.01.2003 #106593# - correct clipping of fly frame area.
633 : : // Consider that fly frame background/shadow can be transparent
634 : : // and <SwAlignRect(..)> fly frame area
635 : : // #i68520#
636 [ - + ]: 116 : const SwFlyFrm* pFly = dynamic_cast<const SwFlyFrm*>(pAnchoredObjTmp);
637 : : // #i47804# - consider transparent graphics
638 : : // and OLE objects.
639 : : bool bClipFlyArea =
640 : 116 : ( ( SURROUND_THROUGHT == rSur.GetSurround() )
641 : : // #i68520#
642 [ # # ][ # # ]: 0 : ? (pAnchoredObjTmp->GetDrawObj()->GetLayer() != nHellId)
643 : 116 : : !rSur.IsContour() ) &&
644 [ + - ]: 116 : !pFly->IsBackgroundTransparent() &&
645 [ + - ]: 116 : !pFly->IsShadowTransparent() &&
646 : 116 : ( !pFly->Lower() ||
647 : 116 : !pFly->Lower()->IsNoTxtFrm() ||
648 [ # # + - ]: 696 : !static_cast<const SwNoTxtFrm*>(pFly->Lower())->IsTransparent() );
[ + - ][ + -
+ - + + ]
[ + - ][ - + ]
[ - + ]
649 [ + + ]: 116 : if ( bClipFlyArea )
650 : : {
651 : : // #i68520#
652 [ + - ]: 98 : SwRect aFly( pAnchoredObjTmp->GetObjRect() );
653 : : // OD 24.01.2003 #106593#
654 [ + - ]: 98 : ::SwAlignRect( aFly, pPage->getRootFrm()->GetCurrShell() );
655 [ + - ][ + - ]: 98 : if( aFly.Width() > 0 && aFly.Height() > 0 )
[ + - ]
656 [ + - ]: 98 : aRegion -= aFly;
657 : : }
658 : : }
659 : : }
660 : : }
661 : :
662 [ + + ]: 160 : for( MSHORT i = 0; i < aRegion.size(); ++i )
663 : : {
664 [ + - ]: 80 : if ( bNoGraphic )
665 [ + - ][ + - ]: 80 : pOut->DrawRect( aRegion[i].SVRect() );
666 : : else
667 : : {
668 : : OSL_ENSURE( ((SvxBrushItem*)-1) != rInf.GetBrushItem(),
669 : : "DrawRect: Uninitialized BrushItem!" );
670 : 0 : ::DrawGraphic( rInf.GetBrushItem(), pOut, rInf.GetBrushRect(),
671 [ # # ]: 0 : aRegion[i] );
672 : : }
673 : 80 : }
674 : 80 : }
675 : :
676 : : // #i26945# - change first parameter
677 : : // Now it's the <SwAnchoredObject> instance of the floating screen object
678 : 1962 : sal_Bool SwTxtFly::GetTop( const SwAnchoredObject* _pAnchoredObj,
679 : : const sal_Bool bInFtn,
680 : : const sal_Bool bInFooterOrHeader )
681 : : {
682 : : // #i68520#
683 : : // <mpCurrAnchoredObj> is set, if <pCurrFrm> is inside a fly frame
684 [ + + ]: 1962 : if( _pAnchoredObj != mpCurrAnchoredObj )
685 : : {
686 : : // #i26945#
687 : 1378 : const SdrObject* pNew = _pAnchoredObj->GetDrawObj();
688 : : // #102344# Ignore connectors which have one or more connections
689 [ - + ][ - + ]: 1378 : if(pNew && pNew->ISA(SdrEdgeObj))
[ + - ]
690 : : {
691 [ # # # # ]: 0 : if(((SdrEdgeObj*)pNew)->GetConnectedNode(sal_True)
[ # # ]
692 : 0 : || ((SdrEdgeObj*)pNew)->GetConnectedNode(sal_False))
693 : : {
694 : 0 : return sal_False;
695 : : }
696 : : }
697 : :
698 [ + - ][ - + ]: 1378 : if( ( bInFtn || bInFooterOrHeader ) && bTopRule )
[ # # ]
699 : : {
700 : : // #i26945#
701 : 0 : const SwFrmFmt& rFrmFmt = _pAnchoredObj->GetFrmFmt();
702 : 0 : const SwFmtAnchor& rNewA = rFrmFmt.GetAnchor();
703 [ # # ]: 0 : if (FLY_AT_PAGE == rNewA.GetAnchorId())
704 : : {
705 [ # # ]: 0 : if ( bInFtn )
706 : 0 : return sal_False;
707 : :
708 [ # # ]: 0 : if ( bInFooterOrHeader )
709 : : {
710 [ # # ][ # # ]: 0 : SwFmtVertOrient aVert( rFrmFmt.GetVertOrient() );
711 : 0 : sal_Bool bVertPrt = aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
712 [ # # ][ # # ]: 0 : aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA;
713 [ # # ]: 0 : if( bVertPrt )
714 [ # # ][ # # ]: 0 : return sal_False;
715 : : }
716 : : }
717 : : }
718 : :
719 : : // #i68520#
720 : : // bEvade: consider pNew, if we are not inside a fly
721 : : // consider pNew, if pNew is lower of <mpCurrAnchoredObj>
722 : 1378 : sal_Bool bEvade = !mpCurrAnchoredObj ||
723 [ + + ][ - + ]: 1378 : Is_Lower_Of( dynamic_cast<const SwFlyFrm*>(mpCurrAnchoredObj), pNew);
[ - + ]
724 : :
725 [ + + ]: 1378 : if ( !bEvade )
726 : : {
727 : : // We are currently inside a fly frame and pNew is not
728 : : // inside this fly frame. We can do some more checks if
729 : : // we have to consider pNew.
730 : :
731 : : // If bTopRule is not set, we ignore the frame types.
732 : : // We directly check the z-order
733 [ + + ]: 259 : if ( !bTopRule )
734 : 138 : bEvade = sal_True;
735 : : else
736 : : {
737 : : // Within chained Flys we only avoid Lower
738 : : // #i68520#
739 : 121 : const SwFmtChain &rChain = mpCurrAnchoredObj->GetFrmFmt().GetChain();
740 [ + - ][ + - ]: 121 : if ( !rChain.GetPrev() && !rChain.GetNext() )
[ + - ]
741 : : {
742 : : // #i26945#
743 : 121 : const SwFmtAnchor& rNewA = _pAnchoredObj->GetFrmFmt().GetAnchor();
744 : : // #i68520#
745 : 121 : const SwFmtAnchor& rCurrA = mpCurrAnchoredObj->GetFrmFmt().GetAnchor();
746 : :
747 : : // If <mpCurrAnchoredObj> is anchored as character, its content
748 : : // does not wrap around pNew
749 [ - + ]: 121 : if (FLY_AS_CHAR == rCurrA.GetAnchorId())
750 : 0 : return sal_False;
751 : :
752 : : // If pNew is anchored to page and <mpCurrAnchoredObj is not anchored
753 : : // to page, the content of <mpCurrAnchoredObj> does not wrap around pNew
754 : : // If both pNew and <mpCurrAnchoredObj> are anchored to page, we can do
755 : : // some more checks
756 [ + + ]: 121 : if (FLY_AT_PAGE == rNewA.GetAnchorId())
757 : : {
758 [ - + ]: 4 : if (FLY_AT_PAGE == rCurrA.GetAnchorId())
759 : : {
760 : 0 : bEvade = sal_True;
761 : : }
762 : : else
763 : 4 : return sal_False;
764 : : }
765 [ + + ]: 117 : else if (FLY_AT_PAGE == rCurrA.GetAnchorId())
766 : 25 : return sal_False; // Page anchored ones only avoid page anchored ones
767 [ - + ]: 92 : else if (FLY_AT_FLY == rNewA.GetAnchorId())
768 : 0 : bEvade = sal_True; // Non-page anchored ones avoid frame anchored ones
769 [ - + ]: 92 : else if( FLY_AT_FLY == rCurrA.GetAnchorId() )
770 : 0 : return sal_False; // Frame anchored ones do not avoid paragraph anchored ones
771 : : // #i57062#
772 : : // In order to avoid loop situation, it's decided to adjust
773 : : // the wrapping behaviour of content of at-paragraph/at-character
774 : : // anchored objects to one in the page header/footer and
775 : : // the document body --> content of at-paragraph/at-character
776 : : // anchored objects doesn't wrap around each other.
777 : : else
778 : 92 : return sal_False;
779 : : }
780 : : }
781 : :
782 : : // But: we never avoid a subordinate one and additionally we only avoid when overlapping.
783 : : // #i68520#
784 : 138 : bEvade &= ( mpCurrAnchoredObj->GetDrawObj()->GetOrdNum() < pNew->GetOrdNum() );
785 [ + + ]: 138 : if( bEvade )
786 : : {
787 : : // #i68520#
788 [ + - ]: 85 : SwRect aTmp( _pAnchoredObj->GetObjRectWithSpaces() );
789 [ + - ][ + + ]: 85 : if ( !aTmp.IsOver( mpCurrAnchoredObj->GetObjRectWithSpaces() ) )
[ + - ]
790 : 85 : bEvade = sal_False;
791 : : }
792 : : }
793 : :
794 [ + + ]: 1257 : if ( bEvade )
795 : : {
796 : : // #i26945#
797 : 1192 : const SwFmtAnchor& rNewA = _pAnchoredObj->GetFrmFmt().GetAnchor();
798 : : OSL_ENSURE( FLY_AS_CHAR != rNewA.GetAnchorId(),
799 : : "Don't call GetTop with a FlyInCntFrm" );
800 [ + + ]: 1192 : if (FLY_AT_PAGE == rNewA.GetAnchorId())
801 : 239 : return sal_True; // We always avoid page anchored ones
802 : :
803 : : // If Flys anchored at paragraph are caught in a FlyCnt, then
804 : : // their influence ends at the borders of the FlyCnt!
805 : : // If we are currently formatting the text of the FlyCnt, then
806 : : // it has to get out of the way of the Frm anchored at paragraph!
807 : : // pCurrFrm ist the anchor of pNew?
808 : : // #i26945#
809 : 953 : const SwFrm* pTmp = _pAnchoredObj->GetAnchorFrm();
810 [ + + ]: 953 : if( pTmp == pCurrFrm )
811 : 551 : return sal_True;
812 [ + - ][ + - ]: 402 : if( pTmp->IsTxtFrm() && ( pTmp->IsInFly() || pTmp->IsInFtn() ) )
[ - + ][ - + ]
813 : : {
814 : : // #i26945#
815 [ # # ]: 0 : Point aPos = _pAnchoredObj->GetObjRect().Pos();
816 [ # # ]: 0 : pTmp = GetVirtualUpper( pTmp, aPos );
817 : : }
818 : : // #i26945#
819 : : // #115759#
820 : : // If <pTmp> is a text frame inside a table, take the upper
821 : : // of the anchor frame, which contains the anchor position.
822 [ + - ][ - + ]: 402 : else if ( pTmp->IsTxtFrm() && pTmp->IsInTab() )
[ - + ]
823 : : {
824 : : pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj)
825 : 0 : ->GetAnchorFrmContainingAnchPos()->GetUpper();
826 : : }
827 : : // #i28701# - consider all objects in same context,
828 : : // if wrapping style is considered on object positioning.
829 : : // Thus, text will wrap around negative positioned objects.
830 : : // #i3317# - remove condition on checking,
831 : : // if wrappings style is considered on object postioning.
832 : : // Thus, text is wrapping around negative positioned objects.
833 : : // #i35640# - no consideration of negative
834 : : // positioned objects, if wrapping style isn't considered on
835 : : // object position and former text wrapping is applied.
836 : : // This condition is typically for documents imported from the
837 : : // OpenOffice.org file format.
838 : 402 : const IDocumentSettingAccess* pIDSA = pCurrFrm->GetTxtNode()->getIDocumentSettingAccess();
839 [ + + ][ + + : 1194 : if ( ( pIDSA->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) ||
+ - + + ]
840 : 390 : !pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) ) &&
841 : 402 : ::FindKontext( pTmp, 0 ) == ::FindKontext( pCurrFrm, 0 ) )
842 : : {
843 : 302 : return sal_True;
844 : : }
845 : :
846 : 100 : const SwFrm* pHeader = 0;
847 [ + - + + : 233 : if ( pCurrFrm->GetNext() != pTmp &&
+ - ][ + +
+ - + - ]
[ + + ]
848 : 100 : ( IsFrmInSameKontext( pTmp, pCurrFrm ) ||
849 : : // #i13832#, #i24135# wrap around objects in page header
850 : 27 : ( !pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) &&
851 : : 0 != ( pHeader = pTmp->FindFooterOrHeader() ) &&
852 : 3 : !pHeader->IsFooterFrm() &&
853 : 3 : pCurrFrm->IsInDocBody() ) ) )
854 : : {
855 [ + + ][ - + ]: 76 : if( pHeader || FLY_AT_FLY == rNewA.GetAnchorId() )
[ + + ]
856 : 3 : return sal_True;
857 : :
858 : : // Compare indices:
859 : : // The Index of the other is retrieved from the anchor attr.
860 : 73 : sal_uLong nTmpIndex = rNewA.GetCntntAnchor()->nNode.GetIndex();
861 : : // Now check whether the current paragraph is before the anchor
862 : : // of the displaced object in the text, then we don't have to
863 : : // get out of its way.
864 : : // If possible determine Index via SwFmtAnchor because
865 : : // otherwise it's quite expensive.
866 [ + + ]: 73 : if( ULONG_MAX == nIndex )
867 : 65 : nIndex = pCurrFrm->GetNode()->GetIndex();
868 : :
869 [ - + ]: 73 : if( nIndex >= nTmpIndex )
870 : 0 : return sal_True;
871 : : }
872 : : }
873 : : }
874 : 1962 : return sal_False;
875 : : }
876 : :
877 : : // #i68520#
878 : 2253 : SwAnchoredObjList* SwTxtFly::InitAnchoredObjList()
879 : : {
880 : : OSL_ENSURE( pCurrFrm, "InitFlyList: No Frame, no FlyList" );
881 : : // #i68520#
882 : : OSL_ENSURE( !mpAnchoredObjList, "InitFlyList: FlyList already initialized" );
883 : :
884 [ - + ][ # # ]: 2253 : SWAP_IF_SWAPPED( pCurrFrm )
[ - + ]
885 : :
886 : 2253 : const SwSortedObjs *pSorted = pPage->GetSortedObjs();
887 [ + - ]: 2253 : const sal_uInt32 nCount = pSorted ? pSorted->Count() : 0;
888 : : // --> #108724# Page header/footer content doesn't have to wrap around
889 : : // floating screen objects
890 : 2253 : const bool bFooterHeader = 0 != pCurrFrm->FindFooterOrHeader();
891 : 2253 : const IDocumentSettingAccess* pIDSA = pCurrFrm->GetTxtNode()->getIDocumentSettingAccess();
892 : : // #i40155# - check, if frame is marked not to wrap
893 : 2253 : const sal_Bool bWrapAllowed = ( pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) ||
894 [ + - ][ + + ]: 2253 : ( !pCurrFrm->IsInFtn() && !bFooterHeader ) );
[ + + ]
895 : :
896 : 2253 : bOn = sal_False;
897 : :
898 [ + - ][ + + ]: 2253 : if( nCount && bWrapAllowed )
899 : : {
900 : : // #i68520#
901 [ + - ][ + - ]: 2091 : mpAnchoredObjList = new SwAnchoredObjList();
902 : :
903 : : // #i28701# - consider complete frame area for new
904 : : // text wrapping
905 : 2091 : SwRect aRect;
906 [ + + ][ + - ]: 2091 : if ( pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) )
907 : : {
908 : 10 : aRect = pCurrFrm->Prt();
909 : 10 : aRect += pCurrFrm->Frm().Pos();
910 : : }
911 : : else
912 : : {
913 : 2081 : aRect = pCurrFrm->Frm();
914 : : }
915 : : // Make ourselves a little smaller than we are,
916 : : // so that 1-Twip-overlappings are ignored (#49532)
917 [ + - ][ - + ]: 2091 : SWRECTFN( pCurrFrm )
[ # # ][ # # ]
[ - + ]
918 [ + - ][ + - ]: 2091 : const long nRight = (aRect.*fnRect->fnGetRight)() - 1;
919 [ + - ][ + - ]: 2091 : const long nLeft = (aRect.*fnRect->fnGetLeft)() + 1;
920 [ + - ]: 2091 : const sal_Bool bR2L = pCurrFrm->IsRightToLeft();
921 : :
922 [ + - ]: 2091 : const IDocumentDrawModelAccess* pIDDMA = pCurrFrm->GetTxtNode()->getIDocumentDrawModelAccess();
923 : :
924 [ + + ]: 5863 : for( sal_uInt32 i = 0; i < nCount; i++ )
925 : : {
926 : : // #i68520#
927 : : // do not consider hidden objects
928 : : // check, if object has to be considered for text wrap
929 : : // #118809# - If requested, do not consider
930 : : // objects in page header|footer for text frames not in page
931 : : // header|footer. This is requested for the calculation of
932 : : // the base offset for objects <SwTxtFrm::CalcBaseOfstForFly()>
933 : : // #i20505# Do not consider oversized objects
934 [ + - ]: 3772 : SwAnchoredObject* pAnchoredObj = (*pSorted)[ i ];
935 [ + - ][ + - ]: 7535 : if ( !pIDDMA->IsVisibleLayerId( pAnchoredObj->GetDrawObj()->GetLayer() ) ||
[ + - ][ + + ]
[ + + ][ + + ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
936 [ + - ]: 3706 : !pAnchoredObj->ConsiderForTextWrap() ||
937 : 57 : ( mbIgnoreObjsInHeaderFooter && !bFooterHeader &&
938 [ + - ][ + - ]: 57 : pAnchoredObj->GetAnchorFrm()->FindFooterOrHeader() ) )
939 : : {
940 : 99 : continue;
941 : : }
942 : :
943 [ + - ]: 3673 : const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
944 [ + - ][ + + ]: 11101 : if ( nRight < (aBound.*fnRect->fnGetLeft)() ||
[ + + ][ + + ]
[ - + ][ + + ]
[ + - ]
945 : 6976 : (*fnRect->fnYDiff)( (aRect.*fnRect->fnGetTop)(),
946 [ + - ][ + - ]: 3488 : (aBound.*fnRect->fnGetBottom)() ) > 0 ||
[ + - ][ + - ]
[ + - ]
947 [ + - ][ + - ]: 1978 : nLeft > (aBound.*fnRect->fnGetRight)() ||
948 [ + - ][ + - ]: 1962 : (aBound.*fnRect->fnGetHeight)() >
949 [ + - ][ + - ]: 1962 : 2 * (pPage->Frm().*fnRect->fnGetHeight)() )
950 : : {
951 : 1711 : continue;
952 : : }
953 : :
954 : : // #i26945# - pass <pAnchoredObj> to method
955 : : // <GetTop(..)> instead of only the <SdrObject> instance of the
956 : : // anchored object
957 [ + - ][ + - ]: 1962 : if ( GetTop( pAnchoredObj, pCurrFrm->IsInFtn(), bFooterHeader ) )
[ + + ]
958 : : {
959 : : // OD 11.03.2003 #107862# - adjust insert position:
960 : : // overlapping objects should be sorted from left to right and
961 : : // inside left to right sorting from top to bottom.
962 : : // If objects on the same position are found, they are sorted
963 : : // on its width.
964 : : // #i68520#
965 : : {
966 : : SwAnchoredObjList::iterator aInsPosIter =
967 : : std::lower_bound( mpAnchoredObjList->begin(),
968 : : mpAnchoredObjList->end(),
969 : : pAnchoredObj,
970 [ + - ]: 1095 : AnchoredObjOrder( bR2L, fnRect ) );
971 : :
972 [ + - ]: 1095 : mpAnchoredObjList->insert( aInsPosIter, pAnchoredObj );
973 : : }
974 : :
975 [ + - ][ + - ]: 1095 : const SwFmtSurround &rFlyFmt = pAnchoredObj->GetFrmFmt().GetSurround();
976 : : // #i68520#
977 [ - + ][ # # ]: 1095 : if ( rFlyFmt.IsAnchorOnly() &&
[ - + ]
978 [ # # ][ # # ]: 0 : pAnchoredObj->GetAnchorFrm() == GetMaster() )
979 : : {
980 : : const SwFmtVertOrient &rTmpFmt =
981 [ # # ][ # # ]: 0 : pAnchoredObj->GetFrmFmt().GetVertOrient();
982 [ # # ]: 0 : if( text::VertOrientation::BOTTOM != rTmpFmt.GetVertOrient() )
983 : : nMinBottom = ( bVert && nMinBottom ) ?
984 : 0 : Min( nMinBottom, aBound.Left() ) :
985 [ # # ][ # # ]: 0 : Max( nMinBottom, (aBound.*fnRect->fnGetBottom)() );
[ # # ][ # # ]
986 : : }
987 : :
988 : 3772 : bOn = sal_True;
989 : : }
990 : : }
991 [ - + ]: 2091 : if( nMinBottom )
992 : : {
993 [ # # ][ # # ]: 0 : SwTwips nMax = (pCurrFrm->GetUpper()->*fnRect->fnGetPrtBottom)();
994 [ # # ][ # # ]: 0 : if( (*fnRect->fnYDiff)( nMinBottom, nMax ) > 0 )
995 : 0 : nMinBottom = nMax;
996 : 2091 : }
997 : : }
998 : : else
999 : : {
1000 : : // #i68520#
1001 [ + - ]: 162 : mpAnchoredObjList = new SwAnchoredObjList();
1002 : : }
1003 : :
1004 [ - + ]: 2253 : UNDO_SWAP( pCurrFrm )
1005 : :
1006 : : // #i68520#
1007 : 2253 : return mpAnchoredObjList;
1008 : : }
1009 : :
1010 : 13772 : SwTwips SwTxtFly::CalcMinBottom() const
1011 : : {
1012 : 13772 : SwTwips nRet = 0;
1013 : 13772 : const SwCntntFrm *pLclMaster = GetMaster();
1014 : : OSL_ENSURE(pLclMaster, "SwTxtFly without master");
1015 [ + - ]: 13772 : const SwSortedObjs *pDrawObj = pLclMaster ? pLclMaster->GetDrawObjs() : NULL;
1016 [ + + ]: 13772 : const sal_uInt32 nCount = pDrawObj ? pDrawObj->Count() : 0;
1017 [ + + ]: 13772 : if( nCount )
1018 : : {
1019 : 878 : SwTwips nEndOfFrm = pCurrFrm->Frm().Bottom();
1020 [ + + ]: 2084 : for( sal_uInt32 i = 0; i < nCount; i++ )
1021 : : {
1022 : 1206 : SwAnchoredObject* pAnchoredObj = (*pDrawObj)[ i ];
1023 : 1206 : const SwFmtSurround &rFlyFmt = pAnchoredObj->GetFrmFmt().GetSurround();
1024 [ - + ]: 1206 : if( rFlyFmt.IsAnchorOnly() )
1025 : : {
1026 : : const SwFmtVertOrient &rTmpFmt =
1027 : 0 : pAnchoredObj->GetFrmFmt().GetVertOrient();
1028 [ # # ]: 0 : if( text::VertOrientation::BOTTOM != rTmpFmt.GetVertOrient() )
1029 : : {
1030 [ # # ]: 0 : const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
1031 [ # # ]: 0 : if( aBound.Top() < nEndOfFrm )
1032 : 0 : nRet = Max( nRet, aBound.Bottom() );
1033 : : }
1034 : : }
1035 : : }
1036 : 878 : SwTwips nMax = pCurrFrm->GetUpper()->Frm().Top() +
1037 : 878 : pCurrFrm->GetUpper()->Prt().Bottom();
1038 [ - + ]: 878 : if( nRet > nMax )
1039 : 0 : nRet = nMax;
1040 : : }
1041 : 13772 : return nRet;
1042 : : }
1043 : :
1044 : :
1045 : 4446 : sal_Bool SwTxtFly::ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const
1046 : : {
1047 [ - + ][ # # ]: 4446 : SWAP_IF_SWAPPED( pCurrFrm )
[ - + ]
1048 : :
1049 : 4446 : sal_Bool bRet = sal_False;
1050 : : // #i68520#
1051 [ + - ]: 4446 : SwAnchoredObjList::size_type nCount( bOn ? GetAnchoredObjList()->size() : 0 );
1052 [ + + ][ + - ]: 4446 : if ( bOn && nCount > 0 )
1053 : : {
1054 [ + + ]: 4595 : for( SwAnchoredObjList::size_type i = 0; i < nCount; ++i )
1055 : : {
1056 : : // #i68520#
1057 [ + - ]: 3646 : const SwAnchoredObject* pAnchoredObj = (*mpAnchoredObjList)[i];
1058 : :
1059 [ + - ]: 3646 : SwRect aRect( pAnchoredObj->GetObjRectWithSpaces() );
1060 : :
1061 : : // Optimierung
1062 [ - + ][ # # ]: 3646 : SWRECTFN( pCurrFrm )
[ # # ][ - + ]
[ + - ]
1063 [ + - ][ + - ]: 3646 : if( (aRect.*fnRect->fnGetLeft)() > (rRect.*fnRect->fnGetRight)() )
[ + - ][ + - ]
[ + + ]
1064 : : break;
1065 : : // #i68520#
1066 [ + - ][ + - ]: 3139 : if ( mpCurrAnchoredObj != pAnchoredObj && aRect.IsOver( rRect ) )
[ + + ][ + + ]
1067 : : {
1068 : : // #i68520#
1069 [ + - ]: 1880 : const SwFmt* pFmt( &(pAnchoredObj->GetFrmFmt()) );
1070 [ + - ]: 1880 : const SwFmtSurround &rSur = pFmt->GetSurround();
1071 [ + + ]: 1880 : if( bAvoid )
1072 : : {
1073 : : // If the text flows below, it has no influence on
1074 : : // formatting. In LineIter::DrawText() it is "just"
1075 : : // necessary to clevely set the ClippingRegions
1076 [ + - ]: 1581 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
1077 [ + + - + ]: 3162 : if( ( SURROUND_THROUGHT == rSur.GetSurround() &&
[ # # # #
# # - + ]
[ + + ]
1078 : 303 : ( !rSur.IsAnchorOnly() ||
1079 : : // #i68520#
1080 [ # # ][ # # ]: 0 : GetMaster() == pAnchoredObj->GetAnchorFrm() ||
1081 : 0 : ((FLY_AT_PARA != rAnchor.GetAnchorId()) &&
1082 : 0 : (FLY_AT_CHAR != rAnchor.GetAnchorId())) ) )
1083 : 1278 : || aRect.Top() == FAR_AWAY )
1084 : 303 : continue;
1085 : : }
1086 : :
1087 : : // #i58642#
1088 : : // Compare <GetMaster()> instead of <pCurrFrm> with the anchor
1089 : : // frame of the anchored object, because a follow frame have
1090 : : // to ignore the anchored objects of its master frame.
1091 : : // Note: Anchored objects are always registered at the master
1092 : : // frame, exception are as-character anchored objects,
1093 : : // but these aren't handled here.
1094 : : // #i68520#
1095 [ - + ][ # # ]: 1577 : if ( mbIgnoreCurrentFrame &&
[ - + ]
1096 [ # # ][ # # ]: 0 : GetMaster() == pAnchoredObj->GetAnchorFrm() )
1097 : 0 : continue;
1098 : :
1099 [ + + ]: 1577 : if( pRect )
1100 : : {
1101 : : // #i68520#
1102 [ + - ]: 1278 : SwRect aFly = AnchoredObjToRect( pAnchoredObj, rRect );
1103 [ + - ][ + - ]: 1278 : if( aFly.IsEmpty() || !aFly.IsOver( rRect ) )
[ - + ][ - + ]
1104 : 0 : continue;
1105 [ + + ][ + - ]: 1422 : if( !bRet || (
[ + - ][ - + ]
[ # # ][ + + ]
1106 [ + - ]: 48 : ( !pCurrFrm->IsRightToLeft() &&
1107 [ + - ][ + - ]: 48 : ( (aFly.*fnRect->fnGetLeft)() <
1108 [ + - ][ + - ]: 48 : (pRect->*fnRect->fnGetLeft)() ) ) ||
1109 [ + - ]: 48 : ( pCurrFrm->IsRightToLeft() &&
1110 [ # # ][ # # ]: 0 : ( (aFly.*fnRect->fnGetRight)() >
1111 [ # # ][ # # ]: 0 : (pRect->*fnRect->fnGetRight)() ) ) ) )
1112 : 1230 : *pRect = aFly;
1113 [ + + ]: 1278 : if( rSur.IsContour() )
1114 : : {
1115 : 48 : bRet = sal_True;
1116 : 1278 : continue;
1117 : : }
1118 : : }
1119 : 3646 : bRet = sal_True;
1120 : : break;
1121 : : }
1122 : : }
1123 : : }
1124 : :
1125 [ - + ]: 4446 : UNDO_SWAP( pCurrFrm )
1126 : :
1127 : 4446 : return bRet;
1128 : : }
1129 : :
1130 : :
1131 : : // #i68520#
1132 : 1278 : SwAnchoredObjList::size_type SwTxtFly::GetPos( const SwAnchoredObject* pAnchoredObj ) const
1133 : : {
1134 : 1278 : SwAnchoredObjList::size_type nCount = GetAnchoredObjList()->size();
1135 : 1278 : SwAnchoredObjList::size_type nRet = 0;
1136 [ + - ][ + + ]: 1534 : while ( nRet < nCount && pAnchoredObj != (*mpAnchoredObjList)[ nRet ] )
[ + + ]
1137 : 256 : ++nRet;
1138 : 1278 : return nRet;
1139 : : }
1140 : :
1141 : : // #i68520#
1142 : 596 : void SwTxtFly::CalcRightMargin( SwRect &rFly,
1143 : : SwAnchoredObjList::size_type nFlyPos,
1144 : : const SwRect &rLine ) const
1145 : : {
1146 : : // Usually the right margin is the right margin of the Printarea
1147 : : OSL_ENSURE( ! pCurrFrm->IsVertical() || ! pCurrFrm->IsSwapped(),
1148 : : "SwTxtFly::CalcRightMargin with swapped frame" );
1149 [ + - ][ - + ]: 596 : SWRECTFN( pCurrFrm )
[ # # ][ # # ]
[ - + ]
1150 : : // #118796# - correct determination of right of printing area
1151 [ + - ][ + - ]: 596 : SwTwips nRight = (pCurrFrm->*fnRect->fnGetPrtRight)();
1152 [ + - ][ + - ]: 596 : SwTwips nFlyRight = (rFly.*fnRect->fnGetRight)();
1153 : 596 : SwRect aLine( rLine );
1154 [ + - ][ + - ]: 596 : (aLine.*fnRect->fnSetRight)( nRight );
1155 [ + - ][ + - ]: 596 : (aLine.*fnRect->fnSetLeft)( (rFly.*fnRect->fnGetLeft)() );
[ + - ][ + - ]
1156 : :
1157 : : // It is possible that there is another object that is _above_ us
1158 : : // and protrudes into the same line.
1159 : : // Flys with run-through are invisible for those below, i.e., they
1160 : : // are ignored for computing the margins of other Flys.
1161 : : // 3301: pNext->Frm().IsOver( rLine ) is necessary
1162 : : // #i68520#
1163 : : SwSurround eSurroundForTextWrap;
1164 : :
1165 : 596 : sal_Bool bStop = sal_False;
1166 : : // #i68520#
1167 : 596 : SwAnchoredObjList::size_type nPos = 0;
1168 : :
1169 : : // #i68520#
1170 [ + + ][ + - ]: 1276 : while( nPos < mpAnchoredObjList->size() && !bStop )
[ + + ]
1171 : : {
1172 [ + + ]: 680 : if( nPos == nFlyPos )
1173 : : {
1174 : 596 : ++nPos;
1175 : 596 : continue;
1176 : : }
1177 : : // #i68520#
1178 [ + - ]: 84 : const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nPos++ ];
1179 [ - + ]: 84 : if ( pNext == mpCurrAnchoredObj )
1180 : 0 : continue;
1181 [ + - ]: 84 : eSurroundForTextWrap = _GetSurroundForTextWrap( pNext );
1182 [ - + ]: 84 : if( SURROUND_THROUGHT == eSurroundForTextWrap )
1183 : 0 : continue;
1184 : :
1185 : : const SwRect aTmp( SwContourCache::CalcBoundRect
1186 [ + - ]: 84 : ( pNext, aLine, pCurrFrm, nFlyRight, sal_True ) );
1187 [ + - ][ + - ]: 84 : SwTwips nTmpRight = (aTmp.*fnRect->fnGetRight)();
1188 : :
1189 : : // optimization:
1190 : : // Record in nNextTop at which Y-position frame related changes are
1191 : : // likely. This is so that, despite only looking at frames in the
1192 : : // current line height, for frames without wrap the line height is
1193 : : // incremented so that with a single line the lower border of the frame
1194 : : // (or possibly the upper border of another frame) is reached.
1195 : : // Especially in HTML documents there are often (dummy) paragraphs in
1196 : : // 2 pt font, and they used to only evade big frames after huge numbers
1197 : : // of empty lines.
1198 [ + - ][ + - ]: 84 : const long nTmpTop = (aTmp.*fnRect->fnGetTop)();
1199 [ + - ][ + - ]: 84 : if( (*fnRect->fnYDiff)( nTmpTop, (aLine.*fnRect->fnGetTop)() ) > 0 )
[ + - ][ - + ]
1200 : : {
1201 [ # # ][ # # ]: 0 : if( (*fnRect->fnYDiff)( nNextTop, nTmpTop ) > 0 )
1202 : 0 : SetNextTop( nTmpTop ); // upper border of next frame
1203 : : }
1204 [ + - ][ + - ]: 84 : else if (!(aTmp.*fnRect->fnGetWidth)()) // typical for Objects with contour wrap
[ - + ]
1205 : : { // For Objects with contour wrap that start before the current
1206 : : // line, and end below it, but do not actually overlap it, the
1207 : : // optimization has to be disabled, because the circumstances
1208 : : // can change in the next line.
1209 [ # # ][ # # ]: 0 : if( ! (aTmp.*fnRect->fnGetHeight)() ||
[ # # ][ # # ]
[ # # ]
1210 : 0 : (*fnRect->fnYDiff)( (aTmp.*fnRect->fnGetBottom)(),
1211 [ # # ][ # # ]: 0 : (aLine.*fnRect->fnGetTop)() ) > 0 )
[ # # ][ # # ]
[ # # ]
1212 : 0 : SetNextTop( 0 );
1213 : : }
1214 [ + - ][ + - ]: 84 : if( aTmp.IsOver( aLine ) && nTmpRight > nFlyRight )
[ - + ][ - + ]
1215 : : {
1216 : 0 : nFlyRight = nTmpRight;
1217 [ # # ][ # # ]: 0 : if( SURROUND_RIGHT == eSurroundForTextWrap ||
1218 : : SURROUND_PARALLEL == eSurroundForTextWrap )
1219 : : {
1220 : : // overrule the FlyFrm
1221 [ # # ]: 0 : if( nRight > nFlyRight )
1222 : 0 : nRight = nFlyRight;
1223 : 680 : bStop = sal_True;
1224 : : }
1225 : : }
1226 : : }
1227 [ + - ][ + - ]: 596 : (rFly.*fnRect->fnSetRight)( nRight );
1228 : 596 : }
1229 : :
1230 : : // #i68520#
1231 : 72 : void SwTxtFly::CalcLeftMargin( SwRect &rFly,
1232 : : SwAnchoredObjList::size_type nFlyPos,
1233 : : const SwRect &rLine ) const
1234 : : {
1235 : : OSL_ENSURE( ! pCurrFrm->IsVertical() || ! pCurrFrm->IsSwapped(),
1236 : : "SwTxtFly::CalcLeftMargin with swapped frame" );
1237 [ + - ][ - + ]: 72 : SWRECTFN( pCurrFrm )
[ # # ][ # # ]
[ - + ]
1238 : : // #118796# - correct determination of left of printing area
1239 [ + - ][ + - ]: 72 : SwTwips nLeft = (pCurrFrm->*fnRect->fnGetPrtLeft)();
1240 [ + - ][ + - ]: 72 : const SwTwips nFlyLeft = (rFly.*fnRect->fnGetLeft)();
1241 : :
1242 [ + + ]: 72 : if( nLeft > nFlyLeft )
1243 : 30 : nLeft = rFly.Left();
1244 : :
1245 : 72 : SwRect aLine( rLine );
1246 [ + - ][ + - ]: 72 : (aLine.*fnRect->fnSetLeft)( nLeft );
1247 : :
1248 : : // It is possible that there is another object that is _above_ us
1249 : : // and protrudes into the same line.
1250 : : // Flys with run-through are invisible for those below, i.e., they
1251 : : // are ignored for computing the margins of other Flys.
1252 : : // 3301: pNext->Frm().IsOver( rLine ) is necessary
1253 : :
1254 : : // #i68520#
1255 : 72 : SwAnchoredObjList::size_type nMyPos = nFlyPos;
1256 [ + + ]: 72 : while( ++nFlyPos < mpAnchoredObjList->size() )
1257 : : {
1258 : : // #i68520#
1259 [ + - ]: 21 : const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nFlyPos ];
1260 [ + - ]: 21 : const SwRect aTmp( pNext->GetObjRectWithSpaces() );
1261 [ + - ][ - + ]: 21 : if( (aTmp.*fnRect->fnGetLeft)() >= nFlyLeft )
[ + - ]
1262 : : break;
1263 : : }
1264 : :
1265 [ + + ]: 144 : while( nFlyPos )
1266 : : {
1267 [ + + ]: 75 : if( --nFlyPos == nMyPos )
1268 : 72 : continue;
1269 : : // #i68520#
1270 [ + - ]: 3 : const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nFlyPos ];
1271 [ - + ]: 3 : if( pNext == mpCurrAnchoredObj )
1272 : 0 : continue;
1273 [ + - ]: 3 : SwSurround eSurroundForTextWrap = _GetSurroundForTextWrap( pNext );
1274 [ - + ]: 3 : if( SURROUND_THROUGHT == eSurroundForTextWrap )
1275 : 0 : continue;
1276 : :
1277 : : const SwRect aTmp( SwContourCache::CalcBoundRect
1278 [ + - ]: 3 : ( pNext, aLine, pCurrFrm, nFlyLeft, sal_False ) );
1279 : :
1280 [ + - ][ + - ]: 3 : if( (aTmp.*fnRect->fnGetLeft)() < nFlyLeft && aTmp.IsOver( aLine ) )
[ + - ][ + - ]
[ + - ][ + - ]
1281 : : {
1282 : : // #118796# - no '+1', because <..fnGetRight>
1283 : : // returns the correct value.
1284 [ + - ][ + - ]: 3 : SwTwips nTmpRight = (aTmp.*fnRect->fnGetRight)();
1285 [ + - ]: 3 : if ( nLeft <= nTmpRight )
1286 : 75 : nLeft = nTmpRight;
1287 : :
1288 : : break;
1289 : : }
1290 : : }
1291 [ + - ][ + - ]: 72 : (rFly.*fnRect->fnSetLeft)( nLeft );
1292 : 72 : }
1293 : :
1294 : : // #i68520#
1295 : 1278 : SwRect SwTxtFly::AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj,
1296 : : const SwRect &rLine ) const
1297 : : {
1298 [ - + ][ # # ]: 1278 : SWRECTFN( pCurrFrm )
[ # # ][ - + ]
1299 : :
1300 : 1278 : const long nXPos = pCurrFrm->IsRightToLeft() ?
1301 : : rLine.Right() :
1302 [ + - ][ - + ]: 1278 : (rLine.*fnRect->fnGetLeft)();
1303 : :
1304 : : SwRect aFly = mbIgnoreContour ?
1305 : 0 : pAnchoredObj->GetObjRectWithSpaces() :
1306 : : SwContourCache::CalcBoundRect( pAnchoredObj, rLine, pCurrFrm,
1307 [ - + ]: 1278 : nXPos, ! pCurrFrm->IsRightToLeft() );
1308 : :
1309 [ - + ]: 1278 : if( !aFly.Width() )
1310 : 0 : return aFly;
1311 : :
1312 : : // so the line may grow up to the lower edge of the frame
1313 [ + - ]: 1278 : SetNextTop( (aFly.*fnRect->fnGetBottom)() );
1314 : 1278 : SwAnchoredObjList::size_type nFlyPos = GetPos( pAnchoredObj );
1315 : :
1316 : : // LEFT and RIGHT, we grow the rectangle.
1317 : : // We have some problems, when several frames are to be seen.
1318 : : // At the moment, only the easier case is assumed:
1319 : : // + LEFT means that the text must flow on the left of the frame,
1320 : : // that is the frame expands to the right edge of the print area
1321 : : // or to the next frame.
1322 : : // + RIGHT is the opposite.
1323 : : // Otherwise the set distance between text and frame is always
1324 : : // added up.
1325 [ + + + + ]: 1278 : switch( _GetSurroundForTextWrap( pAnchoredObj ) )
1326 : : {
1327 : : case SURROUND_LEFT :
1328 : : {
1329 : 554 : CalcRightMargin( aFly, nFlyPos, rLine );
1330 : 554 : break;
1331 : : }
1332 : : case SURROUND_RIGHT :
1333 : : {
1334 : 30 : CalcLeftMargin( aFly, nFlyPos, rLine );
1335 : 30 : break;
1336 : : }
1337 : : case SURROUND_NONE :
1338 : : {
1339 : 42 : CalcRightMargin( aFly, nFlyPos, rLine );
1340 : 42 : CalcLeftMargin( aFly, nFlyPos, rLine );
1341 : 42 : break;
1342 : : }
1343 : : default:
1344 : 652 : break;
1345 : : }
1346 : 1278 : return aFly;
1347 : : }
1348 : :
1349 : : // #i68520#
1350 : :
1351 : : // Wrap only on sides with at least 2cm space for the text
1352 : : #define TEXT_MIN 1134
1353 : :
1354 : : // Wrap on both sides up to a frame width of 1.5cm
1355 : : #define FRAME_MAX 850
1356 : :
1357 : 1365 : SwSurround SwTxtFly::_GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const
1358 : : {
1359 : 1365 : const SwFrmFmt* pFmt = &(pAnchoredObj->GetFrmFmt());
1360 : 1365 : const SwFmtSurround &rFlyFmt = pFmt->GetSurround();
1361 : 1365 : SwSurround eSurroundForTextWrap = rFlyFmt.GetSurround();
1362 : :
1363 [ # # ][ - + ]: 1365 : if( rFlyFmt.IsAnchorOnly() && pAnchoredObj->GetAnchorFrm() != GetMaster() )
[ - + ]
1364 : : {
1365 : 0 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
1366 [ # # ]: 0 : if ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
[ # # # # ]
1367 : 0 : (FLY_AT_CHAR == rAnchor.GetAnchorId()))
1368 : : {
1369 : 0 : return SURROUND_NONE;
1370 : : }
1371 : : }
1372 : :
1373 : : // in cause of run-through and nowrap ignore smartly
1374 [ + - ][ + + ]: 1365 : if( SURROUND_THROUGHT == eSurroundForTextWrap ||
1375 : : SURROUND_NONE == eSurroundForTextWrap )
1376 : 12 : return eSurroundForTextWrap;
1377 : :
1378 : : // left is left and right is right
1379 [ - + ]: 1353 : if ( pCurrFrm->IsRightToLeft() )
1380 : : {
1381 [ # # ]: 0 : if ( SURROUND_LEFT == eSurroundForTextWrap )
1382 : 0 : eSurroundForTextWrap = SURROUND_RIGHT;
1383 [ # # ]: 0 : else if ( SURROUND_RIGHT == eSurroundForTextWrap )
1384 : 0 : eSurroundForTextWrap = SURROUND_LEFT;
1385 : : }
1386 : :
1387 : : // "ideal page wrap":
1388 [ + + ]: 1353 : if ( SURROUND_IDEAL == eSurroundForTextWrap )
1389 : : {
1390 [ + - ][ - + ]: 680 : SWRECTFN( pCurrFrm )
[ # # ][ # # ]
[ - + ]
1391 [ + - ][ + - ]: 680 : const long nCurrLeft = (pCurrFrm->*fnRect->fnGetPrtLeft)();
1392 [ + - ][ + - ]: 680 : const long nCurrRight = (pCurrFrm->*fnRect->fnGetPrtRight)();
1393 [ + - ]: 680 : const SwRect aRect( pAnchoredObj->GetObjRectWithSpaces() );
1394 [ + - ][ + - ]: 680 : long nFlyLeft = (aRect.*fnRect->fnGetLeft)();
1395 [ + - ][ + - ]: 680 : long nFlyRight = (aRect.*fnRect->fnGetRight)();
1396 : :
1397 [ + - ][ - + ]: 680 : if ( nFlyRight < nCurrLeft || nFlyLeft > nCurrRight )
1398 : 0 : eSurroundForTextWrap = SURROUND_PARALLEL;
1399 : : else
1400 : : {
1401 : 680 : long nLeft = nFlyLeft - nCurrLeft;
1402 : 680 : long nRight = nCurrRight - nFlyRight;
1403 [ + + ]: 680 : if( nFlyRight - nFlyLeft > FRAME_MAX )
1404 : : {
1405 [ - + ]: 584 : if( nLeft < nRight )
1406 : 0 : nLeft = 0;
1407 : : else
1408 : 584 : nRight = 0;
1409 : : }
1410 [ + + ]: 680 : if( nLeft < TEXT_MIN )
1411 : 63 : nLeft = 0;
1412 [ + + ]: 680 : if( nRight < TEXT_MIN )
1413 : 584 : nRight = 0;
1414 [ + + ]: 680 : if( nLeft )
1415 [ + + ]: 617 : eSurroundForTextWrap = nRight ? SURROUND_PARALLEL : SURROUND_LEFT;
1416 : : else
1417 [ + + ]: 680 : eSurroundForTextWrap = nRight ? SURROUND_RIGHT: SURROUND_NONE;
1418 : : }
1419 : : }
1420 : :
1421 : 1365 : return eSurroundForTextWrap;
1422 : : }
1423 : :
1424 : 0 : sal_Bool SwTxtFly::IsAnyFrm( const SwRect &rLine ) const
1425 : : {
1426 : :
1427 [ # # ][ # # ]: 0 : SWAP_IF_SWAPPED( pCurrFrm )
[ # # ]
1428 : :
1429 : : OSL_ENSURE( bOn, "IsAnyFrm: Why?" );
1430 : :
1431 : 0 : const sal_Bool bRet = ForEach( rLine, NULL, sal_False );
1432 [ # # ]: 0 : UNDO_SWAP( pCurrFrm )
1433 : 0 : return bRet;
1434 : : }
1435 : :
1436 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|