LibreOffice Module sw (master)  1
tocntntanchoredobjectposition.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 
21 #include <anchoredobject.hxx>
22 #include <frame.hxx>
23 #include <txtfrm.hxx>
24 #include <pagefrm.hxx>
25 #include <sectfrm.hxx>
26 #include <tabfrm.hxx>
27 #include <rootfrm.hxx>
28 #include <viewopt.hxx>
29 #include <viewsh.hxx>
30 #include <frmfmt.hxx>
31 #include <fmtsrnd.hxx>
32 #include <fmtfsize.hxx>
33 #include <fmtanchr.hxx>
34 #include <fmtornt.hxx>
35 #include <editeng/lrspitem.hxx>
36 #include <editeng/ulspitem.hxx>
37 #include <svx/svdobj.hxx>
39 #include <frmatr.hxx>
41 #include <sortedobjs.hxx>
42 #include <textboxhelper.hxx>
43 
44 using namespace objectpositioning;
45 using namespace ::com::sun::star;
46 
48  : SwAnchoredObjectPosition ( _rDrawObj ),
49  mpVertPosOrientFrame( nullptr ),
50  // #i26791#
51  maOffsetToFrameAnchorPos( Point() ),
52  mbAnchorToChar ( false ),
53  mpToCharOrientFrame( nullptr ),
54  mpToCharRect( nullptr ),
55  // #i22341#
56  mnToCharTopOfLine( 0 )
57 {}
58 
60 {}
61 
63 {
64  return mbAnchorToChar;
65 }
66 
68 {
69  return mpToCharOrientFrame;
70 }
71 
73 {
74  return mpToCharRect;
75 }
76 
77 // #i22341#
79 {
80  return mnToCharTopOfLine;
81 }
82 
84 {
85  OSL_ENSURE( dynamic_cast<const SwTextFrame*>( &GetAnchorFrame()) != nullptr ,
86  "SwToContentAnchoredObjectPosition::GetAnchorTextFrame() - wrong anchor frame type" );
87 
88  return static_cast<SwTextFrame&>(GetAnchorFrame());
89 }
90 
91 // #i23512#
92 static bool lcl_DoesVertPosFits( const SwTwips _nRelPosY,
93  const SwTwips _nAvail,
94  const SwLayoutFrame* _pUpperOfOrientFrame,
95  const bool _bBrowse,
96  const bool _bGrowInTable,
97  SwLayoutFrame*& _orpLayoutFrameToGrow )
98 {
99  bool bVertPosFits = false;
100 
101  if ( _nRelPosY <= _nAvail )
102  {
103  bVertPosFits = true;
104  }
105  else if ( _bBrowse )
106  {
107  if ( _pUpperOfOrientFrame->IsInSct() )
108  {
109  SwSectionFrame* pSctFrame =
110  const_cast<SwSectionFrame*>(_pUpperOfOrientFrame->FindSctFrame());
111  bVertPosFits = pSctFrame->GetUpper()->Grow( _nRelPosY - _nAvail, true ) > 0;
112  // Note: do not provide a layout frame for a grow.
113  }
114  else
115  {
116  bVertPosFits = const_cast<SwLayoutFrame*>(_pUpperOfOrientFrame)->
117  Grow( _nRelPosY - _nAvail, true ) > 0;
118  if ( bVertPosFits )
119  _orpLayoutFrameToGrow = const_cast<SwLayoutFrame*>(_pUpperOfOrientFrame);
120  }
121  }
122  else if ( _pUpperOfOrientFrame->IsInTab() && _bGrowInTable )
123  {
124  // #i45085# - check, if upper frame would grow the
125  // expected amount of twips.
126  const SwTwips nTwipsGrown = const_cast<SwLayoutFrame*>(_pUpperOfOrientFrame)->
127  Grow( _nRelPosY - _nAvail, true );
128  bVertPosFits = ( nTwipsGrown == ( _nRelPosY - _nAvail ) );
129  if ( bVertPosFits )
130  _orpLayoutFrameToGrow = const_cast<SwLayoutFrame*>(_pUpperOfOrientFrame);
131  }
132 
133  return bVertPosFits;
134 }
135 
137 {
138  // get format of object
139  const SwFrameFormat& rFrameFormat = GetFrameFormat();
140 
141  // declare and set <pFooter> to footer frame, if object is anchored
142  // at a frame belonging to the footer.
143  const SwFrame* pFooter = GetAnchorFrame().FindFooterOrHeader();
144  if ( pFooter && !pFooter->IsFooterFrame() )
145  pFooter = nullptr;
146 
147  // declare and set <bBrowse> to true, if document is in browser mode and
148  // object is anchored at the body, but not at frame belonging to a table.
149  bool bBrowse = GetAnchorFrame().IsInDocBody() && !GetAnchorFrame().IsInTab();
150  if( bBrowse )
151  {
153  if( !pSh || !pSh->GetViewOptions()->getBrowseMode() )
154  bBrowse = false;
155  }
156 
157  // determine left/right and its upper/lower spacing.
158  const SvxLRSpaceItem &rLR = rFrameFormat.GetLRSpace();
159  const SvxULSpaceItem &rUL = rFrameFormat.GetULSpace();
160 
161  // determine, if object has no surrounding.
162  const SwFormatSurround& rSurround = rFrameFormat.GetSurround();
163  const bool bNoSurround = rSurround.GetSurround() == css::text::WrapTextMode_NONE;
164  const bool bWrapThrough = rSurround.GetSurround() == css::text::WrapTextMode_THROUGH;
165 
166  // new class <SwEnvironmentOfAnchoredObject>
168 
169  // #i18732# - grow only, if object has to follow the text flow
170  const bool bGrow = DoesObjFollowsTextFlow() &&
171  ( !GetAnchorFrame().IsInTab() ||
172  !rFrameFormat.GetFrameSize().GetHeightPercent() );
173 
174  // get text frame the object is anchored at
175  const SwTextFrame& rAnchorTextFrame = GetAnchorTextFrame();
176  SwRectFnSet aRectFnSet(&rAnchorTextFrame);
177 
178  const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() );
179 
180  // local variable keeping the calculated relative position; initialized with
181  // current relative position.
182  // #i26791# - use new object instance of <SwAnchoredObject>
183  Point aRelPos( GetAnchoredObj().GetCurrRelPos() );
184 
185  SwTwips nRelDiff = 0;
186 
187  bool bMoveable = rAnchorTextFrame.IsMoveable();
188 
189  // determine frame the object position has to be oriented at.
190  const SwTextFrame* pOrientFrame = &rAnchorTextFrame;
191  const SwTextFrame* pAnchorFrameForVertPos;
192  {
193  // if object is at-character anchored, determine character-rectangle
194  // and frame, position has to be oriented at.
195  mbAnchorToChar = (RndStdIds::FLY_AT_CHAR == rFrameFormat.GetAnchor().GetAnchorId());
196  if ( mbAnchorToChar )
197  {
198  const SwFormatAnchor& rAnch = rFrameFormat.GetAnchor();
199  // #i26791# - use new object instance of <SwAnchoredObject>
200  // Due to table break algorithm the character
201  // rectangle can have no height. Thus, check also the width
202  if ( ( !GetAnchoredObj().GetLastCharRect().Height() &&
203  !GetAnchoredObj().GetLastCharRect().Width() ) ||
204  !GetAnchoredObj().GetLastTopOfLine() )
205  {
207  // Due to table break algorithm the character
208  // rectangle can have no height. Thus, check also the width
209  if ( ( !GetAnchoredObj().GetLastCharRect().Height() &&
210  !GetAnchoredObj().GetLastCharRect().Width() ) ||
211  !GetAnchoredObj().GetLastTopOfLine() )
212  {
213  // Get default for <mpVertPosOrientFrame>, if it's not set.
214  if ( !mpVertPosOrientFrame )
215  {
216  mpVertPosOrientFrame = rAnchorTextFrame.GetUpper();
217  }
218  return;
219  }
220  }
222  // #i22341# - get top of line, in which the anchor character is.
224  pOrientFrame = &(const_cast<SwTextFrame&>(rAnchorTextFrame).GetFrameAtOfst(
225  rAnchorTextFrame.MapModelToViewPos(*rAnch.GetContentAnchor())));
226  mpToCharOrientFrame = pOrientFrame;
227  }
228  }
229  aRectFnSet.Refresh(pOrientFrame);
230 
231  // determine vertical position
232  {
233 
234  // determine vertical positioning and alignment attributes
235  SwFormatVertOrient aVert( rFrameFormat.GetVertOrient() );
236 
237  // #i18732# - determine layout frame for vertical
238  // positions aligned to 'page areas'.
239  const SwLayoutFrame& rPageAlignLayFrame =
240  aEnvOfObj.GetVertEnvironmentLayoutFrame( *pOrientFrame );
241 
242  if ( aVert.GetVertOrient() != text::VertOrientation::NONE )
243  {
244  // #i18732# - adjustments for follow text flow or not
245  // AND vertical alignment at 'page areas'.
246  SwTwips nAlignAreaHeight;
247  SwTwips nAlignAreaOffset;
248  GetVertAlignmentValues( *pOrientFrame, rPageAlignLayFrame,
249  aVert.GetRelationOrient(),
250  nAlignAreaHeight, nAlignAreaOffset );
251 
252  // determine relative vertical position
253  SwTwips nRelPosY = nAlignAreaOffset;
254  const SwTwips nObjHeight = aRectFnSet.GetHeight(aObjBoundRect);
255  const SwTwips nUpperSpace = aRectFnSet.IsVert()
256  ? ( aRectFnSet.IsVertL2R()
257  ? rLR.GetLeft()
258  : rLR.GetRight() )
259  : rUL.GetUpper();
260  // --> OD 2009-08-31 #monglianlayout#
261  const SwTwips nLowerSpace = aRectFnSet.IsVert()
262  ? ( aRectFnSet.IsVertL2R()
263  ? rLR.GetLeft()
264  : rLR.GetRight() )
265  : rUL.GetLower();
266  switch ( aVert.GetVertOrient() )
267  {
268  case text::VertOrientation::CHAR_BOTTOM:
269  {
270  if ( mbAnchorToChar )
271  {
272  // bottom (to character anchored)
273  nRelPosY += nAlignAreaHeight + nUpperSpace;
274  if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
275  {
276  nRelPosY += nObjHeight;
277  }
278  break;
279  }
280  [[fallthrough]];
281  }
282  case text::VertOrientation::TOP:
283  {
284  // #i22341# - special case for vertical
285  // alignment at top of line
286  if ( mbAnchorToChar &&
287  aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
288  {
289  nRelPosY -= (nObjHeight + nLowerSpace);
290  }
291  else
292  {
293  nRelPosY += nUpperSpace;
294  }
295  }
296  break;
297  // #i22341#
298  case text::VertOrientation::LINE_TOP:
299  {
300  if ( mbAnchorToChar &&
301  aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
302  {
303  nRelPosY -= (nObjHeight + nLowerSpace);
304  }
305  else
306  {
307  OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
308  }
309  }
310  break;
311  case text::VertOrientation::CENTER:
312  {
313  nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2);
314  }
315  break;
316  // #i22341#
317  case text::VertOrientation::LINE_CENTER:
318  {
319  if ( mbAnchorToChar &&
320  aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
321  {
322  nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2);
323  }
324  else
325  {
326  OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
327  }
328  }
329  break;
330  case text::VertOrientation::BOTTOM:
331  {
332  if ( ( aVert.GetRelationOrient() == text::RelOrientation::FRAME ||
333  aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
334  bNoSurround )
335  {
336  // bottom (aligned to 'paragraph areas')
337  nRelPosY += nAlignAreaHeight + nUpperSpace;
338  }
339  else
340  {
341  // #i22341# - special case for vertical
342  // alignment at top of line
343  if ( mbAnchorToChar &&
344  aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
345  {
346  nRelPosY += nUpperSpace;
347  }
348  else
349  {
350  nRelPosY += nAlignAreaHeight -
351  ( nObjHeight + nLowerSpace );
352  }
353  }
354  }
355  break;
356  // #i22341#
357  case text::VertOrientation::LINE_BOTTOM:
358  {
359  if ( mbAnchorToChar &&
360  aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
361  {
362  nRelPosY += nUpperSpace;
363  }
364  else
365  {
366  OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
367  }
368  }
369  break;
370  default:
371  break;
372  }
373 
374  // adjust relative position by distance between anchor frame and
375  // the frame, the object is oriented at.
376  // #i28701# - correction: adjust relative position,
377  // only if the floating screen object has to follow the text flow.
378  if ( DoesObjFollowsTextFlow() && pOrientFrame != &rAnchorTextFrame )
379  {
380  // #i11860# - use new method <GetTopForObjPos>
381  // to get top of frame for object positioning.
382  const SwTwips nTopOfOrient = GetTopForObjPos( *pOrientFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
383  nRelPosY += aRectFnSet.YDiff( nTopOfOrient,
384  GetTopForObjPos( rAnchorTextFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() ) );
385  }
386 
387  // #i42124# - capture object inside vertical
388  // layout environment.
389  {
390  const SwTwips nTopOfAnch =
391  GetTopForObjPos( *pOrientFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
392  const SwLayoutFrame& rVertEnvironLayFrame =
394  *(pOrientFrame->GetUpper()) );
395  const bool bCheckBottom = !DoesObjFollowsTextFlow();
396  nRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
397  rVertEnvironLayFrame, nRelPosY,
399  bCheckBottom );
400  }
401 
402  // keep calculated relative vertical position - needed for filters
403  // (including the xml-filter)
404  {
405  // determine position
406  SwTwips nAttrRelPosY = nRelPosY - nAlignAreaOffset;
407  // set
408  if ( nAttrRelPosY != aVert.GetPos() )
409  {
410  aVert.SetPos( nAttrRelPosY );
411  const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
412  const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr( aVert );
413  const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
414  }
415  }
416 
417  // determine absolute 'vertical' position, depending on layout-direction
418  // #i26791# - determine offset to 'vertical' frame
419  // anchor position, depending on layout-direction
420  if ( aRectFnSet.IsVert() )
421  {
422  aRelPos.setX( nRelPosY );
423  maOffsetToFrameAnchorPos.setX( nAlignAreaOffset );
424  }
425  else
426  {
427  aRelPos.setY( nRelPosY );
428  maOffsetToFrameAnchorPos.setY( nAlignAreaOffset );
429  }
430  }
431 
432  // Determine upper of frame vertical position is oriented at.
433  // #i28701# - determine 'virtual' anchor frame.
434  // This frame is used in the following instead of the 'real' anchor
435  // frame <rAnchorTextFrame> for the 'vertical' position in all cases.
436  const SwLayoutFrame* pUpperOfOrientFrame = nullptr;
437  {
438  // #i28701# - As long as the anchor frame is on the
439  // same page as <pOrientFrame> and the vertical position isn't aligned
440  // automatic at the anchor character or the top of the line of the
441  // anchor character, the anchor frame determines the vertical position.
442  if ( &rAnchorTextFrame == pOrientFrame ||
443  ( rAnchorTextFrame.FindPageFrame() == pOrientFrame->FindPageFrame() &&
444  aVert.GetVertOrient() == text::VertOrientation::NONE &&
445  aVert.GetRelationOrient() != text::RelOrientation::CHAR &&
446  aVert.GetRelationOrient() != text::RelOrientation::TEXT_LINE ) )
447  {
448  pUpperOfOrientFrame = rAnchorTextFrame.GetUpper();
449  pAnchorFrameForVertPos = &rAnchorTextFrame;
450  }
451  else
452  {
453  pUpperOfOrientFrame = pOrientFrame->GetUpper();
454  pAnchorFrameForVertPos = pOrientFrame;
455  }
456  }
457 
458  // ignore one-column sections.
459  // #i23512# - correction: also ignore one-columned
460  // sections with footnotes/endnotes
461  if ( pUpperOfOrientFrame->IsInSct() )
462  {
463  const SwSectionFrame* pSctFrame = pUpperOfOrientFrame->FindSctFrame();
464  const bool bIgnoreSection = pUpperOfOrientFrame->IsSctFrame() ||
465  ( pSctFrame->Lower()->IsColumnFrame() &&
466  !pSctFrame->Lower()->GetNext() );
467  if ( bIgnoreSection )
468  pUpperOfOrientFrame = pSctFrame->GetUpper();
469  }
470 
471  if ( aVert.GetVertOrient() == text::VertOrientation::NONE )
472  {
473  // local variable <nRelPosY> for calculation of relative vertical
474  // distance to anchor.
475  SwTwips nRelPosY = 0;
476  // #i26791# - local variable <nVertOffsetToFrameAnchorPos>
477  // for determination of the 'vertical' offset to the frame anchor
478  // position
479  SwTwips nVertOffsetToFrameAnchorPos( 0 );
480  // #i22341# - add special case for vertical alignment
481  // at top of line.
482  if ( mbAnchorToChar &&
483  ( aVert.GetRelationOrient() == text::RelOrientation::CHAR ||
484  aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) )
485  {
486  // #i11860# - use new method <GetTopForObjPos>
487  // to get top of frame for object positioning.
488  SwTwips nTopOfOrient = GetTopForObjPos( *pOrientFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
489  if ( aVert.GetRelationOrient() == text::RelOrientation::CHAR )
490  {
491  nVertOffsetToFrameAnchorPos = aRectFnSet.YDiff(
492  aRectFnSet.GetBottom(*ToCharRect()),
493  nTopOfOrient );
494  }
495  else
496  {
497  nVertOffsetToFrameAnchorPos = aRectFnSet.YDiff( ToCharTopOfLine(),
498  nTopOfOrient );
499  }
500  nRelPosY = nVertOffsetToFrameAnchorPos - aVert.GetPos();
501  }
502  else
503  {
504  // #i28701# - correction: use <pAnchorFrameForVertPos>
505  // instead of <pOrientFrame> and do not adjust relative position
506  // to get correct vertical position.
507  nVertOffsetToFrameAnchorPos = 0;
508  // #i11860# - use new method <GetTopForObjPos>
509  // to get top of frame for object positioning.
510  const SwTwips nTopOfOrient =
511  GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
512  // Increase <nRelPosY> by margin height,
513  // if position is vertical aligned to "paragraph text area"
514  if ( aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
515  {
516  // #i11860# - consider upper space amount of previous frame
517  SwTwips nTopMargin = aRectFnSet.GetTopMargin(*pAnchorFrameForVertPos);
518  if ( pAnchorFrameForVertPos->IsTextFrame() )
519  {
520  nTopMargin -= pAnchorFrameForVertPos->
521  GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
522  }
523  nVertOffsetToFrameAnchorPos += nTopMargin;
524  }
525  // #i18732# - adjust <nRelPosY> by difference
526  // between 'page area' and 'anchor' frame, if position is
527  // vertical aligned to 'page areas'
528  else if ( aVert.GetRelationOrient() == text::RelOrientation::PAGE_FRAME )
529  {
530  nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(
531  aRectFnSet.GetTop(rPageAlignLayFrame.getFrameArea()),
532  nTopOfOrient );
533  }
534  else if ( aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
535  {
536  SwRect aPgPrtRect( rPageAlignLayFrame.getFrameArea() );
537  if ( rPageAlignLayFrame.IsPageFrame() )
538  {
539  aPgPrtRect =
540  static_cast<const SwPageFrame&>(rPageAlignLayFrame).PrtWithoutHeaderAndFooter();
541  }
542  nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(
543  aRectFnSet.GetTop(aPgPrtRect),
544  nTopOfOrient );
545  }
546  else if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
547  {
548  // The anchored object is relative from the bottom of the page's print area.
549  SwRect aPgPrtRect(rPageAlignLayFrame.getFrameArea());
550  if (rPageAlignLayFrame.IsPageFrame())
551  {
552  auto& rPageFrame = static_cast<const SwPageFrame&>(rPageAlignLayFrame);
553  aPgPrtRect = rPageFrame.PrtWithoutHeaderAndFooter();
554  }
555  SwTwips nPageBottom = aRectFnSet.GetBottom(aPgPrtRect);
556  nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(nPageBottom, nTopOfOrient);
557  }
558  nRelPosY = nVertOffsetToFrameAnchorPos + aVert.GetPos();
559  }
560 
561  // <pUpperOfOrientFrame>: layout frame, at which the position has to
562  // is oriented at
563  // <nRelPosY>: rest of the relative distance in the current
564  // layout frame
565  // <nAvail>: space, which is available in the current
566  // layout frame
567 
568  // #i26791# - determine offset to 'vertical'
569  // frame anchor position, depending on layout-direction
570  if ( aRectFnSet.IsVert() )
571  maOffsetToFrameAnchorPos.setX( nVertOffsetToFrameAnchorPos );
572  else
573  maOffsetToFrameAnchorPos.setY( nVertOffsetToFrameAnchorPos );
574  // #i11860# - use new method <GetTopForObjPos>
575  // to get top of frame for object positioning.
576  const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
577  if( nRelPosY <= 0 )
578  {
579  // Allow negative position, but keep it
580  // inside environment layout frame.
581  const SwLayoutFrame& rVertEnvironLayFrame =
582  aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
583  // #i31805# - do not check, if bottom of
584  // anchored object would fit into environment layout frame, if
585  // anchored object has to follow the text flow.
586  const bool bCheckBottom = !DoesObjFollowsTextFlow();
587  nRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
588  rVertEnvironLayFrame, nRelPosY,
590  bCheckBottom );
591  if ( aRectFnSet.IsVert() )
592  aRelPos.setX( nRelPosY );
593  else
594  aRelPos.setY( nRelPosY );
595  }
596  else
597  {
598  aRectFnSet.Refresh(pAnchorFrameForVertPos);
599  SwTwips nAvail =
600  aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
601  nTopOfAnch );
602  const bool bInFootnote = pAnchorFrameForVertPos->IsInFootnote();
603  while ( nRelPosY )
604  {
605  // #i23512# - correction:
606  // consider section frame for grow in online layout.
607  // use new local method <lcl_DoesVertPosFits(..)>
608  SwLayoutFrame* pLayoutFrameToGrow = nullptr;
609  const bool bDoesVertPosFits = lcl_DoesVertPosFits(
610  nRelPosY, nAvail, pUpperOfOrientFrame, bBrowse,
611  bGrow, pLayoutFrameToGrow );
612 
613  if ( bDoesVertPosFits )
614  {
615  SwTwips nTmpRelPosY =
616  aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
617  nTopOfAnch ) -
618  nAvail + nRelPosY;
619  // #i28701# - adjust calculated
620  // relative vertical position to object's environment.
621  const SwFrame& rVertEnvironLayFrame =
622  aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
623  // Do not check, if bottom of
624  // anchored object would fit into environment layout
625  // frame, if anchored object has to follow the text flow.
626  const bool bCheckBottom = !DoesObjFollowsTextFlow();
627  nTmpRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
628  rVertEnvironLayFrame,
629  nTmpRelPosY,
631  bCheckBottom );
632  if ( aRectFnSet.IsVert() )
633  aRelPos.setX( nTmpRelPosY );
634  else
635  aRelPos.setY( nTmpRelPosY );
636 
637  // #i23512# - use local variable
638  // <pLayoutFrameToGrow> provided by new method
639  // <lcl_DoesVertPosFits(..)>.
640  if ( pLayoutFrameToGrow )
641  {
642  // No need to grow the anchor cell in case the follow-text-flow object
643  // is wrap-though.
644  if (!GetAnchorFrame().IsInTab() || !DoesObjFollowsTextFlow() || !bWrapThrough)
645  {
646  pLayoutFrameToGrow->Grow( nRelPosY - nAvail );
647  }
648  }
649  nRelPosY = 0;
650  }
651  else
652  {
653  // #i26495# - floating screen objects,
654  // which are anchored inside a table, doesn't follow
655  // the text flow.
656  if ( DoesObjFollowsTextFlow() &&
657  ( aVert.GetRelationOrient() != text::RelOrientation::PAGE_FRAME &&
658  aVert.GetRelationOrient() != text::RelOrientation::PAGE_PRINT_AREA ) &&
659  !GetAnchorFrame().IsInTab() )
660  {
661  if ( bMoveable )
662  {
663  // follow the text flow
664  nRelPosY -= nAvail;
665  MakePageType eMakePage = bInFootnote ? MAKEPAGE_NONE
666  : MAKEPAGE_APPEND;
667  const bool bInSct = pUpperOfOrientFrame->IsInSct();
668  if( bInSct )
669  eMakePage = MAKEPAGE_NOSECTION;
670 
671  const SwLayoutFrame* pTmp =
672  pUpperOfOrientFrame->GetLeaf( eMakePage, true, &rAnchorTextFrame );
673  if ( pTmp &&
674  ( !bInSct ||
675  pUpperOfOrientFrame->FindSctFrame()->IsAnFollow( pTmp->FindSctFrame() ) ) )
676  {
677  pUpperOfOrientFrame = pTmp;
678  bMoveable = rAnchorTextFrame.IsMoveable( pUpperOfOrientFrame );
679  aRectFnSet.Refresh(pUpperOfOrientFrame);
680  nAvail = aRectFnSet.GetHeight(pUpperOfOrientFrame->getFramePrintArea());
681  }
682  else
683  {
684  // if there isn't enough space in the (columned)
685  // section, leave it and set available space <nAvail>
686  // to the space below the section.
687  // if the new available space isn't also enough,
688  // new pages can be created.
689  if( bInSct )
690  {
691  const SwFrame* pSct = pUpperOfOrientFrame->FindSctFrame();
692  pUpperOfOrientFrame = pSct->GetUpper();
693  nAvail = aRectFnSet.YDiff(
694  aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
695  aRectFnSet.GetPrtBottom(*pSct) );
696  }
697  else
698  {
699 #if OSL_DEBUG_LEVEL > 1
700  OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - !bInSct" );
701 #endif
702  nRelDiff = nRelPosY;
703  nRelPosY = 0;
704  }
705  }
706  }
707  else
708  {
709  nRelPosY = 0;
710  }
711  }
712  else
713  {
714  // #i18732# - do not follow text flow respectively
715  // align at 'page areas', but stay inside given environment
716  const SwFrame& rVertEnvironLayFrame =
717  aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
718  nRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
719  rVertEnvironLayFrame,
720  nRelPosY,
722  if( aRectFnSet.IsVert() )
723  aRelPos.setX( nRelPosY );
724  else
725  aRelPos.setY( nRelPosY );
726  nRelPosY = 0;
727  }
728  }
729  } // end of <while ( nRelPosY )>
730  } // end of else <nRelPosY <= 0>
731  } // end of <aVert.GetVertOrient() == text::VertOrientation::NONE>
732 
733  // We need to calculate the part's absolute position, in order for
734  // it to be put onto the right page and to be pulled into the
735  // LayLeaf's PrtArea
736  const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
737  if( aRectFnSet.IsVert() )
738  {
739  // --> OD 2009-08-31 #monglianlayout#
740  if ( !aRectFnSet.IsVertL2R() )
741  {
742  GetAnchoredObj().SetObjLeft( nTopOfAnch -
743  ( aRelPos.X() - nRelDiff ) -
744  aObjBoundRect.Width() );
745  }
746  else
747  {
748  GetAnchoredObj().SetObjLeft( nTopOfAnch +
749  ( aRelPos.X() - nRelDiff ) );
750  }
751  }
752  else
753  {
754  GetAnchoredObj().SetObjTop( nTopOfAnch +
755  ( aRelPos.Y() - nRelDiff ) );
756  }
757 
758  // grow environment under certain conditions
759  // ignore one-column sections.
760  // #i23512# - correction: also ignore one-columned
761  // sections with footnotes/endnotes
762  if ( pUpperOfOrientFrame->IsInSct() )
763  {
764  const SwSectionFrame* pSctFrame = pUpperOfOrientFrame->FindSctFrame();
765  const bool bIgnoreSection = pUpperOfOrientFrame->IsSctFrame() ||
766  ( pSctFrame->Lower()->IsColumnFrame() &&
767  !pSctFrame->Lower()->GetNext() );
768  if ( bIgnoreSection )
769  pUpperOfOrientFrame = pSctFrame->GetUpper();
770  }
771  SwTwips nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
772  aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
773  if( nDist < 0 )
774  {
775  // #i23512# - correction:
776  // consider section frame for grow in online layout and
777  // consider page alignment for grow in table.
778  SwLayoutFrame* pLayoutFrameToGrow = nullptr;
779  if ( bBrowse && rAnchorTextFrame.IsMoveable() )
780  {
781  if ( pUpperOfOrientFrame->IsInSct() )
782  {
783  pLayoutFrameToGrow = const_cast<SwLayoutFrame*>(
784  pUpperOfOrientFrame->FindSctFrame()->GetUpper());
785  nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
786  aRectFnSet.GetPrtBottom(*pLayoutFrameToGrow) );
787  if ( nDist >= 0 )
788  {
789  pLayoutFrameToGrow = nullptr;
790  }
791  }
792  else
793  {
794  pLayoutFrameToGrow =
795  const_cast<SwLayoutFrame*>(pUpperOfOrientFrame);
796  }
797  }
798  else if ( rAnchorTextFrame.IsInTab() && bGrow )
799  {
800  pLayoutFrameToGrow = const_cast<SwLayoutFrame*>(pUpperOfOrientFrame);
801  }
802  if ( pLayoutFrameToGrow )
803  {
804  // No need to grow the anchor cell in case the follow-text-flow object
805  // is wrap-though.
806  if (!GetAnchorFrame().IsInTab() || !DoesObjFollowsTextFlow() || !bWrapThrough)
807  {
808  pLayoutFrameToGrow->Grow( -nDist );
809  }
810  }
811  }
812 
813  if ( DoesObjFollowsTextFlow() &&
814  ( aVert.GetRelationOrient() != text::RelOrientation::PAGE_FRAME &&
815  aVert.GetRelationOrient() != text::RelOrientation::PAGE_PRINT_AREA ) )
816  {
817 
818  nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
819  aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
820  // #i26945# - floating screen objects, which are
821  // anchored inside a table, doesn't follow the text flow. But, they
822  // have to stay inside its layout environment.
823  if ( nDist < 0 && pOrientFrame->IsInTab() )
824  {
825  // If the anchor frame is the first content of the table cell
826  // and has no follow, the table frame is notified,
827  // that the object doesn't fit into the table cell.
828  // Adjustment of position isn't needed in this case.
829  if ( pOrientFrame == &rAnchorTextFrame &&
830  !pOrientFrame->GetFollow() &&
831  !pOrientFrame->GetIndPrev() )
832  {
833  const_cast<SwTabFrame*>(pOrientFrame->FindTabFrame())
834  ->SetDoesObjsFit( false );
835  }
836  else
837  {
838  SwTwips nTmpRelPosY( 0 );
839  if ( aRectFnSet.IsVert() )
840  nTmpRelPosY = aRelPos.X() - nDist;
841  else
842  nTmpRelPosY = aRelPos.Y() + nDist;
843  const SwLayoutFrame& rVertEnvironLayFrame =
844  aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
845  nTmpRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
846  rVertEnvironLayFrame,
847  nTmpRelPosY,
849  false );
850  if ( aRectFnSet.IsVert() )
851  {
852  aRelPos.setX( nTmpRelPosY );
853  // --> OD 2009-08-31 #mongolianlayout#
854  if ( !aRectFnSet.IsVertL2R() )
855  {
856  GetAnchoredObj().SetObjLeft( nTopOfAnch -
857  aRelPos.X() -
858  aObjBoundRect.Width() );
859  }
860  else
861  {
862  GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
863  }
864  }
865  else
866  {
867  aRelPos.setY( nTmpRelPosY );
868  GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
869  }
870  // If the anchor frame is the first content of the table cell
871  // and the object still doesn't fit, the table frame is notified,
872  // that the object doesn't fit into the table cell.
873  nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
874  aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
875  if ( nDist < 0 &&
876  pOrientFrame == &rAnchorTextFrame && !pOrientFrame->GetIndPrev() )
877  {
878  const_cast<SwTabFrame*>(pOrientFrame->FindTabFrame())
879  ->SetDoesObjsFit( false );
880  }
881  }
882  }
883  else
884  {
885  // follow text flow
886  const bool bInFootnote = rAnchorTextFrame.IsInFootnote();
887  while( bMoveable && nDist < 0 )
888  {
889  bool bInSct = pUpperOfOrientFrame->IsInSct();
890  if ( bInSct )
891  {
892  const SwLayoutFrame* pTmp = pUpperOfOrientFrame->FindSctFrame()->GetUpper();
893  nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
894  aRectFnSet.GetPrtBottom(*pTmp) );
895  // #i23129# - Try to flow into next
896  // section|section column. Thus, do *not* leave section
897  // area, if anchored object doesn't fit into upper of section.
898  // But the anchored object is allowed to overlap bottom
899  // section|section column.
900  if ( nDist >= 0 )
901  {
902  break;
903  }
904  }
905  if ( !bInSct &&
906  aRectFnSet.GetTop(GetAnchoredObj().GetObjRect()) ==
907  aRectFnSet.GetPrtTop(*pUpperOfOrientFrame) )
908  // It doesn't fit, moving it would not help either anymore
909  break;
910 
911  const SwLayoutFrame* pNextLay = pUpperOfOrientFrame->GetLeaf(
912  ( bInSct
914  : ( bInFootnote ? MAKEPAGE_NONE : MAKEPAGE_APPEND ) ),
915  true, &rAnchorTextFrame );
916  // correction:
917  // If anchor is in footnote and proposed next layout environment
918  // isn't a footnote frame, object can't follow the text flow
919  if ( bInFootnote && pNextLay && !pNextLay->IsFootnoteFrame() )
920  {
921  pNextLay = nullptr;
922  }
923  if ( pNextLay )
924  {
925  SwRectFnSet fnRectX(pNextLay);
926  if ( !bInSct ||
927  ( pUpperOfOrientFrame->FindSctFrame()->IsAnFollow( pNextLay->FindSctFrame() ) &&
928  fnRectX.GetHeight(pNextLay->getFramePrintArea()) ) )
929  {
930  SwTwips nTmpRelPosY =
931  aRectFnSet.YDiff( aRectFnSet.GetPrtTop(*pNextLay),
932  nTopOfAnch );
933  if ( aRectFnSet.IsVert() )
934  aRelPos.setX( nTmpRelPosY );
935  else
936  aRelPos.setY( nTmpRelPosY );
937  pUpperOfOrientFrame = pNextLay;
938  aRectFnSet.Refresh(pUpperOfOrientFrame);
939  bMoveable = rAnchorTextFrame.IsMoveable( pUpperOfOrientFrame );
940  if( fnRectX.IsVert() )
941  {
942  // --> OD 2009-08-31 #mongolianlayout#
943  if ( !aRectFnSet.IsVertL2R() )
944  {
945  GetAnchoredObj().SetObjLeft( nTopOfAnch -
946  aRelPos.X() -
947  aObjBoundRect.Width() );
948  }
949  else
950  {
951  GetAnchoredObj().SetObjLeft( nTopOfAnch +
952  aRelPos.X() );
953  }
954  }
955  else
956  GetAnchoredObj().SetObjTop( nTopOfAnch +
957  aRelPos.Y() );
958  nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
959  aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
960  }
961  // #i23129# - leave section area
962  else if ( bInSct )
963  {
964  const SwLayoutFrame* pTmp = pUpperOfOrientFrame->FindSctFrame()->GetUpper();
965  nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
966  aRectFnSet.GetPrtBottom(*pTmp) );
967  if( nDist < 0 )
968  pUpperOfOrientFrame = pTmp;
969  else
970  break;
971  }
972  }
973  else if ( bInSct )
974  {
975  // If we don't have enough room within the Area, we take a look at
976  // the Page
977  const SwLayoutFrame* pTmp = pUpperOfOrientFrame->FindSctFrame()->GetUpper();
978  nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
979  aRectFnSet.GetPrtBottom(*pTmp) );
980  if( nDist < 0 )
981  pUpperOfOrientFrame = pTmp;
982  else
983  break;
984  }
985  else
986  bMoveable = false;
987  }
988  }
989  }
990 
991  // keep layout frame vertical position is oriented at.
992  mpVertPosOrientFrame = pUpperOfOrientFrame;
993 
994  // If it was requested to not overlap with already formatted objects, take care of that
995  // here.
996  CalcOverlap(pAnchorFrameForVertPos, aRelPos, nTopOfAnch);
997  }
998 
999  // determine 'horizontal' position
1000  {
1001  // determine horizontal positioning and alignment attributes
1002  SwFormatHoriOrient aHori( rFrameFormat.GetHoriOrient() );
1003 
1004  // set calculated vertical position in order to determine correct
1005  // frame, the horizontal position is oriented at.
1006  const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
1007  if( aRectFnSet.IsVert() )
1008  {
1009  // --> OD 2009-08-31 #mongolianlayout#
1010  if ( !aRectFnSet.IsVertL2R() )
1011  {
1012  GetAnchoredObj().SetObjLeft( nTopOfAnch -
1013  aRelPos.X() - aObjBoundRect.Width() );
1014  }
1015  else
1016  {
1017  GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
1018  }
1019  }
1020  else
1021  GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
1022 
1023  // determine frame, horizontal position is oriented at.
1024  // #i28701# - If floating screen object doesn't follow
1025  // the text flow, its horizontal position is oriented at <pOrientFrame>.
1026  const SwFrame* pHoriOrientFrame = DoesObjFollowsTextFlow()
1028  : pOrientFrame;
1029 
1030  // #i26791# - get 'horizontal' offset to frame anchor position.
1031  SwTwips nHoriOffsetToFrameAnchorPos( 0 );
1032  SwTwips nRelPosX = CalcRelPosX( *pHoriOrientFrame, aEnvOfObj,
1033  aHori, rLR, rUL, bWrapThrough,
1034  ( aRectFnSet.IsVert() ? aRelPos.X() : aRelPos.Y() ),
1035  nHoriOffsetToFrameAnchorPos );
1036 
1037  // #i26791# - determine offset to 'horizontal' frame
1038  // anchor position, depending on layout-direction
1039  if ( aRectFnSet.IsVert() )
1040  {
1041  aRelPos.setY( nRelPosX );
1042  maOffsetToFrameAnchorPos.setY( nHoriOffsetToFrameAnchorPos );
1043  }
1044  else
1045  {
1046  aRelPos.setX( nRelPosX );
1047  maOffsetToFrameAnchorPos.setX( nHoriOffsetToFrameAnchorPos );
1048  }
1049 
1050  // save calculated horizontal position - needed for filters
1051  // (including the xml-filter)
1052  {
1053  SwTwips nAttrRelPosX = nRelPosX - nHoriOffsetToFrameAnchorPos;
1054  if ( aHori.GetHoriOrient() != text::HoriOrientation::NONE &&
1055  aHori.GetPos() != nAttrRelPosX )
1056  {
1057  aHori.SetPos( nAttrRelPosX );
1058  const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
1059  const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr( aHori );
1060  const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
1061  }
1062  }
1063  }
1064 
1065  // set absolute position at object
1066  const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
1067  if( aRectFnSet.IsVert() )
1068  {
1069  // --> OD 2009-08-31 #mongolianlayout#
1070  if ( !aRectFnSet.IsVertL2R() )
1071  {
1072  GetAnchoredObj().SetObjLeft( nTopOfAnch -
1073  aRelPos.X() - aObjBoundRect.Width() );
1074  }
1075  else
1076  {
1077  GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
1078  }
1079  GetAnchoredObj().SetObjTop( rAnchorTextFrame.getFrameArea().Top() +
1080  aRelPos.Y() );
1081  }
1082  else
1083  {
1084  GetAnchoredObj().SetObjLeft( rAnchorTextFrame.getFrameArea().Left() +
1085  aRelPos.X() );
1086  GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
1087  }
1088 
1089  // set relative position at object
1090  GetAnchoredObj().SetCurrRelPos( aRelPos );
1091 }
1092 
1094  Point& rRelPos, const SwTwips nTopOfAnch)
1095 {
1096  const SwFrameFormat& rFrameFormat = GetFrameFormat();
1097  bool bAllowOverlap = rFrameFormat.GetWrapInfluenceOnObjPos().GetAllowOverlap();
1098  if (bAllowOverlap)
1099  {
1100  return;
1101  }
1102 
1103  if (rFrameFormat.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH)
1104  {
1105  // This is explicit wrap through: allowed to overlap.
1106  return;
1107  }
1108 
1109  if (SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT))
1110  {
1111  // This is the frame part of a textbox, just take the offset from the textbox's shape part.
1112  SwFrameFormat* pShapeOfTextBox
1114  if (pShapeOfTextBox)
1115  {
1116  SwTwips nYDiff = pShapeOfTextBox->GetWrapInfluenceOnObjPos().GetOverlapVertOffset();
1117  if (nYDiff > 0)
1118  {
1119  rRelPos.setY(rRelPos.getY() + nYDiff + 1);
1120  GetAnchoredObj().SetObjTop(nTopOfAnch + rRelPos.Y());
1121  }
1122  }
1123  return;
1124  }
1125 
1126  // Get the list of objects.
1127  auto pSortedObjs = pAnchorFrameForVertPos->GetDrawObjs();
1128  if (!pSortedObjs)
1129  {
1130  return;
1131  }
1132 
1133  for (const auto& pAnchoredObj : *pSortedObjs)
1134  {
1135  if (pAnchoredObj == &GetAnchoredObj())
1136  {
1137  // We found ourselves, stop iterating.
1138  break;
1139  }
1140 
1141  if (SwTextBoxHelper::isTextBox(&pAnchoredObj->GetFrameFormat(), RES_FLYFRMFMT))
1142  {
1143  // Overlapping with the frame of a textbox is fine.
1144  continue;
1145  }
1146 
1147  css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat().GetSurround().GetSurround();
1148  if (eWrap == css::text::WrapTextMode_THROUGH)
1149  {
1150  // The other object is wrap through: allowed to overlap.
1151  continue;
1152  }
1153 
1154  if (!GetAnchoredObj().GetObjRect().IsOver(pAnchoredObj->GetObjRect()))
1155  {
1156  // Found an already positioned object, but it doesn't overlap, ignore.
1157  continue;
1158  }
1159 
1160  // Already formatted, overlaps: resolve the conflict by shifting ourselves down.
1161  SwTwips nYDiff = pAnchoredObj->GetObjRect().Bottom() - GetAnchoredObj().GetObjRect().Top();
1162  rRelPos.setY(rRelPos.getY() + nYDiff + 1);
1163  GetAnchoredObj().SetObjTop(nTopOfAnch + rRelPos.Y());
1164 
1165  // Store our offset that avoids the overlap. If this is a shape of a textbox, then the frame
1166  // of the textbox will use it.
1167  SwFormatWrapInfluenceOnObjPos aInfluence(rFrameFormat.GetWrapInfluenceOnObjPos());
1168  aInfluence.SetOverlapVertOffset(nYDiff);
1169  const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
1170  const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr(aInfluence);
1171  const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
1172  }
1173 }
1174 
1179  const SwLayoutFrame& _rProposedFrame ) const
1180 {
1181  const SwFrame* pHoriVirtAnchFrame = &_rProposedFrame;
1182 
1183  // Search for first lower content frame, which is the anchor or a follow
1184  // of the anchor (Note: <Anchor.IsAnFollow( Anchor )> is true)
1185  // If none found, <_rProposedFrame> is returned.
1186  const SwFrame* pFrame = _rProposedFrame.Lower();
1187  while ( pFrame )
1188  {
1189  if ( pFrame->IsContentFrame() &&
1190  GetAnchorTextFrame().IsAnFollow( static_cast<const SwContentFrame*>(pFrame) ) )
1191  {
1192  pHoriVirtAnchFrame = pFrame;
1193  break;
1194  }
1195  pFrame = pFrame->GetNext();
1196  }
1197 
1198  return *pHoriVirtAnchFrame;
1199 }
1200 
1201 
1202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long GetLeft() const
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:547
void CheckCharRectAndTopOfLine(const bool _bCheckForParaPorInf)
check anchor character rectangle and top of line
Base class of the Writer layout elements.
Definition: frame.hxx:297
static bool lcl_DoesVertPosFits(const SwTwips _nRelPosY, const SwTwips _nAvail, const SwLayoutFrame *_pUpperOfOrientFrame, const bool _bBrowse, const bool _bGrowInTable, SwLayoutFrame *&_orpLayoutFrameToGrow)
const SwRect & GetLastCharRect() const
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
virtual SwRect GetObjRect() const =0
long BottomDist(const SwRect &rRect, long nPos) const
Definition: frame.hxx:1392
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:545
bool IsInDocBody() const
Definition: frame.hxx:921
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1469
sal_uInt16 GetLower() const
bool IsInSct() const
Definition: frame.hxx:945
const SwLayoutFrame & GetVertEnvironmentLayoutFrame(const SwFrame &_rVertOrientFrame) const
determine environment layout frame for possible vertical object positions respectively for alignments...
void CalcOverlap(const SwTextFrame *pAnchorFrameForVertPos, Point &rRelPos, const SwTwips nTopOfAnch)
In case overlap is not allowed, re-position the current object.
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
void Refresh(const SwFrame *pFrame)
Definition: frame.hxx:1337
bool IsInFootnote() const
Definition: frame.hxx:927
SwRectFn FnRect() const
Definition: frame.hxx:1347
const SwRect & getFramePrintArea() const
Definition: frame.hxx:178
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1356
long SwTwips
Definition: swtypes.hxx:49
bool IsVert() const
Definition: frame.hxx:1345
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1387
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType)
If we have an associated TextFrame, then return that.
bool IsFootnoteFrame() const
Definition: frame.hxx:1180
long YDiff(long n1, long n2) const
Definition: frame.hxx:1401
long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1388
void SetCurrRelPos(Point _aRelPos)
void Top(const long nTop)
Definition: swrect.hxx:204
bool IsMoveable(const SwLayoutFrame *_pLayoutFrame=nullptr) const
determine, if frame is moveable in given environment
Definition: findfrm.cxx:1359
const SwRect & getFrameArea() const
Definition: frame.hxx:177
bool getBrowseMode() const
Definition: viewopt.hxx:461
bool IsInTab() const
Definition: frame.hxx:933
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType)
Is the frame format a text box?
bool IsTextFrame() const
Definition: frame.hxx:1212
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
void SetOverlapVertOffset(SwTwips nOverlapVertOffset)
bool IsSctFrame() const
Definition: frame.hxx:1192
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:846
void SetObjTop(const SwTwips _nTop)
long const nTopMargin
bool IsColumnFrame() const
Definition: frame.hxx:1160
virtual void CalcPosition() override
calculate position of object
SwTwips AdjustVertRelPos(const SwTwips nTopOfAnch, const bool bVert, const bool bVertL2R, const SwFrame &rPageAlignLayFrame, const SwTwips nProposedRelPosY, const bool bFollowTextFlow, const bool bCheckBottom=true) const
adjust calculated vertical in order to keep object inside 'page' alignment layout frame...
Style of a layout element.
Definition: frmfmt.hxx:57
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1259
bool IsContentFrame() const
Definition: frame.hxx:1208
SwFrame * GetIndPrev() const
Definition: frame.hxx:704
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:108
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
SwPageFrame * FindPageFrame()
Definition: frame.hxx:660
const SwFrame * Lower() const
Definition: layfrm.hxx:101
FlyAnchors.
Definition: fmtanchr.hxx:34
SwTwips CalcRelPosX(const SwFrame &_rHoriOrientFrame, const SwEnvironmentOfAnchoredObject &_rEnvOfObj, const SwFormatHoriOrient &_rHoriOrient, const SvxLRSpaceItem &_rLRSpacing, const SvxULSpaceItem &_rULSpacing, const bool _bObjWrapThrough, const SwTwips _nRelPosY, SwTwips &_roHoriOffsetToFrameAnchorPos) const
calculate relative horizontal position
sal_uInt8 GetHeightPercent() const
Definition: fmtfsize.hxx:88
SwLayoutFrame * GetUpper()
Definition: frame.hxx:658
long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1381
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
SwRect PrtWithoutHeaderAndFooter() const
Definition: frmtool.cxx:3775
A page of the document layout.
Definition: pagefrm.hxx:41
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1093
void Left(const long nLeft)
Definition: swrect.hxx:195
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:76
SwLayoutFrame * GetLeaf(MakePageType eMakePage, bool bFwd)
Definition: flowfrm.cxx:786
MakePageType
Definition: frame.hxx:110
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
void Width(long nNew)
Definition: swrect.hxx:187
SwTwips GetLastTopOfLine() const
bool IsVertL2R() const
Definition: frame.hxx:1346
void GetVertAlignmentValues(const SwFrame &_rVertOrientFrame, const SwFrame &_rPageAlignLayFrame, const sal_Int16 _eRelOrient, SwTwips &_orAlignAreaHeight, SwTwips &_orAlignAreaOffset) const
long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1360
const SwFormatWrapInfluenceOnObjPos & GetWrapInfluenceOnObjPos(bool=true) const
bool IsAnFollow(const SwFlowFrame *pFlow) const
Definition: flowfrm.cxx:670
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(154)
long GetRight() const
SwTwips GetTopForObjPos(const SwFrame &_rFrame, const SwRectFn &_fnRect, const bool _bVert) const
helper method to determine top of a frame for the vertical object positioning
void SetObjLeft(const SwTwips _nLeft)
long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1355
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
const SwFrame & GetHoriVirtualAnchor(const SwLayoutFrame &_pProposedFrame) const
determine frame for horizontal position
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:205
bool IsFooterFrame() const
Definition: frame.hxx:1172
SwRootFrame * getRootFrame()
Definition: frame.hxx:659
sal_uInt16 GetUpper() const
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1077
SwFrame * GetNext()
Definition: frame.hxx:656
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74