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