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