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 <fmtfollowtextflow.hxx>
47 #include <pagedesc.hxx>
48 #include <sortedobjs.hxx>
51 #include <svx/svdoedge.hxx>
52 
53 #ifdef DBG_UTIL
54 #include <viewsh.hxx>
55 #include <doc.hxx>
56 #endif
57 
58 using namespace ::com::sun::star;
59 
60 namespace
61 {
62  // #i68520#
63  struct AnchoredObjOrder
64  {
65  bool mbR2L;
66  SwRectFn mfnRect;
67 
68  AnchoredObjOrder( const bool bR2L,
69  SwRectFn fnRect )
70  : mbR2L( bR2L ),
71  mfnRect( fnRect )
72  {}
73 
74  bool operator()( const SwAnchoredObject* pListedAnchoredObj,
75  const SwAnchoredObject* pNewAnchoredObj )
76  {
77  const SwRect& aBoundRectOfListedObj( pListedAnchoredObj->GetObjRectWithSpaces() );
78  const SwRect& aBoundRectOfNewObj( pNewAnchoredObj->GetObjRectWithSpaces() );
79  if ( ( mbR2L &&
80  ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ==
81  (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
82  ( !mbR2L &&
83  ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ==
84  (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
85  {
86  SwTwips nTopDiff =
87  (*mfnRect->fnYDiff)( (aBoundRectOfNewObj.*mfnRect->fnGetTop)(),
88  (aBoundRectOfListedObj.*mfnRect->fnGetTop)() );
89  if ( nTopDiff == 0 &&
90  ( ( mbR2L &&
91  ( (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() >
92  (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() ) ) ||
93  ( !mbR2L &&
94  ( (aBoundRectOfNewObj.*mfnRect->fnGetRight)() <
95  (aBoundRectOfListedObj.*mfnRect->fnGetRight)() ) ) ) )
96  {
97  return true;
98  }
99  else if ( nTopDiff > 0 )
100  {
101  return true;
102  }
103  }
104  else if ( ( mbR2L &&
105  ( (aBoundRectOfListedObj.*mfnRect->fnGetRight)() >
106  (aBoundRectOfNewObj.*mfnRect->fnGetRight)() ) ) ||
107  ( !mbR2L &&
108  ( (aBoundRectOfListedObj.*mfnRect->fnGetLeft)() <
109  (aBoundRectOfNewObj.*mfnRect->fnGetLeft)() ) ) )
110  {
111  return true;
112  }
113 
114  return false;
115  }
116  };
117 }
118 
120  mnPointCount( 0 )
121 {
122 }
123 
125 {
126 }
127 
128 void SwContourCache::ClrObject( sal_uInt16 nPos )
129 {
130  mnPointCount -= mvItems[ nPos ].mxTextRanger->GetPointCount();
131  mvItems.erase(mvItems.begin() + nPos);
132 }
133 
134 void ClrContourCache( const SdrObject *pObj )
135 {
136  if( pContourCache && pObj )
137  for( sal_uInt16 i = 0; i < pContourCache->GetCount(); ++i )
138  if( pObj == pContourCache->GetObject( i ) )
139  {
141  break;
142  }
143 }
144 
146 {
147  if( pContourCache )
148  {
149  pContourCache->mvItems.clear();
151  }
152 }
153 
154 // #i68520#
156  const SwRect &rLine,
157  const SwTextFrame* pFrame,
158  const tools::Long nXPos,
159  const bool bRight )
160 {
161  SwRect aRet;
162  const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat());
163  bool bHandleContour(pFormat->GetSurround().IsContour());
164 
165  if(!bHandleContour)
166  {
167  // RotateFlyFrame3: Object has no set contour, but for rotated
168  // FlyFrames we can create a 'default' contour to make text
169  // flow around the free, non-covered
170  const SwFlyFreeFrame* pSwFlyFreeFrame(dynamic_cast< const SwFlyFreeFrame* >(pAnchoredObj));
171 
172  if(nullptr != pSwFlyFreeFrame && pSwFlyFreeFrame->supportsAutoContour())
173  {
174  bHandleContour = true;
175  }
176  }
177 
178  if( bHandleContour &&
179  ( pAnchoredObj->DynCastFlyFrame() == nullptr ||
180  ( static_cast<const SwFlyFrame*>(pAnchoredObj)->Lower() &&
181  static_cast<const SwFlyFrame*>(pAnchoredObj)->Lower()->IsNoTextFrame() ) ) )
182  {
183  aRet = pAnchoredObj->GetObjRectWithSpaces();
184  if( aRet.IsOver( rLine ) )
185  {
186  if( !pContourCache )
188 
189  aRet = pContourCache->ContourRect(
190  pFormat, pAnchoredObj->GetDrawObj(), pFrame, rLine, nXPos, bRight );
191  }
192  else
193  aRet.Width( 0 );
194  }
195  else
196  {
197  aRet = pAnchoredObj->GetObjRectWithSpaces();
198  }
199 
200  return aRet;
201 }
202 
204  const SdrObject* pObj, const SwTextFrame* pFrame, const SwRect &rLine,
205  const tools::Long nXPos, const bool bRight )
206 {
207  SwRect aRet;
208  sal_uInt16 nPos = 0; // Search in the Cache
209  while( nPos < GetCount() && pObj != mvItems[ nPos ].mpSdrObj )
210  ++nPos;
211  if( GetCount() == nPos ) // Not found
212  {
213  if( GetCount() == POLY_CNT )
214  {
215  mnPointCount -= mvItems.back().mxTextRanger->GetPointCount();
216  mvItems.pop_back();
217  }
218  ::basegfx::B2DPolyPolygon aPolyPolygon;
219  std::optional<::basegfx::B2DPolyPolygon> pPolyPolygon;
220 
221  if ( auto pVirtFlyDrawObj = dynamic_cast< const SwVirtFlyDrawObj *>( pObj ) )
222  {
223  // GetContour() causes the graphic to be loaded, which may cause
224  // the graphic to change its size, call ClrObject()
225  tools::PolyPolygon aPoly;
226  if( !pVirtFlyDrawObj->GetFlyFrame()->GetContour( aPoly ) )
227  aPoly = tools::PolyPolygon( pVirtFlyDrawObj->
228  GetFlyFrame()->getFrameArea().SVRect() );
229  aPolyPolygon.clear();
230  aPolyPolygon.append(aPoly.getB2DPolyPolygon());
231  }
232  else
233  {
234  if( dynamic_cast< const E3dObject *>( pObj ) == nullptr )
235  {
236  aPolyPolygon = pObj->TakeXorPoly();
237  }
238 
239  pPolyPolygon = pObj->TakeContour();
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 ? &*pPolyPolygon : nullptr, 20,
246  o3tl::narrowing<sal_uInt16>(rLRSpace.GetLeft()), o3tl::narrowing<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  tools::Long nTmpTop = aRectFnSet.GetTop(rLine);
270  // fnGetBottom is top + height
271  tools::Long nTmpBottom = aRectFnSet.GetBottom(rLine);
272 
273  Range aRange( std::min( nTmpTop, nTmpBottom ), std::max( nTmpTop, nTmpBottom ) );
274 
275  std::deque<tools::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  const SwFlyFrame* pFly = pTmpAnchoredObj->DynCastFlyFrame();
496  if( pFly && mpCurrAnchoredObj != pTmpAnchoredObj )
497  {
498  // #i68520#
499  if( aRegion.GetOrigin().IsOver( pFly->getFrameArea() ) )
500  {
501  const SwFrameFormat *pFormat = pFly->GetFormat();
502  const SwFormatSurround &rSur = pFormat->GetSurround();
503  const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
504  // Only the ones who are opaque and more to the top
505  if( ! pFly->IsBackgroundTransparent() &&
506  css::text::WrapTextMode_THROUGH == rSur.GetSurround() &&
507  ( !rSur.IsAnchorOnly() ||
508  // #i68520#
509  GetMaster() == pFly->GetAnchorFrame() ||
510  ((RndStdIds::FLY_AT_PARA != rAnchor.GetAnchorId()) &&
511  (RndStdIds::FLY_AT_CHAR != rAnchor.GetAnchorId())
512  )
513  ) &&
514  // #i68520#
515  pTmpAnchoredObj->GetDrawObj()->GetLayer() != nHellId &&
516  nCurrOrd < pTmpAnchoredObj->GetDrawObj()->GetOrdNum()
517  )
518  {
519  // Except for the content is transparent
520  const SwNoTextFrame *pNoText =
521  pFly->Lower() && pFly->Lower()->IsNoTextFrame()
522  ? static_cast<const SwNoTextFrame*>(pFly->Lower())
523  : nullptr;
524  if ( !pNoText ||
525  (!pNoText->IsTransparent() && !rSur.IsContour()) )
526  {
527  bOpaque = true;
528  aRegion -= pFly->getFrameArea();
529  }
530  }
531  }
532  }
533  }
534  }
535 
536  Point aPos( rInf.GetPos().X(), rInf.GetPos().Y() + rInf.GetAscent() );
537  const Point aOldPos(rInf.GetPos());
538  rInf.SetPos( aPos );
539 
540  if( !bOpaque )
541  {
542  if( rInf.GetKern() )
543  rInf.GetFont()->DrawStretchText_( rInf );
544  else
545  rInf.GetFont()->DrawText_( rInf );
546  rInf.SetPos(aOldPos);
547  return;
548  }
549  else if( !aRegion.empty() )
550  {
551  // What a huge effort ...
552  SwSaveClip aClipVout( rInf.GetpOut() );
553  for( size_t i = 0; i < aRegion.size(); ++i )
554  {
555  SwRect &rRect = aRegion[i];
556  if( rRect != aRegion.GetOrigin() )
557  aClipVout.ChgClip( rRect );
558  if( rInf.GetKern() )
559  rInf.GetFont()->DrawStretchText_( rInf );
560  else
561  rInf.GetFont()->DrawText_( rInf );
562  }
563  }
564  rInf.SetPos(aOldPos);
565 }
566 
567 void SwTextFly::DrawFlyRect( OutputDevice* pOut, const SwRect &rRect )
568 {
569  SwRegionRects aRegion( rRect );
570  OSL_ENSURE( !m_bTopRule, "DrawFlyRect: Wrong TopRule" );
571  // #i68520#
572  const SwAnchoredObjList::size_type nCount( m_bOn ? GetAnchoredObjList()->size() : 0 );
573  if (nCount > 0)
574  {
576  for( SwAnchoredObjList::size_type i = 0; i < nCount; ++i )
577  {
578  // #i68520#
579  const SwAnchoredObject* pAnchoredObjTmp = (*mpAnchoredObjList)[i];
580  if (mpCurrAnchoredObj == pAnchoredObjTmp)
581  continue;
582 
583  // #i68520#
584  const SwFlyFrame* pFly = pAnchoredObjTmp->DynCastFlyFrame();
585  if (pFly)
586  {
587  // #i68520#
588  const SwFormatSurround& rSur = pAnchoredObjTmp->GetFrameFormat().GetSurround();
589 
590  // OD 24.01.2003 #106593# - correct clipping of fly frame area.
591  // Consider that fly frame background/shadow can be transparent
592  // and <SwAlignRect(..)> fly frame area
593  // #i47804# - consider transparent graphics
594  // and OLE objects.
595  bool bClipFlyArea =
596  ( ( css::text::WrapTextMode_THROUGH == rSur.GetSurround() )
597  // #i68520#
598  ? (pAnchoredObjTmp->GetDrawObj()->GetLayer() != nHellId)
599  : !rSur.IsContour() ) &&
600  !pFly->IsBackgroundTransparent() &&
601  ( !pFly->Lower() ||
602  !pFly->Lower()->IsNoTextFrame() ||
603  !static_cast<const SwNoTextFrame*>(pFly->Lower())->IsTransparent() );
604  if ( bClipFlyArea )
605  {
606  // #i68520#
607  SwRect aFly( pAnchoredObjTmp->GetObjRect() );
608  // OD 24.01.2003 #106593#
609  ::SwAlignRect( aFly, m_pPage->getRootFrame()->GetCurrShell(), pOut );
610  if( !aFly.IsEmpty() )
611  aRegion -= aFly;
612  }
613  }
614  }
615  }
616 
617  for( size_t i = 0; i < aRegion.size(); ++i )
618  {
619  pOut->DrawRect( aRegion[i].SVRect() );
620  }
621 }
622 
627 bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj,
628  const bool bInFootnote,
629  const bool bInFooterOrHeader )
630 {
631  // #i68520#
632  // <mpCurrAnchoredObj> is set, if <m_pCurrFrame> is inside a fly frame
633  if( _pAnchoredObj != mpCurrAnchoredObj )
634  {
635  // #i26945#
636  const SdrObject* pNew = _pAnchoredObj->GetDrawObj();
637  // #102344# Ignore connectors which have one or more connections
638  if (const SdrEdgeObj* pEdgeObj = dynamic_cast<const SdrEdgeObj*>(pNew))
639  {
640  if (pEdgeObj->GetConnectedNode(true) || pEdgeObj->GetConnectedNode(false))
641  {
642  return false;
643  }
644  }
645 
646  if( ( bInFootnote || bInFooterOrHeader ) && m_bTopRule )
647  {
648  // #i26945#
649  const SwFrameFormat& rFrameFormat = _pAnchoredObj->GetFrameFormat();
650  const SwFormatAnchor& rNewA = rFrameFormat.GetAnchor();
651  if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
652  {
653  if ( bInFootnote )
654  return false;
655 
656  if ( bInFooterOrHeader )
657  {
658  const SwFormatVertOrient& aVert( rFrameFormat.GetVertOrient() );
659  bool bVertPrt = aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
660  aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA;
661  if( bVertPrt )
662  return false;
663  }
664  }
665  }
666 
667  // #i68520#
668  // bEvade: consider pNew, if we are not inside a fly
669  // consider pNew, if pNew is lower of <mpCurrAnchoredObj>
670  bool bEvade = !mpCurrAnchoredObj ||
672 
673  if ( !bEvade )
674  {
675  // We are currently inside a fly frame and pNew is not
676  // inside this fly frame. We can do some more checks if
677  // we have to consider pNew.
678 
679  // If bTopRule is not set, we ignore the frame types.
680  // We directly check the z-order
681  if ( !m_bTopRule )
682  bEvade = true;
683  else
684  {
685  // Within chained Flys we only avoid Lower
686  // #i68520#
688  if ( !rChain.GetPrev() && !rChain.GetNext() )
689  {
690  // #i26945#
691  const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor();
692  // #i68520#
694 
695  // If <mpCurrAnchoredObj> is anchored as character, its content
696  // does not wrap around pNew
697  if (RndStdIds::FLY_AS_CHAR == rCurrA.GetAnchorId())
698  return false;
699 
700  // If pNew is anchored to page and <mpCurrAnchoredObj is not anchored
701  // to page, the content of <mpCurrAnchoredObj> does not wrap around pNew
702  // If both pNew and <mpCurrAnchoredObj> are anchored to page, we can do
703  // some more checks
704  if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
705  {
706  if (RndStdIds::FLY_AT_PAGE == rCurrA.GetAnchorId())
707  {
708  bEvade = true;
709  }
710  else
711  return false;
712  }
713  else if (RndStdIds::FLY_AT_PAGE == rCurrA.GetAnchorId())
714  return false; // Page anchored ones only avoid page anchored ones
715  else if (RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId())
716  bEvade = true; // Non-page anchored ones avoid frame anchored ones
717  else if( RndStdIds::FLY_AT_FLY == rCurrA.GetAnchorId() )
718  return false; // Frame anchored ones do not avoid paragraph anchored ones
719  // #i57062#
720  // In order to avoid loop situation, it's decided to adjust
721  // the wrapping behaviour of content of at-paragraph/at-character
722  // anchored objects to one in the page header/footer and
723  // the document body --> content of at-paragraph/at-character
724  // anchored objects doesn't wrap around each other.
725  else
726  return false;
727  }
728  }
729 
730  // But: we never avoid a subordinate one and additionally we only avoid when overlapping.
731  // #i68520#
732  bEvade &= ( mpCurrAnchoredObj->GetDrawObj()->GetOrdNum() < pNew->GetOrdNum() );
733  if( bEvade )
734  {
735  // #i68520#
736  const SwRect& aTmp( _pAnchoredObj->GetObjRectWithSpaces() );
737  if ( !aTmp.IsOver( mpCurrAnchoredObj->GetObjRectWithSpaces() ) )
738  bEvade = false;
739  }
740  }
741 
742  if ( bEvade )
743  {
744  // #i26945#
745  const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor();
746  OSL_ENSURE( RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(),
747  "Don't call GetTop with a FlyInContentFrame" );
748  if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
749  return true; // We always avoid page anchored ones
750 
751  // If Flys anchored at paragraph are caught in a FlyCnt, then
752  // their influence ends at the borders of the FlyCnt!
753  // If we are currently formatting the text of the FlyCnt, then
754  // it has to get out of the way of the Frame anchored at paragraph!
755  // m_pCurrFrame is the anchor of pNew?
756  // #i26945#
757  const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame();
758  if (pTmp == m_pCurrFrame)
759  return true;
760  if( pTmp->IsTextFrame() && ( pTmp->IsInFly() || pTmp->IsInFootnote() ) )
761  {
762  // #i26945#
763  Point aPos = _pAnchoredObj->GetObjRect().Pos();
764  pTmp = GetVirtualUpper( pTmp, aPos );
765  }
766  // #i26945#
767  // If <pTmp> is a text frame inside a table, take the upper
768  // of the anchor frame, which contains the anchor position.
769  else if ( pTmp->IsTextFrame() && pTmp->IsInTab() )
770  {
771  pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj)
772  ->GetAnchorFrameContainingAnchPos()->GetUpper();
773  }
774  // #i28701# - consider all objects in same context,
775  // if wrapping style is considered on object positioning.
776  // Thus, text will wrap around negative positioned objects.
777  // #i3317# - remove condition on checking,
778  // if wrappings style is considered on object positioning.
779  // Thus, text is wrapping around negative positioned objects.
780  // #i35640# - no consideration of negative
781  // positioned objects, if wrapping style isn't considered on
782  // object position and former text wrapping is applied.
783  // This condition is typically for documents imported from the
784  // OpenOffice.org file format.
789  {
790  return true;
791  }
792 
793  const SwFrame* pHeader = nullptr;
794  if (m_pCurrFrame->GetNext() != pTmp &&
796  // #i13832#, #i24135# wrap around objects in page header
798  nullptr != ( pHeader = pTmp->FindFooterOrHeader() ) &&
800  {
801  if( pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId() )
802  return true;
803 
804  // Compare indices:
805  // The Index of the other is retrieved from the anchor attr.
806  sal_uLong nTmpIndex = rNewA.GetContentAnchor()->nNode.GetIndex();
807  // Now check whether the current paragraph is before the anchor
808  // of the displaced object in the text, then we don't have to
809  // get out of its way.
810  // If possible determine Index via SwFormatAnchor because
811  // otherwise it's quite expensive.
812  if (ULONG_MAX == m_nCurrFrameNodeIndex)
814 
815  if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) || nTmpIndex < m_nCurrFrameNodeIndex)
816  return true;
817  }
818  }
819  }
820  return false;
821 }
822 
823 // #i68520#
825 {
826  OSL_ENSURE( m_pCurrFrame, "InitFlyList: No Frame, no FlyList" );
827  // #i68520#
828  OSL_ENSURE( !mpAnchoredObjList, "InitFlyList: FlyList already initialized" );
829 
830  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(m_pCurrFrame));
831 
832  const SwSortedObjs *pSorted = m_pPage->GetSortedObjs();
833  const size_t nCount = pSorted ? pSorted->size() : 0;
834  // --> #108724# Page header/footer content doesn't have to wrap around
835  // floating screen objects
836  // which was added simply to be compatible with MS Office.
837  // MSO still allows text to wrap around in-table-flies in headers/footers/footnotes
838  const bool bFooterHeader = nullptr != m_pCurrFrame->FindFooterOrHeader();
840  // #i40155# - check, if frame is marked not to wrap
841  const bool bAllowCompatWrap = m_pCurrFrame->IsInTab() && (bFooterHeader || m_pCurrFrame->IsInFootnote());
842  const bool bWrapAllowed = ( pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) ||
843  bAllowCompatWrap ||
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 tools::Long nRight = aRectFnSet.GetRight(aRect) - 1;
869  const tools::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  ( bAllowCompatWrap && !pAnchoredObj->GetFrameFormat().GetFollowTextFlow().GetValue() )
892  )
893  {
894  continue;
895  }
896 
897  const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
898  if ( nRight < aRectFnSet.GetLeft(aBound) ||
899  aRectFnSet.YDiff( aRectFnSet.GetTop(aRect),
900  aRectFnSet.GetBottom(aBound) ) > 0 ||
901  nLeft > aRectFnSet.GetRight(aBound) ||
902  aRectFnSet.GetHeight(aBound) >
903  2 * aRectFnSet.GetHeight(m_pPage->getFrameArea()) )
904  {
905  continue;
906  }
907 
908  // #i26945# - pass <pAnchoredObj> to method
909  // <GetTop(..)> instead of only the <SdrObject> instance of the
910  // anchored object
911  if (GetTop(pAnchoredObj, m_pCurrFrame->IsInFootnote(), bFooterHeader))
912  {
913  // OD 11.03.2003 #107862# - adjust insert position:
914  // overlapping objects should be sorted from left to right and
915  // inside left to right sorting from top to bottom.
916  // If objects on the same position are found, they are sorted
917  // on its width.
918  // #i68520#
919  {
920  SwAnchoredObjList::iterator aInsPosIter =
921  std::lower_bound( mpAnchoredObjList->begin(),
922  mpAnchoredObjList->end(),
923  pAnchoredObj,
924  AnchoredObjOrder( bR2L, aRectFnSet.FnRect() ) );
925 
926  mpAnchoredObjList->insert( aInsPosIter, pAnchoredObj );
927  }
928 
929  const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround();
930  // #i68520#
931  if ( rFlyFormat.IsAnchorOnly() &&
932  pAnchoredObj->GetAnchorFrame() == GetMaster() )
933  {
934  const SwFormatVertOrient &rTmpFormat =
935  pAnchoredObj->GetFrameFormat().GetVertOrient();
936  if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() )
937  m_nMinBottom = ( aRectFnSet.IsVert() && m_nMinBottom ) ?
938  std::min( m_nMinBottom, aBound.Left() ) :
939  std::max( m_nMinBottom, aRectFnSet.GetBottom(aBound) );
940  }
941 
942  m_bOn = true;
943  }
944  }
945  if( m_nMinBottom )
946  {
947  SwTwips nMax = aRectFnSet.GetPrtBottom(*m_pCurrFrame->GetUpper());
948  if( aRectFnSet.YDiff( m_nMinBottom, nMax ) > 0 )
949  m_nMinBottom = nMax;
950  }
951  }
952  else
953  {
954  // #i68520#
956  }
957 
958  // #i68520#
959  return mpAnchoredObjList.get();
960 }
961 
963 {
964  SwTwips nRet = 0;
965  const SwContentFrame *pLclMaster = GetMaster();
966  OSL_ENSURE(pLclMaster, "SwTextFly without master");
967  const SwSortedObjs *pDrawObj = pLclMaster ? pLclMaster->GetDrawObjs() : nullptr;
968  const size_t nCount = pDrawObj ? pDrawObj->size() : 0;
969  if( nCount )
970  {
971  SwTwips nEndOfFrame = m_pCurrFrame->getFrameArea().Bottom();
972  for( size_t i = 0; i < nCount; ++i )
973  {
974  SwAnchoredObject* pAnchoredObj = (*pDrawObj)[ i ];
975  const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround();
976  if( rFlyFormat.IsAnchorOnly() )
977  {
978  const SwFormatVertOrient &rTmpFormat =
979  pAnchoredObj->GetFrameFormat().GetVertOrient();
980  if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() )
981  {
982  const SwRect& aBound( pAnchoredObj->GetObjRectWithSpaces() );
983  if( aBound.Top() < nEndOfFrame )
984  nRet = std::max( nRet, SwTwips(aBound.Bottom()) );
985  }
986  }
987  }
988  SwTwips nMax = m_pCurrFrame->GetUpper()->getFrameArea().Top() +
990  if( nRet > nMax )
991  nRet = nMax;
992  }
993  return nRet;
994 }
995 
996 bool SwTextFly::ForEach( const SwRect &rRect, SwRect* pRect, bool bAvoid ) const
997 {
998  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(m_pCurrFrame));
999 
1000  // Optimization
1001  SwRectFnSet aRectFnSet(m_pCurrFrame);
1002 
1003  // tdf#127235 stop if the area is larger than the page
1004  if( aRectFnSet.GetHeight(m_pPage->getFrameArea()) < aRectFnSet.GetHeight(rRect))
1005  {
1006  // get the doc model description
1007  const SwPageDesc* pPageDesc = m_pPage->GetPageDesc();
1008 
1009  // if there is no next page style or it is the same as the current
1010  // => stop trying to place the frame (it would end in an infinite loop)
1011  if( pPageDesc &&
1012  ( !pPageDesc->GetFollow() || pPageDesc->GetFollow() == pPageDesc) )
1013  {
1014  return false;
1015  }
1016  }
1017 
1018  bool bRet = false;
1019  // #i68520#
1020  const SwAnchoredObjList::size_type nCount( m_bOn ? GetAnchoredObjList()->size() : 0 );
1021  if (nCount > 0)
1022  {
1023  for( SwAnchoredObjList::size_type i = 0; i < nCount; ++i )
1024  {
1025  // #i68520#
1026  const SwAnchoredObject* pAnchoredObj = (*mpAnchoredObjList)[i];
1027 
1028  SwRect aRect( pAnchoredObj->GetObjRectWithSpaces() );
1029 
1030  if( aRectFnSet.GetLeft(aRect) > aRectFnSet.GetRight(rRect) )
1031  break;
1032 
1033  // #i68520#
1034  if ( mpCurrAnchoredObj != pAnchoredObj && aRect.IsOver( rRect ) )
1035  {
1036  // #i68520#
1037  const SwFormat* pFormat( &(pAnchoredObj->GetFrameFormat()) );
1038  const SwFormatSurround &rSur = pFormat->GetSurround();
1039  if( bAvoid )
1040  {
1041  // If the text flows below, it has no influence on
1042  // formatting. In LineIter::DrawText() it is "just"
1043  // necessary to cleverly set the ClippingRegions
1044  const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
1045  if( ( css::text::WrapTextMode_THROUGH == rSur.GetSurround() &&
1046  ( !rSur.IsAnchorOnly() ||
1047  // #i68520#
1048  GetMaster() == pAnchoredObj->GetAnchorFrame() ||
1049  ((RndStdIds::FLY_AT_PARA != rAnchor.GetAnchorId()) &&
1050  (RndStdIds::FLY_AT_CHAR != rAnchor.GetAnchorId())) ) )
1051  || aRect.Top() == FAR_AWAY )
1052  continue;
1053  }
1054 
1055  // #i58642#
1056  // Compare <GetMaster()> instead of <m_pCurrFrame> with the
1057  // anchor frame of the anchored object, because a follow frame
1058  // has to ignore the anchored objects of its master frame.
1059  // Note: Anchored objects are always registered at the master
1060  // frame, exception are as-character anchored objects,
1061  // but these aren't handled here.
1062  // #i68520#
1063  if ( mbIgnoreCurrentFrame &&
1064  GetMaster() == pAnchoredObj->GetAnchorFrame() )
1065  continue;
1066 
1067  if( pRect )
1068  {
1069  // #i68520#
1070  SwRect aFly = AnchoredObjToRect( pAnchoredObj, rRect );
1071  if( aFly.IsEmpty() || !aFly.IsOver( rRect ) )
1072  continue;
1073  if( !bRet || (
1074  (!m_pCurrFrame->IsRightToLeft() &&
1075  ( aRectFnSet.GetLeft(aFly) <
1076  aRectFnSet.GetLeft(*pRect) ) ) ||
1078  ( aRectFnSet.GetRight(aFly) >
1079  aRectFnSet.GetRight(*pRect) ) ) ) )
1080  *pRect = aFly;
1081  if( rSur.IsContour() )
1082  {
1083  bRet = true;
1084  continue;
1085  }
1086  }
1087  bRet = true;
1088  break;
1089  }
1090  }
1091  }
1092 
1093  return bRet;
1094 }
1095 
1096 // #i68520#
1097 SwAnchoredObjList::size_type SwTextFly::GetPos( const SwAnchoredObject* pAnchoredObj ) const
1098 {
1099  SwAnchoredObjList::size_type nCount = GetAnchoredObjList()->size();
1100  SwAnchoredObjList::size_type nRet = 0;
1101  while ( nRet < nCount && pAnchoredObj != (*mpAnchoredObjList)[ nRet ] )
1102  ++nRet;
1103  return nRet;
1104 }
1105 
1106 // #i68520#
1108  SwAnchoredObjList::size_type nFlyPos,
1109  const SwRect &rLine ) const
1110 {
1111  // Usually the right margin is the right margin of the Printarea
1112  OSL_ENSURE( !m_pCurrFrame->IsVertical() || !m_pCurrFrame->IsSwapped(),
1113  "SwTextFly::CalcRightMargin with swapped frame" );
1114  SwRectFnSet aRectFnSet(m_pCurrFrame);
1115  // #118796# - correct determination of right of printing area
1116  SwTwips nRight = aRectFnSet.GetPrtRight(*m_pCurrFrame);
1117  SwTwips nFlyRight = aRectFnSet.GetRight(rFly);
1118  SwRect aLine( rLine );
1119  aRectFnSet.SetRight( aLine, nRight );
1120  aRectFnSet.SetLeft( aLine, aRectFnSet.GetLeft(rFly) );
1121 
1122  // It is possible that there is another object that is _above_ us
1123  // and protrudes into the same line.
1124  // Flys with run-through are invisible for those below, i.e., they
1125  // are ignored for computing the margins of other Flys.
1126  // 3301: pNext->getFrameArea().IsOver( rLine ) is necessary
1127  // #i68520#
1128  css::text::WrapTextMode eSurroundForTextWrap;
1129 
1130  bool bStop = false;
1131  // #i68520#
1132  SwAnchoredObjList::size_type nPos = 0;
1133 
1134  // #i68520#
1135  while( nPos < mpAnchoredObjList->size() && !bStop )
1136  {
1137  if( nPos == nFlyPos )
1138  {
1139  ++nPos;
1140  continue;
1141  }
1142  // #i68520#
1143  const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nPos++ ];
1144  if ( pNext == mpCurrAnchoredObj )
1145  continue;
1146  eSurroundForTextWrap = GetSurroundForTextWrap( pNext );
1147  if( css::text::WrapTextMode_THROUGH == eSurroundForTextWrap )
1148  continue;
1149 
1151  ( pNext, aLine, m_pCurrFrame, nFlyRight, true ) );
1152  SwTwips nTmpRight = aRectFnSet.GetRight(aTmp);
1153 
1154  // optimization:
1155  // Record in nNextTop at which Y-position frame related changes are
1156  // likely. This is so that, despite only looking at frames in the
1157  // current line height, for frames without wrap the line height is
1158  // incremented so that with a single line the lower border of the frame
1159  // (or possibly the upper border of another frame) is reached.
1160  // Especially in HTML documents there are often (dummy) paragraphs in
1161  // 2 pt font, and they used to only evade big frames after huge numbers
1162  // of empty lines.
1163  const tools::Long nTmpTop = aRectFnSet.GetTop(aTmp);
1164  if( aRectFnSet.YDiff( nTmpTop, aRectFnSet.GetTop(aLine) ) > 0 )
1165  {
1166  if( aRectFnSet.YDiff( m_nNextTop, nTmpTop ) > 0 )
1167  SetNextTop( nTmpTop ); // upper border of next frame
1168  }
1169  else if (!aRectFnSet.GetWidth(aTmp)) // typical for Objects with contour wrap
1170  { // For Objects with contour wrap that start before the current
1171  // line, and end below it, but do not actually overlap it, the
1172  // optimization has to be disabled, because the circumstances
1173  // can change in the next line.
1174  if( ! aRectFnSet.GetHeight(aTmp) ||
1175  aRectFnSet.YDiff( aRectFnSet.GetBottom(aTmp),
1176  aRectFnSet.GetTop(aLine) ) > 0 )
1177  SetNextTop( 0 );
1178  }
1179  if( aTmp.IsOver( aLine ) && nTmpRight > nFlyRight )
1180  {
1181  nFlyRight = nTmpRight;
1182  if( css::text::WrapTextMode_RIGHT == eSurroundForTextWrap ||
1183  css::text::WrapTextMode_PARALLEL == eSurroundForTextWrap )
1184  {
1185  // overrule the FlyFrame
1186  if( nRight > nFlyRight )
1187  nRight = nFlyRight;
1188  bStop = true;
1189  }
1190  }
1191  }
1192  aRectFnSet.SetRight( rFly, nRight );
1193 }
1194 
1195 // #i68520#
1197  SwAnchoredObjList::size_type nFlyPos,
1198  const SwRect &rLine ) const
1199 {
1200  OSL_ENSURE( !m_pCurrFrame->IsVertical() || !m_pCurrFrame->IsSwapped(),
1201  "SwTextFly::CalcLeftMargin with swapped frame" );
1202  SwRectFnSet aRectFnSet(m_pCurrFrame);
1203  // #118796# - correct determination of left of printing area
1204  SwTwips nLeft = aRectFnSet.GetPrtLeft(*m_pCurrFrame);
1205  const SwTwips nFlyLeft = aRectFnSet.GetLeft(rFly);
1206 
1207  if( nLeft > nFlyLeft )
1208  nLeft = rFly.Left();
1209 
1210  SwRect aLine( rLine );
1211  aRectFnSet.SetLeft( aLine, nLeft );
1212 
1213  // It is possible that there is another object that is _above_ us
1214  // and protrudes into the same line.
1215  // Flys with run-through are invisible for those below, i.e., they
1216  // are ignored for computing the margins of other Flys.
1217  // 3301: pNext->getFrameArea().IsOver( rLine ) is necessary
1218 
1219  // #i68520#
1220  SwAnchoredObjList::size_type nMyPos = nFlyPos;
1221  while( ++nFlyPos < mpAnchoredObjList->size() )
1222  {
1223  // #i68520#
1224  const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nFlyPos ];
1225  const SwRect& aTmp( pNext->GetObjRectWithSpaces() );
1226  if( aRectFnSet.GetLeft(aTmp) >= nFlyLeft )
1227  break;
1228  }
1229 
1230  while( nFlyPos )
1231  {
1232  if( --nFlyPos == nMyPos )
1233  continue;
1234  // #i68520#
1235  const SwAnchoredObject* pNext = (*mpAnchoredObjList)[ nFlyPos ];
1236  if( pNext == mpCurrAnchoredObj )
1237  continue;
1238  css::text::WrapTextMode eSurroundForTextWrap = GetSurroundForTextWrap( pNext );
1239  if( css::text::WrapTextMode_THROUGH == eSurroundForTextWrap )
1240  continue;
1241 
1243  (pNext, aLine, m_pCurrFrame, nFlyLeft, false) );
1244 
1245  if( aRectFnSet.GetLeft(aTmp) < nFlyLeft && aTmp.IsOver( aLine ) )
1246  {
1247  // #118796# - no '+1', because <..fnGetRight>
1248  // returns the correct value.
1249  SwTwips nTmpRight = aRectFnSet.GetRight(aTmp);
1250  if ( nLeft <= nTmpRight )
1251  nLeft = nTmpRight;
1252 
1253  break;
1254  }
1255  }
1256  aRectFnSet.SetLeft( rFly, nLeft );
1257 }
1258 
1259 // #i68520#
1261  const SwRect &rLine ) const
1262 {
1263  SwRectFnSet aRectFnSet(m_pCurrFrame);
1264 
1265  const tools::Long nXPos = m_pCurrFrame->IsRightToLeft() ?
1266  rLine.Right() :
1267  aRectFnSet.GetLeft(rLine);
1268 
1269  SwRect aFly = mbIgnoreContour ?
1270  pAnchoredObj->GetObjRectWithSpaces() :
1271  SwContourCache::CalcBoundRect(pAnchoredObj, rLine, m_pCurrFrame,
1272  nXPos, !m_pCurrFrame->IsRightToLeft());
1273 
1274  if( !aFly.Width() )
1275  return aFly;
1276 
1277  // so the line may grow up to the lower edge of the frame
1278  SetNextTop( aRectFnSet.GetBottom(aFly) );
1279  SwAnchoredObjList::size_type nFlyPos = GetPos( pAnchoredObj );
1280 
1281  // LEFT and RIGHT, we grow the rectangle.
1282  // We have some problems, when several frames are to be seen.
1283  // At the moment, only the easier case is assumed:
1284  // + LEFT means that the text must flow on the left of the frame,
1285  // that is the frame expands to the right edge of the print area
1286  // or to the next frame.
1287  // + RIGHT is the opposite.
1288  // Otherwise the set distance between text and frame is always
1289  // added up.
1290  switch( GetSurroundForTextWrap( pAnchoredObj ) )
1291  {
1292  case css::text::WrapTextMode_LEFT :
1293  {
1294  CalcRightMargin( aFly, nFlyPos, rLine );
1295  break;
1296  }
1297  case css::text::WrapTextMode_RIGHT :
1298  {
1299  CalcLeftMargin( aFly, nFlyPos, rLine );
1300  break;
1301  }
1302  case css::text::WrapTextMode_NONE :
1303  {
1304  CalcRightMargin( aFly, nFlyPos, rLine );
1305  CalcLeftMargin( aFly, nFlyPos, rLine );
1306  break;
1307  }
1308  default:
1309  break;
1310  }
1311  return aFly;
1312 }
1313 
1314 // #i68520#
1315 
1316 // Wrap only on sides with at least 2cm space for the text
1317 #define TEXT_MIN 1134
1318 
1319 // MS Word wraps on sides with even less space (value guessed).
1320 #define TEXT_MIN_SMALL 300
1321 
1322 // Wrap on both sides up to a frame width of 1.5cm
1323 #define FRAME_MAX 850
1324 
1325 css::text::WrapTextMode SwTextFly::GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const
1326 {
1327  const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat());
1328  const SwFormatSurround &rFlyFormat = pFormat->GetSurround();
1329  css::text::WrapTextMode eSurroundForTextWrap = rFlyFormat.GetSurround();
1330 
1331  if( rFlyFormat.IsAnchorOnly() && pAnchoredObj->GetAnchorFrame() != GetMaster() )
1332  {
1333  const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
1334  if ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) ||
1335  (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()))
1336  {
1337  return css::text::WrapTextMode_NONE;
1338  }
1339  }
1340 
1341  // in cause of run-through and nowrap ignore smartly
1342  if( css::text::WrapTextMode_THROUGH == eSurroundForTextWrap ||
1343  css::text::WrapTextMode_NONE == eSurroundForTextWrap )
1344  return eSurroundForTextWrap;
1345 
1346  // left is left and right is right
1347  if (m_pCurrFrame->IsRightToLeft())
1348  {
1349  if ( css::text::WrapTextMode_LEFT == eSurroundForTextWrap )
1350  eSurroundForTextWrap = css::text::WrapTextMode_RIGHT;
1351  else if ( css::text::WrapTextMode_RIGHT == eSurroundForTextWrap )
1352  eSurroundForTextWrap = css::text::WrapTextMode_LEFT;
1353  }
1354 
1355  // "ideal page wrap":
1356  if ( css::text::WrapTextMode_DYNAMIC == eSurroundForTextWrap )
1357  {
1358  SwRectFnSet aRectFnSet(m_pCurrFrame);
1359  const tools::Long nCurrLeft = aRectFnSet.GetPrtLeft(*m_pCurrFrame);
1360  const tools::Long nCurrRight = aRectFnSet.GetPrtRight(*m_pCurrFrame);
1361  const SwRect& aRect( pAnchoredObj->GetObjRectWithSpaces() );
1362  tools::Long nFlyLeft = aRectFnSet.GetLeft(aRect);
1363  tools::Long nFlyRight = aRectFnSet.GetRight(aRect);
1364 
1365  if ( nFlyRight < nCurrLeft || nFlyLeft > nCurrRight )
1366  eSurroundForTextWrap = css::text::WrapTextMode_PARALLEL;
1367  else
1368  {
1369  tools::Long nLeft = nFlyLeft - nCurrLeft;
1370  tools::Long nRight = nCurrRight - nFlyRight;
1371  if( nFlyRight - nFlyLeft > FRAME_MAX )
1372  {
1373  if( nLeft < nRight )
1374  nLeft = 0;
1375  else
1376  nRight = 0;
1377  }
1378  const int textMin = GetMaster()->GetDoc()
1381 
1382  // In case there is no space on either side, then css::text::WrapTextMode_PARALLEL
1383  // gives the same result when doing the initial layout or a layout
1384  // update after editing, so prefer that over css::text::WrapTextMode_NONE.
1385  if (nLeft == 0 && nRight == 0)
1386  return css::text::WrapTextMode_PARALLEL;
1387 
1388  if( nLeft < textMin )
1389  nLeft = 0;
1390  if( nRight < textMin )
1391  nRight = 0;
1392  if( nLeft )
1393  eSurroundForTextWrap = nRight ? css::text::WrapTextMode_PARALLEL : css::text::WrapTextMode_LEFT;
1394  else
1395  eSurroundForTextWrap = nRight ? css::text::WrapTextMode_RIGHT: css::text::WrapTextMode_NONE;
1396  }
1397  }
1398 
1399  return eSurroundForTextWrap;
1400 }
1401 
1402 bool SwTextFly::IsAnyFrame( const SwRect &rLine ) const
1403 {
1404 
1405  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(m_pCurrFrame));
1406 
1407  OSL_ENSURE( m_bOn, "IsAnyFrame: Why?" );
1408 
1409  return ForEach( rLine, nullptr, false );
1410 }
1411 
1412 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwAnchoredObjList * GetAnchoredObjList() const
Definition: txtfly.hxx:301
bool GetValue() const
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:548
void SetTop(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1387
vcl::Region GetClipRegion() const
bool IsContour() const
Definition: fmtsrnd.hxx:53
void SetNextTop(tools::Long nNew) const
Definition: txtfly.hxx:351
Base class of the Writer layout elements.
Definition: frame.hxx:315
virtual basegfx::B2DPolyPolygon TakeXorPoly() const
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:158
virtual SwRect GetObjRect() const =0
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1381
sal_uLong GetIndex() const
Definition: node.hxx:291
void Right(const tools::Long nRight)
Definition: swrect.hxx:199
bool IsFollow() const
Definition: flowfrm.hxx:166
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2877
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:565
const SwRect & GetOrigin() const
Definition: swregion.hxx:47
bool IsInDocBody() const
Definition: frame.hxx:944
tools::Long GetPrtRight(const SwFrame &rFrame) const
Definition: frame.hxx:1413
bool IsInFly() const
Definition: frame.hxx:962
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:3593
sal_uInt16 GetLower() const
tools::Long m_nMinBottom
Definition: txtfly.hxx:127
vcl::RenderContext * GetpOut() const
Definition: drawfont.hxx:187
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:252
bool IsSwapped() const
Definition: txtfrm.hxx:535
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
void Left(const tools::Long nLeft)
Definition: swrect.hxx:194
SwNodeIndex nNode
Definition: pam.hxx:37
void ClrObject(sal_uInt16 nPos)
Definition: txtfly.cxx:128
bool IsInFootnote() const
Definition: frame.hxx:950
SwRectFn FnRect() const
Definition: frame.hxx:1370
#define TEXT_MIN_SMALL
Definition: txtfly.cxx:1320
sal_uIntPtr sal_uLong
long Long
tools::Long GetRight() const
const SwRect & getFramePrintArea() const
Definition: frame.hxx:181
void DrawFlyRect(OutputDevice *pOut, const SwRect &rRect)
Two subtleties needs to be mentioned:
Definition: txtfly.cxx:567
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:824
#define POLY_CNT
Definition: txtfly.hxx:46
void SetPos(const Point &rNew)
Definition: drawfont.hxx:399
#define TEXT_MIN
Definition: txtfly.cxx:1317
sal_uInt16 GetAscent() const
Definition: drawfont.hxx:301
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:1368
void Pos(const Point &rNew)
Definition: swrect.hxx:168
bool IsBackgroundTransparent() const
SwFlyFrame::IsBackgroundTransparent.
Definition: paintfrm.cxx:3816
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
tools::Rectangle GetBoundRect() const
tools::Long mnPointCount
Definition: txtfly.hxx:61
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:55
SwTwips CalcMinBottom() const
Definition: txtfly.cxx:962
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:155
const SwTextFrame * m_pMaster
Definition: txtfly.hxx:124
SwRectGet fnGetRight
Definition: frame.hxx:1295
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1378
#define SAL_MAX_UINT32
void SetBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1388
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.
void SwAlignRect(SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext *pRenderContext)
Function is also used outside this file.
Definition: paintfrm.cxx:1124
const SwRect & getFrameArea() const
Definition: frame.hxx:180
bool IsInTab() const
Definition: frame.hxx:956
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:1196
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:3607
bool IsTextFrame() const
Definition: frame.hxx:1235
bool IsAnchorOnly() const
Definition: fmtsrnd.hxx:52
tools::Long GetPrtLeft(const SwFrame &rFrame) const
Definition: frame.hxx:1412
void Width(tools::Long nNew)
Definition: swrect.hxx:186
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
sal_uLong m_nCurrFrameNodeIndex
Stores the upper edge of the "next" frame.
Definition: txtfly.hxx:129
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1112
tools::Long m_nNextTop
Definition: txtfly.hxx:128
void DrawTextOpaque(SwDrawTextInfo &rInf)
This method is called by DrawText().
Definition: txtfly.cxx:446
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1380
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2674
#define POLY_MAX
Definition: txtfly.hxx:48
bool IsEmpty() const
Definition: swrect.hxx:284
void ClrContourCache(const SdrObject *pObj)
Definition: txtfly.cxx:134
void DrawRect(const tools::Rectangle &rRect)
const OUString & GetText() const
Definition: drawfont.hxx:218
Base class for various Writer styles.
Definition: format.hxx:46
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:457
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:288
const SwFormatFollowTextFlow & GetFollowTextFlow(bool=true) const
Style of a layout element.
Definition: frmfmt.hxx:59
const SdrObject * GetDrawObj() const
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:132
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1411
bool IsClipRegion() const
static SwRect CalcBoundRect(const SwAnchoredObject *pAnchoredObj, const SwRect &rLine, const SwTextFrame *pFrame, const tools::Long nXPos, const bool bRight)
Computes the rectangle that will cover the object in the given line.
Definition: txtfly.cxx:155
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
size_t size() const
Definition: sortedobjs.cxx:43
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:143
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1383
const sal_Unicode CH_BLANK
Definition: swfont.hxx:42
FlyAnchors.
Definition: fmtanchr.hxx:34
tools::Long GetLeft() const
void SetRight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1390
virtual const SwFlyFrame * DynCastFlyFrame() const
SwLayoutFrame * GetUpper()
Definition: frame.hxx:679
const SwRect & GetObjRectWithSpaces() const
method to determine object area inclusive its spacing
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:627
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:1260
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1424
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:1107
void SSize(const Size &rNew)
Definition: swrect.hxx:177
bool IsTransparent() const
Definition: notxtfrm.cxx:1418
sal_uInt16 GetCount() const
Definition: txtfly.hxx:70
tools::Long SwTwips
Definition: swtypes.hxx:52
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:267
SwTextFly()
Definition: txtfly.cxx:306
bool m_bOn
Definition: txtfly.hxx:131
SwRectGet fnGetLeft
Definition: frame.hxx:1294
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:1097
void SetTopAndHeight(SwRect &rRect, tools::Long nTop, tools::Long nHeight) const
Definition: frame.hxx:1429
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:208
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:76
tools::Long GetSpace() const
Definition: drawfont.hxx:327
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:3561
const SwTextFrame * GetMaster() const
Definition: txtfly.hxx:341
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
::basegfx::B2DPolyPolygon getB2DPolyPolygon() const
virtual SwFrameFormat & GetFrameFormat()=0
const SwPageFrame * m_pPage
Definition: txtfly.hxx:121
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:738
bool supportsAutoContour() const
Definition: flylay.cxx:301
const Point & GetPos() const
Definition: drawfont.hxx:197
TextFrameIndex GetLen() const
Definition: drawfont.hxx:270
bool IsNoTextFrame() const
Definition: frame.hxx:1239
const Size & GetSize() const
Definition: drawfont.hxx:244
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
bool IsRightToLeft() const
Definition: frame.hxx:988
~SwTextFly()
Definition: txtfly.cxx:349
SwRect ContourRect(const SwFormat *pFormat, const SdrObject *pObj, const SwTextFrame *pFrame, const SwRect &rLine, const tools::Long nXPos, const bool bRight)
Definition: txtfly.cxx:203
void Top(const tools::Long nTop)
Definition: swrect.hxx:203
bool ForEach(const SwRect &rRect, SwRect *pRect, bool bAvoid) const
Look for the first object which overlaps with the rectangle.
Definition: txtfly.cxx:996
const SwFrame * GetVirtualUpper(const SwFrame *pFrame, const Point &rPos)
Provides the Upper of an anchor in paragraph-bound objects.
Definition: frmtool.cxx:3529
css::text::WrapTextMode GetSurroundForTextWrap(const SwAnchoredObject *pAnchoredObj) const
Definition: txtfly.cxx:1325
#define FRAME_MAX
Definition: txtfly.cxx:1323
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:54
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
vcl::RenderContext & GetOut() const
Definition: drawfont.hxx:182
#define FAR_AWAY
Definition: frmtool.hxx:53
tools::Long GetKern() const
Definition: drawfont.hxx:322
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:58
bool IsVertical() const
Definition: frame.hxx:974
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1379
void SetLeft(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1389
SwDoc & GetDoc()
Definition: txtfrm.hxx:460
TextFrameIndex GetIdx() const
Definition: drawfont.hxx:265
bool IsOutside() const
Definition: fmtsrnd.hxx:54
const SwFrame * GetAnchorFrame() const
SwOperator fnYDiff
Definition: frame.hxx:1338
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:207
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
SwRootFrame * getRootFrame()
Definition: frame.hxx:680
sal_uInt16 nPos
sal_uInt16 GetUpper() const
SwRectGet fnGetTop
Definition: frame.hxx:1292
SwFrame * GetNext()
Definition: frame.hxx:677
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74