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