LibreOffice Module sw (master)  1
txtfly.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <vcl/outdev.hxx>
21 
22 #include <pagefrm.hxx>
23 #include <rootfrm.hxx>
24 #include <pam.hxx>
25 #include <swfont.hxx>
26 #include <swregion.hxx>
27 #include <dflyobj.hxx>
28 #include <drawfont.hxx>
29 #include <flyfrm.hxx>
30 #include <flyfrms.hxx>
31 #include <fmtornt.hxx>
32 #include <frmatr.hxx>
33 #include <frmtool.hxx>
34 #include <ndtxt.hxx>
35 #include <txtfly.hxx>
36 #include "txtpaint.hxx"
37 #include <notxtfrm.hxx>
38 #include <fmtcnct.hxx>
39 #include <svx/obj3d.hxx>
40 #include <editeng/txtrange.hxx>
41 #include <editeng/lrspitem.hxx>
42 #include <editeng/ulspitem.hxx>
43 #include <fmtsrnd.hxx>
44 #include <fmtanchr.hxx>
45 #include <frmfmt.hxx>
46 #include <pagedesc.hxx>
47 #include <sortedobjs.hxx>
50 #include <svx/svdoedge.hxx>
51 
52 #ifdef DBG_UTIL
53 #include <viewsh.hxx>
54 #include <doc.hxx>
55 #endif
56 
57 using namespace ::com::sun::star;
58 
59 namespace
60 {
61  // #i68520#
62  struct AnchoredObjOrder
63  {
64  bool mbR2L;
65  SwRectFn mfnRect;
66 
67  AnchoredObjOrder( const bool bR2L,
68  SwRectFn fnRect )
69  : mbR2L( bR2L ),
70  mfnRect( fnRect )
71  {}
72 
73  bool operator()( const SwAnchoredObject* pListedAnchoredObj,
74  const SwAnchoredObject* pNewAnchoredObj )
75  {
76  const SwRect& aBoundRectOfListedObj( pListedAnchoredObj->GetObjRectWithSpaces() );
77  const SwRect& aBoundRectOfNewObj( pNewAnchoredObj->GetObjRectWithSpaces() );
78  if ( ( mbR2L &&
79  ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ==
80  (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
81  ( !mbR2L &&
82  ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ==
83  (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
84  {
85  SwTwips nTopDiff =
86  (*mfnRect->fnYDiff)( (aBoundRectOfNewObj.*mfnRect->fnGetTop)(),
87  (aBoundRectOfListedObj.*mfnRect->fnGetTop)() );
88  if ( nTopDiff == 0 &&
89  ( ( mbR2L &&
90  ( (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() >
91  (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ) ) ||
92  ( !mbR2L &&
93  ( (aBoundRectOfNewObj.*mfnRect->fnGetRight)() <
94  (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ) ) ) )
95  {
96  return true;
97  }
98  else if ( nTopDiff > 0 )
99  {
100  return true;
101  }
102  }
103  else if ( ( mbR2L &&
104  ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() >
105  (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
106  ( !mbR2L &&
107  ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() <
108  (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
109  {
110  return true;
111  }
112 
113  return false;
114  }
115  };
116 }
117 
119  mnPointCount( 0 )
120 {
121 }
122 
124 {
125 }
126 
127 void SwContourCache::ClrObject( sal_uInt16 nPos )
128 {
129  mnPointCount -= mvItems[ nPos ].mxTextRanger->GetPointCount();
130  mvItems.erase(mvItems.begin() + nPos);
131 }
132 
133 void ClrContourCache( const SdrObject *pObj )
134 {
135  if( pContourCache && pObj )
136  for( sal_uInt16 i = 0; i < pContourCache->GetCount(); ++i )
137  if( pObj == pContourCache->GetObject( i ) )
138  {
140  break;
141  }
142 }
143 
145 {
146  if( pContourCache )
147  {
148  pContourCache->mvItems.clear();
150  }
151 }
152 
153 // #i68520#
155  const SwRect &rLine,
156  const SwTextFrame* pFrame,
157  const long nXPos,
158  const bool bRight )
159 {
160  SwRect aRet;
161  const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat());
162  bool bHandleContour(pFormat->GetSurround().IsContour());
163 
164  if(!bHandleContour)
165  {
166  // RotateFlyFrame3: Object has no set contour, but for rotated
167  // FlyFrames we can create a 'default' contour to make text
168  // flow around the free, non-covered
169  const SwFlyFreeFrame* pSwFlyFreeFrame(dynamic_cast< const SwFlyFreeFrame* >(pAnchoredObj));
170 
171  if(nullptr != pSwFlyFreeFrame && pSwFlyFreeFrame->supportsAutoContour())
172  {
173  bHandleContour = true;
174  }
175  }
176 
177  if( bHandleContour &&
178  ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) == nullptr ||
179  ( static_cast<const SwFlyFrame*>(pAnchoredObj)->Lower() &&
180  static_cast<const SwFlyFrame*>(pAnchoredObj)->Lower()->IsNoTextFrame() ) ) )
181  {
182  aRet = pAnchoredObj->GetObjRectWithSpaces();
183  if( aRet.IsOver( rLine ) )
184  {
185  if( !pContourCache )
187 
188  aRet = pContourCache->ContourRect(
189  pFormat, pAnchoredObj->GetDrawObj(), pFrame, rLine, nXPos, bRight );
190  }
191  else
192  aRet.Width( 0 );
193  }
194  else
195  {
196  aRet = pAnchoredObj->GetObjRectWithSpaces();
197  }
198 
199  return aRet;
200 }
201 
203  const SdrObject* pObj, const SwTextFrame* pFrame, const SwRect &rLine,
204  const long nXPos, const bool bRight )
205 {
206  SwRect aRet;
207  sal_uInt16 nPos = 0; // Search in the Cache
208  while( nPos < GetCount() && pObj != mvItems[ nPos ].mpSdrObj )
209  ++nPos;
210  if( GetCount() == nPos ) // Not found
211  {
212  if( GetCount() == POLY_CNT )
213  {
214  mnPointCount -= mvItems.back().mxTextRanger->GetPointCount();
215  mvItems.pop_back();
216  }
217  ::basegfx::B2DPolyPolygon aPolyPolygon;
218  std::unique_ptr<::basegfx::B2DPolyPolygon> pPolyPolygon;
219 
220  if ( auto pVirtFlyDrawObj = dynamic_cast< const SwVirtFlyDrawObj *>( pObj ) )
221  {
222  // GetContour() causes the graphic to be loaded, which may cause
223  // the graphic to change its size, call ClrObject()
224  tools::PolyPolygon aPoly;
225  if( !pVirtFlyDrawObj->GetFlyFrame()->GetContour( aPoly ) )
226  aPoly = tools::PolyPolygon( static_cast<const SwVirtFlyDrawObj*>(pObj)->
227  GetFlyFrame()->getFrameArea().SVRect() );
228  aPolyPolygon.clear();
229  aPolyPolygon.append(aPoly.getB2DPolyPolygon());
230  }
231  else
232  {
233  if( dynamic_cast< const E3dObject *>( pObj ) == nullptr )
234  {
235  aPolyPolygon = pObj->TakeXorPoly();
236  }
237 
238  ::basegfx::B2DPolyPolygon aContourPoly(pObj->TakeContour());
239  pPolyPolygon.reset(new ::basegfx::B2DPolyPolygon(aContourPoly));
240  }
241  const SvxLRSpaceItem &rLRSpace = pFormat->GetLRSpace();
242  const SvxULSpaceItem &rULSpace = pFormat->GetULSpace();
243  CacheItem item {
244  pObj, // due to #37347 the Object must be entered only after GetContour()
245  std::make_unique<TextRanger>( aPolyPolygon, pPolyPolygon.get(), 20,
246  static_cast<sal_uInt16>(rLRSpace.GetLeft()), static_cast<sal_uInt16>(rLRSpace.GetRight()),
247  pFormat->GetSurround().IsOutside(), false, pFrame->IsVertical() )
248  };
249  mvItems.insert(mvItems.begin(), std::move(item));
250  mvItems[0].mxTextRanger->SetUpper( rULSpace.GetUpper() );
251  mvItems[0].mxTextRanger->SetLower( rULSpace.GetLower() );
252 
253  pPolyPolygon.reset();
254 
255  mnPointCount += mvItems[0].mxTextRanger->GetPointCount();
256  while( mnPointCount > POLY_MAX && mvItems.size() > POLY_MIN )
257  {
258  mnPointCount -= mvItems.back().mxTextRanger->GetPointCount();
259  mvItems.pop_back();
260  }
261  }
262  else if( nPos )
263  {
264  CacheItem item = std::move(mvItems[nPos]);
265  mvItems.erase(mvItems.begin() + nPos);
266  mvItems.insert(mvItems.begin(), std::move(item));
267  }
268  SwRectFnSet aRectFnSet(pFrame);
269  long nTmpTop = aRectFnSet.GetTop(rLine);
270  // fnGetBottom is top + height
271  long nTmpBottom = aRectFnSet.GetBottom(rLine);
272 
273  Range aRange( std::min( nTmpTop, nTmpBottom ), std::max( nTmpTop, nTmpBottom ) );
274 
275  std::deque<long>* pTmp = mvItems[0].mxTextRanger->GetTextRanges( aRange );
276 
277  const size_t nCount = pTmp->size();
278  if( 0 != nCount )
279  {
280  size_t nIdx = 0;
281  while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos )
282  ++nIdx;
283  bool bOdd = nIdx % 2;
284  bool bSet = true;
285  if( bOdd )
286  --nIdx; // within interval
287  else if( ! bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) )
288  {
289  if( nIdx )
290  nIdx -= 2; // an interval to the left
291  else
292  bSet = false; // before the first interval
293  }
294 
295  if( bSet && nIdx < nCount )
296  {
297  aRectFnSet.SetTopAndHeight( aRet, aRectFnSet.GetTop(rLine),
298  aRectFnSet.GetHeight(rLine) );
299  aRectFnSet.SetLeft( aRet, (*pTmp)[ nIdx ] );
300  aRectFnSet.SetRight( aRet, (*pTmp)[ nIdx + 1 ] + 1 );
301  }
302  }
303  return aRet;
304 }
305 
307  : m_pPage(nullptr)
308  , mpCurrAnchoredObj(nullptr)
309  , m_pCurrFrame(nullptr)
310  , m_pMaster(nullptr)
311  , m_nMinBottom(0)
312  , m_nNextTop(0)
313  , m_nCurrFrameNodeIndex(0)
314  , m_bOn(false)
315  , m_bTopRule(false)
316  , mbIgnoreCurrentFrame(false)
317  , mbIgnoreContour(false)
318  , mbIgnoreObjsInHeaderFooter(false)
319 
320 {
321 }
322 
324 {
325  CtorInitTextFly( pFrame );
326 }
327 
328 SwTextFly::SwTextFly( const SwTextFly& rTextFly )
329 {
330  m_pPage = rTextFly.m_pPage;
332  m_pCurrFrame = rTextFly.m_pCurrFrame;
333  m_pMaster = rTextFly.m_pMaster;
334  if( rTextFly.mpAnchoredObjList )
335  {
336  mpAnchoredObjList.reset( new SwAnchoredObjList( *(rTextFly.mpAnchoredObjList) ) );
337  }
338 
339  m_bOn = rTextFly.m_bOn;
340  m_bTopRule = rTextFly.m_bTopRule;
341  m_nMinBottom = rTextFly.m_nMinBottom;
342  m_nNextTop = rTextFly.m_nNextTop;
345  mbIgnoreContour = rTextFly.mbIgnoreContour;
347 }
348 
350 {
351 }
352 
354 {
355  mbIgnoreCurrentFrame = false;
356  mbIgnoreContour = false;
358  m_pPage = pFrame->FindPageFrame();
359  const SwFlyFrame* pTmp = pFrame->FindFlyFrame();
360  // #i68520#
361  mpCurrAnchoredObj = pTmp;
362  m_pCurrFrame = pFrame;
363  m_pMaster = m_pCurrFrame->IsFollow() ? nullptr : m_pCurrFrame;
364  // If we're not overlapped by a frame or if a FlyCollection does not exist
365  // at all, we switch off forever.
366  // It could be, however, that a line is added while formatting, that
367  // extends into a frame.
368  // That's why we do not optimize for: bOn = pSortedFlys && IsAnyFrame();
369  m_bOn = m_pPage->GetSortedObjs() != nullptr;
370  m_bTopRule = true;
371  m_nMinBottom = 0;
372  m_nNextTop = 0;
373  m_nCurrFrameNodeIndex = ULONG_MAX;
374 }
375 
376 SwRect SwTextFly::GetFrame_( const SwRect &rRect ) const
377 {
378  SwRect aRet;
379  if( ForEach( rRect, &aRet, true ) )
380  {
381  SwRectFnSet aRectFnSet(m_pCurrFrame);
382  aRectFnSet.SetTop( aRet, aRectFnSet.GetTop(rRect) );
383 
384  // Do not always adapt the bottom
385  const SwTwips nRetBottom = aRectFnSet.GetBottom(aRet);
386  const SwTwips nRectBottom = aRectFnSet.GetBottom(rRect);
387  if ( aRectFnSet.YDiff( nRetBottom, nRectBottom ) > 0 ||
388  aRectFnSet.GetHeight(aRet) < 0 )
389  aRectFnSet.SetBottom( aRet, nRectBottom );
390  }
391  return aRet;
392 }
393 
395 {
396  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(m_pCurrFrame));
397 
398  OSL_ENSURE( m_bOn, "IsAnyFrame: Why?" );
401 
402  return ForEach( aRect, nullptr, false );
403 }
404 
405 bool SwTextFly::IsAnyObj( const SwRect &rRect ) const
406 {
407  OSL_ENSURE( m_bOn, "SwTextFly::IsAnyObj: Who's knocking?" );
408 
409  SwRect aRect( rRect );
410  if ( aRect.IsEmpty() )
411  {
414  }
415 
416  const SwSortedObjs *pSorted = m_pPage->GetSortedObjs();
417  if( pSorted ) // bOn actually makes sure that we have objects on the side,
418  // but who knows who deleted something in the meantime?
419  {
420  for ( size_t i = 0; i < pSorted->size(); ++i )
421  {
422  const SwAnchoredObject* pObj = (*pSorted)[i];
423 
424  const SwRect aBound( pObj->GetObjRectWithSpaces() );
425 
426  // Optimization
427  if( pObj->GetObjRect().Left() > aRect.Right() )
428  continue;
429 
430  // #i68520#
431  if( mpCurrAnchoredObj != pObj && aBound.IsOver( aRect ) )
432  return true;
433  }
434  }
435  return false;
436 }
437 
439 {
441  while (m_pMaster && m_pMaster->IsFollow())
443  return m_pMaster;
444 }
445 
447 {
448  SwSaveClip aClipSave( rInf.GetpOut() );
449  SwRect aRect( rInf.GetPos(), rInf.GetSize() );
450  if( rInf.GetSpace() )
451  {
452  TextFrameIndex const nTmpLen = TextFrameIndex(COMPLETE_STRING) == rInf.GetLen()
453  ? TextFrameIndex(rInf.GetText().getLength())
454  : rInf.GetLen();
455  if( rInf.GetSpace() > 0 )
456  {
457  sal_Int32 nSpaceCnt = 0;
458  const TextFrameIndex nEndPos = rInf.GetIdx() + nTmpLen;
459  for (TextFrameIndex nPos = rInf.GetIdx(); nPos < nEndPos; ++nPos)
460  {
461  if (CH_BLANK == rInf.GetText()[sal_Int32(nPos)])
462  ++nSpaceCnt;
463  }
464  if( nSpaceCnt )
465  aRect.Width( aRect.Width() + nSpaceCnt * rInf.GetSpace() );
466  }
467  else
468  aRect.Width( aRect.Width() - sal_Int32(nTmpLen) * rInf.GetSpace() );
469  }
470 
471  if( aClipSave.IsOn() && rInf.GetOut().IsClipRegion() )
472  {
473  SwRect aClipRect( rInf.GetOut().GetClipRegion().GetBoundRect() );
474  aRect.Intersection( aClipRect );
475  }
476 
477  SwRegionRects aRegion( aRect );
478 
479  bool bOpaque = false;
480  // #i68520#
481  const sal_uInt32 nCurrOrd = mpCurrAnchoredObj
483  : SAL_MAX_UINT32;
484  OSL_ENSURE( !m_bTopRule, "DrawTextOpaque: Wrong TopRule" );
485 
486  // #i68520#
487  const SwAnchoredObjList::size_type nCount( m_bOn ? GetAnchoredObjList()->size() : 0 );
488  if (nCount > 0)
489  {
491  for( SwAnchoredObjList::size_type i = 0; i < nCount; ++i )
492  {
493  // #i68520#
494  const SwAnchoredObject* pTmpAnchoredObj = (*mpAnchoredObjList)[i];
495  if( dynamic_cast<const SwFlyFrame*>(pTmpAnchoredObj) &&
496  mpCurrAnchoredObj != pTmpAnchoredObj )
497  {
498  // #i68520#
499  const SwFlyFrame& rFly = dynamic_cast<const SwFlyFrame&>(*pTmpAnchoredObj);
500  if( aRegion.GetOrigin().IsOver( rFly.getFrameArea() ) )
501  {
502  const SwFrameFormat *pFormat = rFly.GetFormat();
503  const SwFormatSurround &rSur = pFormat->GetSurround();
504  const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
505  // Only the ones who are opaque and more to the top
506  if( ! rFly.IsBackgroundTransparent() &&
507  css::text::WrapTextMode_THROUGH == rSur.GetSurround() &&
508  ( !rSur.IsAnchorOnly() ||
509  // #i68520#
510  GetMaster() == rFly.GetAnchorFrame() ||
511  ((RndStdIds::FLY_AT_PARA != rAnchor.GetAnchorId()) &&
512  (RndStdIds::FLY_AT_CHAR != rAnchor.GetAnchorId())
513  )
514  ) &&
515  // #i68520#
516  pTmpAnchoredObj->GetDrawObj()->GetLayer() != nHellId &&
517  nCurrOrd < pTmpAnchoredObj->GetDrawObj()->GetOrdNum()
518  )
519  {
520  // Except for the content is transparent
521  const SwNoTextFrame *pNoText =
522  rFly.Lower() && rFly.Lower()->IsNoTextFrame()
523  ? static_cast<const SwNoTextFrame*>(rFly.Lower())
524  : nullptr;
525  if ( !pNoText ||
526  (!pNoText->IsTransparent() && !rSur.IsContour()) )
527  {
528  bOpaque = true;
529  aRegion -= rFly.getFrameArea();
530  }
531  }
532  }
533  }
534  }
535  }
536 
537  Point aPos( rInf.GetPos().X(), rInf.GetPos().Y() + rInf.GetAscent() );
538  const Point aOldPos(rInf.GetPos());
539  rInf.SetPos( aPos );
540 
541  if( !bOpaque )
542  {
543  if( rInf.GetKern() )
544  rInf.GetFont()->DrawStretchText_( rInf );
545  else
546  rInf.GetFont()->DrawText_( rInf );
547  rInf.SetPos(aOldPos);
548  return;
549  }
550  else if( !aRegion.empty() )
551  {
552  // What a huge effort ...
553  SwSaveClip aClipVout( rInf.GetpOut() );
554  for( size_t i = 0; i < aRegion.size(); ++i )
555  {
556  SwRect &rRect = aRegion[i];
557  if( rRect != aRegion.GetOrigin() )
558  aClipVout.ChgClip( rRect );
559  if( rInf.GetKern() )
560  rInf.GetFont()->DrawStretchText_( rInf );
561  else
562  rInf.GetFont()->DrawText_( rInf );
563  }
564  }
565  rInf.SetPos(aOldPos);
566 }
567 
568 void SwTextFly::DrawFlyRect( OutputDevice* pOut, const SwRect &rRect )
569 {
570  SwRegionRects aRegion( rRect );
571  OSL_ENSURE( !m_bTopRule, "DrawFlyRect: Wrong TopRule" );
572  // #i68520#
573  const SwAnchoredObjList::size_type nCount( m_bOn ? GetAnchoredObjList()->size() : 0 );
574  if (nCount > 0)
575  {
577  for( SwAnchoredObjList::size_type i = 0; i < nCount; ++i )
578  {
579  // #i68520#
580  const SwAnchoredObject* pAnchoredObjTmp = (*mpAnchoredObjList)[i];
581  if (mpCurrAnchoredObj == pAnchoredObjTmp)
582  continue;
583 
584  // #i68520#
585  const SwFlyFrame* pFly = dynamic_cast<const SwFlyFrame*>(pAnchoredObjTmp);
586  if (pFly)
587  {
588  // #i68520#
589  const SwFormatSurround& rSur = pAnchoredObjTmp->GetFrameFormat().GetSurround();
590 
591  // OD 24.01.2003 #106593# - correct clipping of fly frame area.
592  // Consider that fly frame background/shadow can be transparent
593  // and <SwAlignRect(..)> fly frame area
594  // #i47804# - consider transparent graphics
595  // and OLE objects.
596  bool bClipFlyArea =
597  ( ( css::text::WrapTextMode_THROUGH == rSur.GetSurround() )
598  // #i68520#
599  ? (pAnchoredObjTmp->GetDrawObj()->GetLayer() != nHellId)
600  : !rSur.IsContour() ) &&
601  !pFly->IsBackgroundTransparent() &&
602  ( !pFly->Lower() ||
603  !pFly->Lower()->IsNoTextFrame() ||
604  !static_cast<const SwNoTextFrame*>(pFly->Lower())->IsTransparent() );
605  if ( bClipFlyArea )
606  {
607  // #i68520#
608  SwRect aFly( pAnchoredObjTmp->GetObjRect() );
609  // OD 24.01.2003 #106593#
610  ::SwAlignRect( aFly, m_pPage->getRootFrame()->GetCurrShell(), pOut );
611  if( !aFly.IsEmpty() )
612  aRegion -= aFly;
613  }
614  }
615  }
616  }
617 
618  for( size_t i = 0; i < aRegion.size(); ++i )
619  {
620  pOut->DrawRect( aRegion[i].SVRect() );
621  }
622 }
623 
628 bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj,
629  const bool bInFootnote,
630  const bool bInFooterOrHeader )
631 {
632  // #i68520#
633  // <mpCurrAnchoredObj> is set, if <m_pCurrFrame> is inside a fly frame
634  if( _pAnchoredObj != mpCurrAnchoredObj )
635  {
636  // #i26945#
637  const SdrObject* pNew = _pAnchoredObj->GetDrawObj();
638  // #102344# Ignore connectors which have one or more connections
639  if (const SdrEdgeObj* pEdgeObj = dynamic_cast<const SdrEdgeObj*>(pNew))
640  {
641  if (pEdgeObj->GetConnectedNode(true) || pEdgeObj->GetConnectedNode(false))
642  {
643  return false;
644  }
645  }
646 
647  if( ( bInFootnote || bInFooterOrHeader ) && m_bTopRule )
648  {
649  // #i26945#
650  const SwFrameFormat& rFrameFormat = _pAnchoredObj->GetFrameFormat();
651  const SwFormatAnchor& rNewA = rFrameFormat.GetAnchor();
652  if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
653  {
654  if ( bInFootnote )
655  return false;
656 
657  if ( bInFooterOrHeader )
658  {
659  const SwFormatVertOrient& aVert( rFrameFormat.GetVertOrient() );
660  bool bVertPrt = aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
661  aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA;
662  if( bVertPrt )
663  return false;
664  }
665  }
666  }
667 
668  // #i68520#
669  // bEvade: consider pNew, if we are not inside a fly
670  // consider pNew, if pNew is lower of <mpCurrAnchoredObj>
671  bool bEvade = !mpCurrAnchoredObj ||
672  Is_Lower_Of( dynamic_cast<const SwFlyFrame*>(mpCurrAnchoredObj), pNew);
673 
674  if ( !bEvade )
675  {
676  // We are currently inside a fly frame and pNew is not
677  // inside this fly frame. We can do some more checks if
678  // we have to consider pNew.
679 
680  // If bTopRule is not set, we ignore the frame types.
681  // We directly check the z-order
682  if ( !m_bTopRule )
683  bEvade = true;
684  else
685  {
686  // Within chained Flys we only avoid Lower
687  // #i68520#
689  if ( !rChain.GetPrev() && !rChain.GetNext() )
690  {
691  // #i26945#
692  const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor();
693  // #i68520#
695 
696  // If <mpCurrAnchoredObj> is anchored as character, its content
697  // does not wrap around pNew
698  if (RndStdIds::FLY_AS_CHAR == rCurrA.GetAnchorId())
699  return false;
700 
701  // If pNew is anchored to page and <mpCurrAnchoredObj is not anchored
702  // to page, the content of <mpCurrAnchoredObj> does not wrap around pNew
703  // If both pNew and <mpCurrAnchoredObj> are anchored to page, we can do
704  // some more checks
705  if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
706  {
707  if (RndStdIds::FLY_AT_PAGE == rCurrA.GetAnchorId())
708  {
709  bEvade = true;
710  }
711  else
712  return false;
713  }
714  else if (RndStdIds::FLY_AT_PAGE == rCurrA.GetAnchorId())
715  return false; // Page anchored ones only avoid page anchored ones
716  else if (RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId())
717  bEvade = true; // Non-page anchored ones avoid frame anchored ones
718  else if( RndStdIds::FLY_AT_FLY == rCurrA.GetAnchorId() )
719  return false; // Frame anchored ones do not avoid paragraph anchored ones
720  // #i57062#
721  // In order to avoid loop situation, it's decided to adjust
722  // the wrapping behaviour of content of at-paragraph/at-character
723  // anchored objects to one in the page header/footer and
724  // the document body --> content of at-paragraph/at-character
725  // anchored objects doesn't wrap around each other.
726  else
727  return false;
728  }
729  }
730 
731  // But: we never avoid a subordinate one and additionally we only avoid when overlapping.
732  // #i68520#
733  bEvade &= ( mpCurrAnchoredObj->GetDrawObj()->GetOrdNum() < pNew->GetOrdNum() );
734  if( bEvade )
735  {
736  // #i68520#
737  const SwRect& aTmp( _pAnchoredObj->GetObjRectWithSpaces() );
738  if ( !aTmp.IsOver( mpCurrAnchoredObj->GetObjRectWithSpaces() ) )
739  bEvade = false;
740  }
741  }
742 
743  if ( bEvade )
744  {
745  // #i26945#
746  const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor();
747  OSL_ENSURE( RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(),
748  "Don't call GetTop with a FlyInContentFrame" );
749  if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
750  return true; // We always avoid page anchored ones
751 
752  // If Flys anchored at paragraph are caught in a FlyCnt, then
753  // their influence ends at the borders of the FlyCnt!
754  // If we are currently formatting the text of the FlyCnt, then
755  // it has to get out of the way of the Frame anchored at paragraph!
756  // m_pCurrFrame is the anchor of pNew?
757  // #i26945#
758  const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame();
759  if (pTmp == m_pCurrFrame)
760  return true;
761  if( pTmp->IsTextFrame() && ( pTmp->IsInFly() || pTmp->IsInFootnote() ) )
762  {
763  // #i26945#
764  Point aPos = _pAnchoredObj->GetObjRect().Pos();
765  pTmp = GetVirtualUpper( pTmp, aPos );
766  }
767  // #i26945#
768  // If <pTmp> is a text frame inside a table, take the upper
769  // of the anchor frame, which contains the anchor position.
770  else if ( pTmp->IsTextFrame() && pTmp->IsInTab() )
771  {
772  pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj)
773  ->GetAnchorFrameContainingAnchPos()->GetUpper();
774  }
775  // #i28701# - consider all objects in same context,
776  // if wrapping style is considered on object positioning.
777  // Thus, text will wrap around negative positioned objects.
778  // #i3317# - remove condition on checking,
779  // if wrappings style is considered on object positioning.
780  // Thus, text is wrapping around negative positioned objects.
781  // #i35640# - no consideration of negative
782  // positioned objects, if wrapping style isn't considered on
783  // object position and former text wrapping is applied.
784  // This condition is typically for documents imported from the
785  // OpenOffice.org file format.
790  {
791  return true;
792  }
793 
794  const SwFrame* pHeader = nullptr;
795  if (m_pCurrFrame->GetNext() != pTmp &&
797  // #i13832#, #i24135# wrap around objects in page header
799  nullptr != ( pHeader = pTmp->FindFooterOrHeader() ) &&
801  {
802  if( pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId() )
803  return true;
804 
805  // Compare indices:
806  // The Index of the other is retrieved from the anchor attr.
807  sal_uLong nTmpIndex = rNewA.GetContentAnchor()->nNode.GetIndex();
808  // Now check whether the current paragraph is before the anchor
809  // of the displaced object in the text, then we don't have to
810  // get out of its way.
811  // If possible determine Index via SwFormatAnchor because
812  // otherwise it's quite expensive.
813  if (ULONG_MAX == m_nCurrFrameNodeIndex)
815 
816  if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) || nTmpIndex < m_nCurrFrameNodeIndex)
817  return true;
818  }
819  }
820  }
821  return false;
822 }
823 
824 // #i68520#
826 {
827  OSL_ENSURE( m_pCurrFrame, "InitFlyList: No Frame, no FlyList" );
828  // #i68520#
829  OSL_ENSURE( !mpAnchoredObjList, "InitFlyList: FlyList already initialized" );
830 
831  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(m_pCurrFrame));
832 
833  const SwSortedObjs *pSorted = m_pPage->GetSortedObjs();
834  const size_t nCount = pSorted ? pSorted->size() : 0;
835  // --> #108724# Page header/footer content doesn't have to wrap around
836  // floating screen objects
837  // which was added simply to be compatible with MS Office.
838  // MSO still allows text to wrap around in-table-flies in headers/footers/footnotes
839  const bool bFooterHeader = nullptr != m_pCurrFrame->FindFooterOrHeader();
841  // #i40155# - check, if frame is marked not to wrap
842  const bool bWrapAllowed = ( pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) ||
844  (!m_pCurrFrame->IsInFootnote() && !bFooterHeader));
845 
846  m_bOn = false;
847 
848  if( nCount && bWrapAllowed )
849  {
850  // #i68520#
852 
853  // #i28701# - consider complete frame area for new
854  // text wrapping
855  SwRect aRect;
857  {
858  aRect = m_pCurrFrame->getFramePrintArea();
859  aRect += m_pCurrFrame->getFrameArea().Pos();
860  }
861  else
862  {
863  aRect = m_pCurrFrame->getFrameArea();
864  }
865  // Make ourselves a little smaller than we are,
866  // so that 1-Twip-overlappings are ignored (#49532)
867  SwRectFnSet aRectFnSet(m_pCurrFrame);
868  const long nRight = aRectFnSet.GetRight(aRect) - 1;
869  const long nLeft = aRectFnSet.GetLeft(aRect) + 1;
870  const bool bR2L = m_pCurrFrame->IsRightToLeft();
871 
873 
874  for( size_t i = 0; i < nCount; ++i )
875  {
876  // #i68520#
877  // do not consider hidden objects
878  // check, if object has to be considered for text wrap
879  // #118809# - If requested, do not consider
880  // objects in page header|footer for text frames not in page
881  // header|footer. This is requested for the calculation of
882  // the base offset for objects <SwTextFrame::CalcBaseOfstForFly()>
883  // #i20505# Do not consider oversized objects
884  SwAnchoredObject* pAnchoredObj = (*pSorted)[ i ];
885  assert(pAnchoredObj);
886  if ( !pAnchoredObj ||
887  !rIDDMA.IsVisibleLayerId( pAnchoredObj->GetDrawObj()->GetLayer() ) ||
888  !pAnchoredObj->ConsiderForTextWrap() ||
889  ( mbIgnoreObjsInHeaderFooter && !bFooterHeader &&
890  pAnchoredObj->GetAnchorFrame()->FindFooterOrHeader() ) )
891  {
892  continue;
893  }
894 
895  const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
896  if ( nRight < aRectFnSet.GetLeft(aBound) ||
897  aRectFnSet.YDiff( aRectFnSet.GetTop(aRect),
898  aRectFnSet.GetBottom(aBound) ) > 0 ||
899  nLeft > aRectFnSet.GetRight(aBound) ||
900  aRectFnSet.GetHeight(aBound) >
901  2 * aRectFnSet.GetHeight(m_pPage->getFrameArea()) )
902  {
903  continue;
904  }
905 
906  // #i26945# - pass <pAnchoredObj> to method
907  // <GetTop(..)> instead of only the <SdrObject> instance of the
908  // anchored object
909  if (GetTop(pAnchoredObj, m_pCurrFrame->IsInFootnote(), bFooterHeader))
910  {
911  // OD 11.03.2003 #107862# - adjust insert position:
912  // overlapping objects should be sorted from left to right and
913  // inside left to right sorting from top to bottom.
914  // If objects on the same position are found, they are sorted
915  // on its width.
916  // #i68520#
917  {
918  SwAnchoredObjList::iterator aInsPosIter =
919  std::lower_bound( mpAnchoredObjList->begin(),
920  mpAnchoredObjList->end(),
921  pAnchoredObj,
922  AnchoredObjOrder( bR2L, aRectFnSet.FnRect() ) );
923 
924  mpAnchoredObjList->insert( aInsPosIter, pAnchoredObj );
925  }
926 
927  const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround();
928  // #i68520#
929  if ( rFlyFormat.IsAnchorOnly() &&
930  pAnchoredObj->GetAnchorFrame() == GetMaster() )
931  {
932  const SwFormatVertOrient &rTmpFormat =
933  pAnchoredObj->GetFrameFormat().GetVertOrient();
934  if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() )
935  m_nMinBottom = ( aRectFnSet.IsVert() && m_nMinBottom ) ?
936  std::min( m_nMinBottom, aBound.Left() ) :
937  std::max( m_nMinBottom, aRectFnSet.GetBottom(aBound) );
938  }
939 
940  m_bOn = true;
941  }
942  }
943  if( m_nMinBottom )
944  {
945  SwTwips nMax = aRectFnSet.GetPrtBottom(*m_pCurrFrame->GetUpper());
946  if( aRectFnSet.YDiff( m_nMinBottom, nMax ) > 0 )
947  m_nMinBottom = nMax;
948  }
949  }
950  else
951  {
952  // #i68520#
954  }
955 
956  // #i68520#
957  return mpAnchoredObjList.get();
958 }
959 
961 {
962  SwTwips nRet = 0;
963  const SwContentFrame *pLclMaster = GetMaster();
964  OSL_ENSURE(pLclMaster, "SwTextFly without master");
965  const SwSortedObjs *pDrawObj = pLclMaster ? pLclMaster->GetDrawObjs() : nullptr;
966  const size_t nCount = pDrawObj ? pDrawObj->size() : 0;
967  if( nCount )
968  {
969  SwTwips nEndOfFrame = m_pCurrFrame->getFrameArea().Bottom();
970  for( size_t i = 0; i < nCount; ++i )
971  {
972  SwAnchoredObject* pAnchoredObj = (*pDrawObj)[ i ];
973  const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround();
974  if( rFlyFormat.IsAnchorOnly() )
975  {
976  const SwFormatVertOrient &rTmpFormat =
977  pAnchoredObj->GetFrameFormat().GetVertOrient();
978  if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() )
979  {
980  const SwRect& aBound( pAnchoredObj->GetObjRectWithSpaces() );
981  if( aBound.Top() < nEndOfFrame )
982  nRet = std::max( nRet, aBound.Bottom() );
983  }
984  }
985  }
986  SwTwips nMax = m_pCurrFrame->GetUpper()->getFrameArea().Top() +
988  if( nRet > nMax )
989  nRet = nMax;
990  }
991  return nRet;
992 }
993 
994 bool SwTextFly::ForEach( const SwRect &rRect, SwRect* pRect, bool bAvoid ) const
995 {
996  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(m_pCurrFrame));
997 
998  // Optimization
999  SwRectFnSet aRectFnSet(m_pCurrFrame);
1000 
1001  // tdf#127235 stop if the area is larger than the page
1002  if( aRectFnSet.GetHeight(m_pPage->getFrameArea()) < aRectFnSet.GetHeight(rRect))
1003  {
1004  // get the doc model description
1005  const SwPageDesc* pPageDesc = m_pPage->GetPageDesc();
1006 
1007  // if there is no next page style or it is the same as the current
1008  // => stop trying to place the frame (it would end in an infinite loop)
1009  if( pPageDesc &&
1010  ( !pPageDesc->GetFollow() || pPageDesc->GetFollow() == pPageDesc) )
1011  {
1012  return false;
1013  }
1014  }
1015 
1016  bool bRet = false;
1017  // #i68520#
1018  const SwAnchoredObjList::size_type nCount( m_bOn ? GetAnchoredObjList()->size() : 0 );
1019  if (nCount > 0)
1020  {
1021  for( SwAnchoredObjList::size_type i = 0; i < nCount; ++i )
1022  {
1023  // #i68520#
1024  const SwAnchoredObject* pAnchoredObj = (*mpAnchoredObjList)[i];
1025 
1026  SwRect aRect( pAnchoredObj->GetObjRectWithSpaces() );
1027 
1028  if( aRectFnSet.GetLeft(aRect) > aRectFnSet.GetRight(rRect) )
1029  break;
1030 
1031  // #i68520#
1032  if ( mpCurrAnchoredObj != pAnchoredObj && aRect.IsOver( rRect ) )
1033  {
1034  // #i68520#
1035  const SwFormat* pFormat( &(pAnchoredObj->GetFrameFormat()) );
1036  const SwFormatSurround &rSur = pFormat->GetSurround();
1037  if( bAvoid )
1038  {
1039  // If the text flows below, it has no influence on
1040  // formatting. In LineIter::DrawText() it is "just"
1041  // necessary to cleverly set the ClippingRegions
1042  const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
1043  if( ( css::text::WrapTextMode_THROUGH == rSur.GetSurround() &&
1044  ( !rSur.IsAnchorOnly() ||
1045  // #i68520#
1046  GetMaster() == pAnchoredObj->GetAnchorFrame() ||
1047  ((RndStdIds::FLY_AT_PARA != rAnchor.GetAnchorId()) &&
1048  (RndStdIds::FLY_AT_CHAR != rAnchor.GetAnchorId())) ) )
1049  || aRect.Top() == FAR_AWAY )
1050  continue;
1051  }
1052 
1053  // #i58642#
1054  // Compare <GetMaster()> instead of <m_pCurrFrame> with the
1055  // anchor frame of the anchored object, because a follow frame
1056  // has to ignore the anchored objects of its master frame.
1057  // Note: Anchored objects are always registered at the master
1058  // frame, exception are as-character anchored objects,
1059  // but these aren't handled here.
1060  // #i68520#
1061  if ( mbIgnoreCurrentFrame &&
1062  GetMaster() == pAnchoredObj->GetAnchorFrame() )
1063  continue;
1064 
1065  if( pRect )
1066  {
1067  // #i68520#
1068  SwRect aFly = AnchoredObjToRect( pAnchoredObj, rRect );
1069  if( aFly.IsEmpty() || !aFly.IsOver( rRect ) )
1070  continue;
1071  if( !bRet || (
1072  (!m_pCurrFrame->IsRightToLeft() &&
1073  ( aRectFnSet.GetLeft(aFly) <
1074  aRectFnSet.GetLeft(*pRect) ) ) ||
1076  ( aRectFnSet.GetRight(aFly) >
1077  aRectFnSet.GetRight(*pRect) ) ) ) )
1078  *pRect = aFly;
1079  if( rSur.IsContour() )
1080  {
1081  bRet = true;
1082  continue;
1083  }
1084  }
1085  bRet = true;
1086  break;
1087  }
1088  }
1089  }
1090 
1091  return bRet;
1092 }
1093 
1094 // #i68520#
1095 SwAnchoredObjList::size_type SwTextFly::GetPos( const SwAnchoredObject* pAnchoredObj ) const
1096 {
1097  SwAnchoredObjList::size_type nCount = GetAnchoredObjList()->size();
1098  SwAnchoredObjList::size_type nRet = 0;
1099  while ( nRet < nCount && pAnchoredObj != (*mpAnchoredObjList)[ nRet ] )
1100  ++nRet;
1101  return nRet;
1102 }
1103 
1104 // #i68520#
1106  SwAnchoredObjList::size_type nFlyPos,
1107  const SwRect &rLine ) const
1108 {
1109  // Usually the right margin is the right margin of the Printarea
1110  OSL_ENSURE( !m_pCurrFrame->IsVertical() || !m_pCurrFrame->IsSwapped(),
1111  "SwTextFly::CalcRightMargin with swapped frame" );
1112  SwRectFnSet aRectFnSet(m_pCurrFrame);
1113  // #118796# - correct determination of right of printing area
1114  SwTwips nRight = aRectFnSet.GetPrtRight(*m_pCurrFrame);
1115  SwTwips nFlyRight = aRectFnSet.GetRight(rFly);
1116  SwRect aLine( rLine );
1117  aRectFnSet.SetRight( aLine, nRight );
1118  aRectFnSet.SetLeft( aLine, aRectFnSet.GetLeft(rFly) );
1119 
1120  // It is possible that there is another object that is _above_ us
1121  // and protrudes into the same line.
1122  // Flys with run-through are invisible for those below, i.e., they
1123  // are ignored for computing the margins of other Flys.
1124  // 3301: pNext->getFrameArea().IsOver( rLine ) is necessary
1125  // #i68520#
1126  css::text::WrapTextMode eSurroundForTextWrap;
1127 
1128  bool bStop = false;
1129  // #i68520#
1130  SwAnchoredObjList::size_type nPos = 0;
1131 
1132  // #i68520#
1133  while( nPos < mpAnchoredObjList->size() && !bStop )
1134  {
1135  if( nPos == nFlyPos )
1136  {
1137  ++nPos;
1138  continue;
1139  }
1140  // #i68520#
1141  const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nPos++ ];
1142  if ( pNext == mpCurrAnchoredObj )
1143  continue;
1144  eSurroundForTextWrap = GetSurroundForTextWrap( pNext );
1145  if( css::text::WrapTextMode_THROUGH == eSurroundForTextWrap )
1146  continue;
1147 
1149  ( pNext, aLine, m_pCurrFrame, nFlyRight, true ) );
1150  SwTwips nTmpRight = aRectFnSet.GetRight(aTmp);
1151 
1152  // optimization:
1153  // Record in nNextTop at which Y-position frame related changes are
1154  // likely. This is so that, despite only looking at frames in the
1155  // current line height, for frames without wrap the line height is
1156  // incremented so that with a single line the lower border of the frame
1157  // (or possibly the upper border of another frame) is reached.
1158  // Especially in HTML documents there are often (dummy) paragraphs in
1159  // 2 pt font, and they used to only evade big frames after huge numbers
1160  // of empty lines.
1161  const long nTmpTop = aRectFnSet.GetTop(aTmp);
1162  if( aRectFnSet.YDiff( nTmpTop, aRectFnSet.GetTop(aLine) ) > 0 )
1163  {
1164  if( aRectFnSet.YDiff( m_nNextTop, nTmpTop ) > 0 )
1165  SetNextTop( nTmpTop ); // upper border of next frame
1166  }
1167  else if (!aRectFnSet.GetWidth(aTmp)) // typical for Objects with contour wrap
1168  { // For Objects with contour wrap that start before the current
1169  // line, and end below it, but do not actually overlap it, the
1170  // optimization has to be disabled, because the circumstances
1171  // can change in the next line.
1172  if( ! aRectFnSet.GetHeight(aTmp) ||
1173  aRectFnSet.YDiff( aRectFnSet.GetBottom(aTmp),
1174  aRectFnSet.GetTop(aLine) ) > 0 )
1175  SetNextTop( 0 );
1176  }
1177  if( aTmp.IsOver( aLine ) && nTmpRight > nFlyRight )
1178  {
1179  nFlyRight = nTmpRight;
1180  if( css::text::WrapTextMode_RIGHT == eSurroundForTextWrap ||
1181  css::text::WrapTextMode_PARALLEL == eSurroundForTextWrap )
1182  {
1183  // overrule the FlyFrame
1184  if( nRight > nFlyRight )
1185  nRight = nFlyRight;
1186  bStop = true;
1187  }
1188  }
1189  }
1190  aRectFnSet.SetRight( rFly, nRight );
1191 }
1192 
1193 // #i68520#
1195  SwAnchoredObjList::size_type nFlyPos,
1196  const SwRect &rLine ) const
1197 {
1198  OSL_ENSURE( !m_pCurrFrame->IsVertical() || !m_pCurrFrame->IsSwapped(),
1199  "SwTextFly::CalcLeftMargin with swapped frame" );
1200  SwRectFnSet aRectFnSet(m_pCurrFrame);
1201  // #118796# - correct determination of left of printing area
1202  SwTwips nLeft = aRectFnSet.GetPrtLeft(*m_pCurrFrame);
1203  const SwTwips nFlyLeft = aRectFnSet.GetLeft(rFly);
1204 
1205  if( nLeft > nFlyLeft )
1206  nLeft = rFly.Left();
1207 
1208  SwRect aLine( rLine );
1209  aRectFnSet.SetLeft( aLine, nLeft );
1210 
1211  // It is possible that there is another object that is _above_ us
1212  // and protrudes into the same line.
1213  // Flys with run-through are invisible for those below, i.e., they
1214  // are ignored for computing the margins of other Flys.
1215  // 3301: pNext->getFrameArea().IsOver( rLine ) is necessary
1216 
1217  // #i68520#
1218  SwAnchoredObjList::size_type nMyPos = nFlyPos;
1219  while( ++nFlyPos < mpAnchoredObjList->size() )
1220  {
1221  // #i68520#
1222  const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nFlyPos ];
1223  const SwRect& aTmp( pNext->GetObjRectWithSpaces() );
1224  if( aRectFnSet.GetLeft(aTmp) >= nFlyLeft )
1225  break;
1226  }
1227 
1228  while( nFlyPos )
1229  {
1230  if( --nFlyPos == nMyPos )
1231  continue;
1232  // #i68520#
1233  const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nFlyPos ];
1234  if( pNext == mpCurrAnchoredObj )
1235  continue;
1236  css::text::WrapTextMode eSurroundForTextWrap = GetSurroundForTextWrap( pNext );
1237  if( css::text::WrapTextMode_THROUGH == eSurroundForTextWrap )
1238  continue;
1239 
1241  (pNext, aLine, m_pCurrFrame, nFlyLeft, false) );
1242 
1243  if( aRectFnSet.GetLeft(aTmp) < nFlyLeft && aTmp.IsOver( aLine ) )
1244  {
1245  // #118796# - no '+1', because <..fnGetRight>
1246  // returns the correct value.
1247  SwTwips nTmpRight = aRectFnSet.GetRight(aTmp);
1248  if ( nLeft <= nTmpRight )
1249  nLeft = nTmpRight;
1250 
1251  break;
1252  }
1253  }
1254  aRectFnSet.SetLeft( rFly, nLeft );
1255 }
1256 
1257 // #i68520#
1259  const SwRect &rLine ) const
1260 {
1261  SwRectFnSet aRectFnSet(m_pCurrFrame);
1262 
1263  const long nXPos = m_pCurrFrame->IsRightToLeft() ?
1264  rLine.Right() :
1265  aRectFnSet.GetLeft(rLine);
1266 
1267  SwRect aFly = mbIgnoreContour ?
1268  pAnchoredObj->GetObjRectWithSpaces() :
1269  SwContourCache::CalcBoundRect(pAnchoredObj, rLine, m_pCurrFrame,
1270  nXPos, !m_pCurrFrame->IsRightToLeft());
1271 
1272  if( !aFly.Width() )
1273  return aFly;
1274 
1275  // so the line may grow up to the lower edge of the frame
1276  SetNextTop( aRectFnSet.GetBottom(aFly) );
1277  SwAnchoredObjList::size_type nFlyPos = GetPos( pAnchoredObj );
1278 
1279  // LEFT and RIGHT, we grow the rectangle.
1280  // We have some problems, when several frames are to be seen.
1281  // At the moment, only the easier case is assumed:
1282  // + LEFT means that the text must flow on the left of the frame,
1283  // that is the frame expands to the right edge of the print area
1284  // or to the next frame.
1285  // + RIGHT is the opposite.
1286  // Otherwise the set distance between text and frame is always
1287  // added up.
1288  switch( GetSurroundForTextWrap( pAnchoredObj ) )
1289  {
1290  case css::text::WrapTextMode_LEFT :
1291  {
1292  CalcRightMargin( aFly, nFlyPos, rLine );
1293  break;
1294  }
1295  case css::text::WrapTextMode_RIGHT :
1296  {
1297  CalcLeftMargin( aFly, nFlyPos, rLine );
1298  break;
1299  }
1300  case css::text::WrapTextMode_NONE :
1301  {
1302  CalcRightMargin( aFly, nFlyPos, rLine );
1303  CalcLeftMargin( aFly, nFlyPos, rLine );
1304  break;
1305  }
1306  default:
1307  break;
1308  }
1309  return aFly;
1310 }
1311 
1312 // #i68520#
1313 
1314 // Wrap only on sides with at least 2cm space for the text
1315 #define TEXT_MIN 1134
1316 
1317 // MS Word wraps on sides with even less space (value guessed).
1318 #define TEXT_MIN_SMALL 300
1319 
1320 // Wrap on both sides up to a frame width of 1.5cm
1321 #define FRAME_MAX 850
1322 
1323 css::text::WrapTextMode SwTextFly::GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const
1324 {
1325  const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat());
1326  const SwFormatSurround &rFlyFormat = pFormat->GetSurround();
1327  css::text::WrapTextMode eSurroundForTextWrap = rFlyFormat.GetSurround();
1328 
1329  if( rFlyFormat.IsAnchorOnly() && pAnchoredObj->GetAnchorFrame() != GetMaster() )
1330  {
1331  const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
1332  if ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) ||
1333  (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()))
1334  {
1335  return css::text::WrapTextMode_NONE;
1336  }
1337  }
1338 
1339  // in cause of run-through and nowrap ignore smartly
1340  if( css::text::WrapTextMode_THROUGH == eSurroundForTextWrap ||
1341  css::text::WrapTextMode_NONE == eSurroundForTextWrap )
1342  return eSurroundForTextWrap;
1343 
1344  // left is left and right is right
1345  if (m_pCurrFrame->IsRightToLeft())
1346  {
1347  if ( css::text::WrapTextMode_LEFT == eSurroundForTextWrap )
1348  eSurroundForTextWrap = css::text::WrapTextMode_RIGHT;
1349  else if ( css::text::WrapTextMode_RIGHT == eSurroundForTextWrap )
1350  eSurroundForTextWrap = css::text::WrapTextMode_LEFT;
1351  }
1352 
1353  // "ideal page wrap":
1354  if ( css::text::WrapTextMode_DYNAMIC == eSurroundForTextWrap )
1355  {
1356  SwRectFnSet aRectFnSet(m_pCurrFrame);
1357  const long nCurrLeft = aRectFnSet.GetPrtLeft(*m_pCurrFrame);
1358  const long nCurrRight = aRectFnSet.GetPrtRight(*m_pCurrFrame);
1359  const SwRect& aRect( pAnchoredObj->GetObjRectWithSpaces() );
1360  long nFlyLeft = aRectFnSet.GetLeft(aRect);
1361  long nFlyRight = aRectFnSet.GetRight(aRect);
1362 
1363  if ( nFlyRight < nCurrLeft || nFlyLeft > nCurrRight )
1364  eSurroundForTextWrap = css::text::WrapTextMode_PARALLEL;
1365  else
1366  {
1367  long nLeft = nFlyLeft - nCurrLeft;
1368  long nRight = nCurrRight - nFlyRight;
1369  if( nFlyRight - nFlyLeft > FRAME_MAX )
1370  {
1371  if( nLeft < nRight )
1372  nLeft = 0;
1373  else
1374  nRight = 0;
1375  }
1376  const int textMin = GetMaster()->GetDoc()
1379 
1380  // In case there is no space on either side, then css::text::WrapTextMode_PARALLEL
1381  // gives the same result when doing the initial layout or a layout
1382  // update after editing, so prefer that over css::text::WrapTextMode_NONE.
1383  if (nLeft == 0 && nRight == 0)
1384  return css::text::WrapTextMode_PARALLEL;
1385 
1386  if( nLeft < textMin )
1387  nLeft = 0;
1388  if( nRight < textMin )
1389  nRight = 0;
1390  if( nLeft )
1391  eSurroundForTextWrap = nRight ? css::text::WrapTextMode_PARALLEL : css::text::WrapTextMode_LEFT;
1392  else
1393  eSurroundForTextWrap = nRight ? css::text::WrapTextMode_RIGHT: css::text::WrapTextMode_NONE;
1394  }
1395  }
1396 
1397  return eSurroundForTextWrap;
1398 }
1399 
1400 bool SwTextFly::IsAnyFrame( const SwRect &rLine ) const
1401 {
1402 
1403  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(m_pCurrFrame));
1404 
1405  OSL_ENSURE( m_bOn, "IsAnyFrame: Why?" );
1406 
1407  return ForEach( rLine, nullptr, false );
1408 }
1409 
1410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwAnchoredObjList * GetAnchoredObjList() const
Definition: txtfly.hxx:301
long GetLeft() const
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:547
vcl::Region GetClipRegion() const
bool IsContour() const
Definition: fmtsrnd.hxx:53
Base class of the Writer layout elements.
Definition: frame.hxx:297
virtual basegfx::B2DPolyPolygon TakeXorPoly() const
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
virtual SwRect GetObjRect() const =0
long m_nNextTop
Definition: txtfly.hxx:128
void SetTopAndHeight(SwRect &rRect, long nTop, long nHeight) const
Definition: frame.hxx:1406
sal_uLong GetIndex() const
Definition: node.hxx:282
long GetSpace() const
Definition: drawfont.hxx:325
bool IsFollow() const
Definition: flowfrm.hxx:166
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2807
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:545
const SwRect & GetOrigin() const
Definition: swregion.hxx:47
bool IsInDocBody() const
Definition: frame.hxx:921
bool IsInFly() const
Definition: frame.hxx:939
const SwFrame * FindContext(const SwFrame *pFrame, SwFrameType nAdditionalContextTyp)
provides the area of a frame in that no Fly from another area can overlap
Definition: frmtool.cxx:3497
sal_uInt16 GetLower() const
vcl::RenderContext * GetpOut() const
Definition: drawfont.hxx:185
bool IsAnyFrame() const
Same as IsAnyFrame(const SwRect&), but uses the current frame print area.
Definition: txtfly.cxx:394
SwFont * GetFont() const
Definition: drawfont.hxx:250
bool IsSwapped() const
Definition: txtfrm.hxx:526
bool IsAnyObj(const SwRect &rRect) const
true when a frame or DrawObj must be taken in account.
Definition: txtfly.cxx:405
bool mbIgnoreObjsInHeaderFooter
boolean, indicating if objects in page header|footer are considered for text frames not in page heade...
Definition: txtfly.hxx:139
SwRect GetFrame_(const SwRect &rPortion) const
This method will be called during the LineIter formatting.
Definition: txtfly.cxx:376
const SwTextFrame * GetMaster_()
Definition: txtfly.cxx:438
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
SwNodeIndex nNode
Definition: pam.hxx:37
void ClrObject(sal_uInt16 nPos)
Definition: txtfly.cxx:127
bool IsInFootnote() const
Definition: frame.hxx:927
SwRectFn FnRect() const
Definition: frame.hxx:1347
#define TEXT_MIN_SMALL
Definition: txtfly.cxx:1318
sal_uIntPtr sal_uLong
const SwRect & getFramePrintArea() const
Definition: frame.hxx:178
void DrawFlyRect(OutputDevice *pOut, const SwRect &rRect)
Two subtleties needs to be mentioned:
Definition: txtfly.cxx:568
The purpose of this class is to be the universal interface between formatting/text output and the pos...
Definition: txtfly.hxx:119
SwAnchoredObjList * InitAnchoredObjList()
Definition: txtfly.cxx:825
#define POLY_CNT
Definition: txtfly.hxx:46
void SetPos(const Point &rNew)
Definition: drawfont.hxx:397
long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1356
long SwTwips
Definition: swtypes.hxx:49
#define TEXT_MIN
Definition: txtfly.cxx:1315
sal_uInt16 GetAscent() const
Definition: drawfont.hxx:299
SwContourCache * pContourCache
Contour-cache global variable, initialized/destroyed in txtinit.cxx and needed in txtfly...
Definition: txtinit.cxx:30
bool IsVert() const
Definition: frame.hxx:1345
void Pos(const Point &rNew)
Definition: swrect.hxx:169
bool IsBackgroundTransparent() const
SwFlyFrame::IsBackgroundTransparent.
Definition: paintfrm.cxx:3749
long mnPointCount
Definition: txtfly.hxx:61
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
tools::Rectangle GetBoundRect() const
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:55
SwTwips CalcMinBottom() const
Definition: txtfly.cxx:960
const SwAnchoredObject * mpCurrAnchoredObj
Definition: txtfly.hxx:122
bool mbIgnoreCurrentFrame
Definition: txtfly.hxx:133
void DrawText_(SwDrawTextInfo &rInf)
Definition: swfont.hxx:314
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:154
const SwTextFrame * m_pMaster
Definition: txtfly.hxx:124
SwRectGet fnGetRight
Definition: frame.hxx:1272
long YDiff(long n1, long n2) const
Definition: frame.hxx:1401
#define SAL_MAX_UINT32
wrapper class for the positioning of Writer fly frames and drawing objects
virtual bool IsVisibleLayerId(SdrLayerID _nLayerId) const =0
method to determine, if a layer ID belongs to the visible ones.
long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1388
void Top(const long nTop)
Definition: swrect.hxx:204
void SwAlignRect(SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext *pRenderContext)
Function is also used outside this file.
Definition: paintfrm.cxx:1120
const SwRect & getFrameArea() const
Definition: frame.hxx:177
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
bool IsInTab() const
Definition: frame.hxx:933
void CalcLeftMargin(SwRect &rFly, SwAnchoredObjList::size_type nPos, const SwRect &rLine) const
The left margin is the left margin of the current PrintArea or it is determined by the last FlyFrame...
Definition: txtfly.cxx:1194
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:56
int nCount
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
#define POLY_MIN
Definition: txtfly.hxx:47
bool IsFrameInSameContext(const SwFrame *pInnerFrame, const SwFrame *pFrame)
Definition: frmtool.cxx:3511
bool IsTextFrame() const
Definition: frame.hxx:1212
bool IsAnchorOnly() const
Definition: fmtsrnd.hxx:52
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
long GetKern() const
Definition: drawfont.hxx:320
SwRect ContourRect(const SwFormat *pFormat, const SdrObject *pObj, const SwTextFrame *pFrame, const SwRect &rLine, const long nXPos, const bool bRight)
Definition: txtfly.cxx:202
sal_uLong m_nCurrFrameNodeIndex
Stores the upper edge of the "next" frame.
Definition: txtfly.hxx:129
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1089
long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1357
long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1358
void Right(const long nRight)
Definition: swrect.hxx:200
void DrawTextOpaque(SwDrawTextInfo &rInf)
This method is called by DrawText().
Definition: txtfly.cxx:446
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2589
#define POLY_MAX
Definition: txtfly.hxx:48
bool IsEmpty() const
Definition: swrect.hxx:292
void ClrContourCache(const SdrObject *pObj)
Definition: txtfly.cxx:133
void SetBottom(SwRect &rRect, long nNew) const
Definition: frame.hxx:1365
void DrawRect(const tools::Rectangle &rRect)
const OUString & GetText() const
Definition: drawfont.hxx:216
Base class for various Writer styles.
Definition: format.hxx:43
std::vector< CacheItem > mvItems
Definition: txtfly.hxx:60
bool ConsiderForTextWrap() const
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:448
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:284
Style of a layout element.
Definition: frmfmt.hxx:57
long m_nMinBottom
Definition: txtfly.hxx:127
void SetTop(SwRect &rRect, long nNew) const
Definition: frame.hxx:1364
const SdrObject * GetDrawObj() const
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:119
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
bool IsClipRegion() const
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
size_t size() const
Definition: sortedobjs.cxx:42
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
SwPageFrame * FindPageFrame()
Definition: frame.hxx:660
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:130
const sal_Unicode CH_BLANK
Definition: swfont.hxx:42
FlyAnchors.
Definition: fmtanchr.hxx:34
SwLayoutFrame * GetUpper()
Definition: frame.hxx:658
const SwRect & GetObjRectWithSpaces() const
method to determine object area inclusive its spacing
static SwRect CalcBoundRect(const SwAnchoredObject *pAnchoredObj, const SwRect &rLine, const SwTextFrame *pFrame, const long nXPos, const bool bRight)
Computes the rectangle that will cover the object in the given line.
Definition: txtfly.cxx:154
virtual basegfx::B2DPolyPolygon TakeContour() const
bool GetTop(const SwAnchoredObject *_pAnchoredObj, const bool bInFootnote, const bool bInFooterOrHeader)
#i26945# - change first parameter Now it's the instance of the floating screen obj...
Definition: txtfly.cxx:628
sal_uInt32 GetOrdNum() const
Provides access to settings of a document.
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
void DrawStretchText_(SwDrawTextInfo &rInf)
Definition: swfont.hxx:317
size
Connection (text flow) between two FlyFrames.
Definition: fmtcnct.hxx:31
SwRect AnchoredObjToRect(const SwAnchoredObject *pAnchoredObj, const SwRect &rRect) const
Determines the demanded rectangle for an anchored object, considering its surround for text wrapping...
Definition: txtfly.cxx:1258
const SdrObject * GetObject(sal_uInt16 nPos) const
Definition: txtfly.hxx:69
bool mbIgnoreContour
Definition: txtfly.hxx:134
void CalcRightMargin(SwRect &rFly, SwAnchoredObjList::size_type nPos, const SwRect &rLine) const
The right margin is the right margin or it is determined by the next object standing on the line...
Definition: txtfly.cxx:1105
void SSize(const Size &rNew)
Definition: swrect.hxx:178
long GetPrtRight(const SwFrame &rFrame) const
Definition: frame.hxx:1390
bool IsTransparent() const
Definition: notxtfrm.cxx:1486
sal_uInt16 GetCount() const
Definition: txtfly.hxx:70
bool m_bTopRule
Definition: txtfly.hxx:132
SwFlyFrameFormat * GetNext() const
Definition: fmtcnct.hxx:54
virtual SdrLayerID GetHellId() const =0
std::vector< SwAnchoredObject * > SwAnchoredObjList
Definition: txtfly.hxx:37
virtual SdrLayerID GetLayer() const
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:246
void SetLeft(SwRect &rRect, long nNew) const
Definition: frame.hxx:1366
long GetPrtLeft(const SwFrame &rFrame) const
Definition: frame.hxx:1389
SwTextFly()
Definition: txtfly.cxx:306
bool m_bOn
Definition: txtfly.hxx:131
SwRectGet fnGetLeft
Definition: frame.hxx:1271
const SwTextFrame * m_pCurrFrame
Definition: txtfly.hxx:123
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
SwAnchoredObjList::size_type GetPos(const SwAnchoredObject *pAnchoredObj) const
Definition: txtfly.cxx:1095
void Left(const long nLeft)
Definition: swrect.hxx:195
void Bottom(const long nBottom)
Definition: swrect.hxx:209
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:76
std::unique_ptr< SwAnchoredObjList > mpAnchoredObjList
Definition: txtfly.hxx:125
const SwFormatChain & GetChain(bool=true) const
Definition: fmtcnct.hxx:70
bool Is_Lower_Of(const SwFrame *pCurrFrame, const SdrObject *pObj)
Definition: frmtool.cxx:3465
const SwTextFrame * GetMaster() const
Definition: txtfly.hxx:341
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
::basegfx::B2DPolyPolygon getB2DPolyPolygon() const
virtual SwFrameFormat & GetFrameFormat()=0
const SwPageFrame * m_pPage
Definition: txtfly.hxx:121
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:681
bool supportsAutoContour() const
Definition: flylay.cxx:303
void Width(long nNew)
Definition: swrect.hxx:187
const Point & GetPos() const
Definition: drawfont.hxx:195
TextFrameIndex GetLen() const
Definition: drawfont.hxx:268
bool IsNoTextFrame() const
Definition: frame.hxx:1216
const Size & GetSize() const
Definition: drawfont.hxx:242
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:175
bool IsRightToLeft() const
Definition: frame.hxx:965
~SwTextFly()
Definition: txtfly.cxx:349
bool ForEach(const SwRect &rRect, SwRect *pRect, bool bAvoid) const
Look for the first object which overlaps with the rectangle.
Definition: txtfly.cxx:994
const SwFrame * GetVirtualUpper(const SwFrame *pFrame, const Point &rPos)
Provides the Upper of an anchor in paragraph-bound objects.
Definition: frmtool.cxx:3433
void SetRight(SwRect &rRect, long nNew) const
Definition: frame.hxx:1367
css::text::WrapTextMode GetSurroundForTextWrap(const SwAnchoredObject *pAnchoredObj) const
Definition: txtfly.cxx:1323
#define FRAME_MAX
Definition: txtfly.cxx:1321
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:54
long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1360
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
vcl::RenderContext & GetOut() const
Definition: drawfont.hxx:180
#define FAR_AWAY
Definition: frmtool.hxx:52
void SetNextTop(long nNew) const
Definition: txtfly.hxx:351
long GetRight() const
bool IsVertical() const
Definition: frame.hxx:951
long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1355
SwDoc & GetDoc()
Definition: txtfrm.hxx:451
TextFrameIndex GetIdx() const
Definition: drawfont.hxx:263
bool IsOutside() const
Definition: fmtsrnd.hxx:54
const SwFrame * GetAnchorFrame() const
SwOperator fnYDiff
Definition: frame.hxx:1315
void CtorInitTextFly(const SwTextFrame *pFrame)
Definition: txtfly.cxx:353
bool IsOver(const SwRect &rRect) const
Definition: swrect.cxx:123
SwFlyFrameFormat * GetPrev() const
Definition: fmtcnct.hxx:53
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:205
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
class for collecting anchored objects
Definition: sortedobjs.hxx:48
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:659
sal_uInt16 nPos
sal_uInt16 GetUpper() const
SwRectGet fnGetTop
Definition: frame.hxx:1269
SwFrame * GetNext()
Definition: frame.hxx:656
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74