nss: upgrade to release 3.73
[LibreOffice.git] / sw / source / core / objectpositioning / tocntntanchoredobjectposition.cxx
blobdea6424bc3dd987e47f70b4b5227ccd3d5a5e489
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <tocntntanchoredobjectposition.hxx>
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>
38 #include <environmentofanchoredobject.hxx>
39 #include <frmatr.hxx>
40 #include <fmtwrapinfluenceonobjpos.hxx>
41 #include <sortedobjs.hxx>
42 #include <textboxhelper.hxx>
44 using namespace objectpositioning;
45 using namespace ::com::sun::star;
47 SwToContentAnchoredObjectPosition::SwToContentAnchoredObjectPosition( SdrObject& _rDrawObj )
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 )
59 SwToContentAnchoredObjectPosition::~SwToContentAnchoredObjectPosition()
62 bool SwToContentAnchoredObjectPosition::IsAnchoredToChar() const
64 return mbAnchorToChar;
67 const SwFrame* SwToContentAnchoredObjectPosition::ToCharOrientFrame() const
69 return mpToCharOrientFrame;
72 const SwRect* SwToContentAnchoredObjectPosition::ToCharRect() const
74 return mpToCharRect;
77 // #i22341#
78 SwTwips SwToContentAnchoredObjectPosition::ToCharTopOfLine() const
80 return mnToCharTopOfLine;
83 SwTextFrame& SwToContentAnchoredObjectPosition::GetAnchorTextFrame() const
85 OSL_ENSURE( dynamic_cast<const SwTextFrame*>( &GetAnchorFrame()) != nullptr ,
86 "SwToContentAnchoredObjectPosition::GetAnchorTextFrame() - wrong anchor frame type" );
88 return static_cast<SwTextFrame&>(GetAnchorFrame());
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 )
99 bool bVertPosFits = false;
101 if ( _nRelPosY <= _nAvail )
103 bVertPosFits = true;
105 else if ( _bBrowse )
107 if ( _pUpperOfOrientFrame->IsInSct() )
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.
114 else
116 bVertPosFits = const_cast<SwLayoutFrame*>(_pUpperOfOrientFrame)->
117 Grow( _nRelPosY - _nAvail, true ) > 0;
118 if ( bVertPosFits )
119 _orpLayoutFrameToGrow = const_cast<SwLayoutFrame*>(_pUpperOfOrientFrame);
122 else if ( _pUpperOfOrientFrame->IsInTab() && _bGrowInTable )
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);
133 return bVertPosFits;
136 void SwToContentAnchoredObjectPosition::CalcPosition()
138 // get format of object
139 const SwFrameFormat& rFrameFormat = GetFrameFormat();
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;
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 )
152 const SwViewShell *pSh = GetAnchorFrame().getRootFrame()->GetCurrShell();
153 if( !pSh || !pSh->GetViewOptions()->getBrowseMode() )
154 bBrowse = false;
157 // determine left/right and its upper/lower spacing.
158 const SvxLRSpaceItem &rLR = rFrameFormat.GetLRSpace();
159 const SvxULSpaceItem &rUL = rFrameFormat.GetULSpace();
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;
166 // new class <SwEnvironmentOfAnchoredObject>
167 SwEnvironmentOfAnchoredObject aEnvOfObj( DoesObjFollowsTextFlow() );
169 // #i18732# - grow only, if object has to follow the text flow
170 const bool bGrow = DoesObjFollowsTextFlow() &&
171 ( !GetAnchorFrame().IsInTab() ||
172 !rFrameFormat.GetFrameSize().GetHeightPercent() );
174 // get text frame the object is anchored at
175 const SwTextFrame& rAnchorTextFrame = GetAnchorTextFrame();
176 SwRectFnSet aRectFnSet(&rAnchorTextFrame);
178 const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() );
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() );
185 SwTwips nRelDiff = 0;
187 bool bMoveable = rAnchorTextFrame.IsMoveable();
189 // determine frame the object position has to be oriented at.
190 const SwTextFrame* pOrientFrame = &rAnchorTextFrame;
191 const SwTextFrame* pAnchorFrameForVertPos;
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 )
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() )
206 GetAnchoredObj().CheckCharRectAndTopOfLine( false );
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() )
213 // Get default for <mpVertPosOrientFrame>, if it's not set.
214 if ( !mpVertPosOrientFrame )
216 mpVertPosOrientFrame = rAnchorTextFrame.GetUpper();
218 return;
221 mpToCharRect = &(GetAnchoredObj().GetLastCharRect());
222 // #i22341# - get top of line, in which the anchor character is.
223 mnToCharTopOfLine = GetAnchoredObj().GetLastTopOfLine();
224 pOrientFrame = &(const_cast<SwTextFrame&>(rAnchorTextFrame).GetFrameAtOfst(
225 rAnchorTextFrame.MapModelToViewPos(*rAnch.GetContentAnchor())));
226 mpToCharOrientFrame = pOrientFrame;
229 aRectFnSet.Refresh(pOrientFrame);
231 // determine vertical position
234 // determine vertical positioning and alignment attributes
235 SwFormatVertOrient aVert( rFrameFormat.GetVertOrient() );
237 // #i18732# - determine layout frame for vertical
238 // positions aligned to 'page areas'.
239 const SwLayoutFrame& rPageAlignLayFrame =
240 aEnvOfObj.GetVertEnvironmentLayoutFrame( *pOrientFrame );
242 if ( aVert.GetVertOrient() != text::VertOrientation::NONE )
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 );
252 SwRect aHeaderRect;
253 const SwPageFrame* aPageFrame = pOrientFrame->FindPageFrame();
254 const SwHeaderFrame* pHeaderFrame = aPageFrame->GetHeaderFrame();
255 if (pHeaderFrame)
256 aHeaderRect = pHeaderFrame->GetPaintArea();
257 const SwTwips nTopMarginHeight = aPageFrame->GetTopMargin() + aHeaderRect.Height();
258 const SwTwips nHeightBetweenOffsetAndMargin = nAlignAreaOffset + nTopMarginHeight;
260 // determine relative vertical position
261 SwTwips nRelPosY = nAlignAreaOffset;
262 const SwTwips nObjHeight = aRectFnSet.GetHeight(aObjBoundRect);
263 const SwTwips nUpperSpace = aRectFnSet.IsVert()
264 ? ( aRectFnSet.IsVertL2R()
265 ? rLR.GetLeft()
266 : rLR.GetRight() )
267 : rUL.GetUpper();
268 // --> OD 2009-08-31 #monglianlayout#
269 const SwTwips nLowerSpace = aRectFnSet.IsVert()
270 ? ( aRectFnSet.IsVertL2R()
271 ? rLR.GetLeft()
272 : rLR.GetRight() )
273 : rUL.GetLower();
274 switch ( aVert.GetVertOrient() )
276 case text::VertOrientation::CHAR_BOTTOM:
278 if ( mbAnchorToChar )
280 // bottom (to character anchored)
281 nRelPosY += nAlignAreaHeight + nUpperSpace;
282 if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
284 nRelPosY += nObjHeight;
286 break;
288 [[fallthrough]];
290 case text::VertOrientation::TOP:
292 // #i22341# - special case for vertical
293 // alignment at top of line
294 if ( mbAnchorToChar &&
295 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
297 nRelPosY -= (nObjHeight + nLowerSpace);
299 else
301 nRelPosY += nUpperSpace;
304 break;
305 // #i22341#
306 case text::VertOrientation::LINE_TOP:
308 if ( mbAnchorToChar &&
309 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
311 nRelPosY -= (nObjHeight + nLowerSpace);
313 else
315 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
318 break;
319 case text::VertOrientation::CENTER:
321 if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_TOP)
322 nRelPosY = (nAlignAreaOffset / 2) - (nObjHeight / 2) + (nHeightBetweenOffsetAndMargin / 2);
323 else
324 nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2);
326 break;
327 // #i22341#
328 case text::VertOrientation::LINE_CENTER:
330 if ( mbAnchorToChar &&
331 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
333 nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2);
335 else
337 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
340 break;
341 case text::VertOrientation::BOTTOM:
343 if ( ( aVert.GetRelationOrient() == text::RelOrientation::FRAME ||
344 aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
345 bNoSurround )
347 // bottom (aligned to 'paragraph areas')
348 nRelPosY += nAlignAreaHeight + nUpperSpace;
350 else
352 // #i22341# - special case for vertical
353 // alignment at top of line
354 if ( mbAnchorToChar &&
355 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
357 nRelPosY += nUpperSpace;
359 else
361 if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_TOP)
362 nRelPosY = 0 - (nObjHeight + nLowerSpace) + nHeightBetweenOffsetAndMargin;
363 else
364 nRelPosY += nAlignAreaHeight - (nObjHeight + nLowerSpace);
368 break;
369 // #i22341#
370 case text::VertOrientation::LINE_BOTTOM:
372 if ( mbAnchorToChar &&
373 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
375 nRelPosY += nUpperSpace;
377 else
379 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
382 break;
383 default:
384 break;
387 // adjust relative position by distance between anchor frame and
388 // the frame, the object is oriented at.
389 // #i28701# - correction: adjust relative position,
390 // only if the floating screen object has to follow the text flow.
391 if ( DoesObjFollowsTextFlow() && pOrientFrame != &rAnchorTextFrame )
393 // #i11860# - use new method <GetTopForObjPos>
394 // to get top of frame for object positioning.
395 const SwTwips nTopOfOrient = GetTopForObjPos( *pOrientFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
396 nRelPosY += aRectFnSet.YDiff( nTopOfOrient,
397 GetTopForObjPos( rAnchorTextFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() ) );
400 // #i42124# - capture object inside vertical
401 // layout environment.
403 const SwTwips nTopOfAnch =
404 GetTopForObjPos( *pOrientFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
405 const SwLayoutFrame& rVertEnvironLayFrame =
406 aEnvOfObj.GetVertEnvironmentLayoutFrame(
407 *(pOrientFrame->GetUpper()) );
408 const bool bCheckBottom = !DoesObjFollowsTextFlow();
409 nRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
410 rVertEnvironLayFrame, nRelPosY,
411 DoesObjFollowsTextFlow(),
412 bCheckBottom );
415 // keep calculated relative vertical position - needed for filters
416 // (including the xml-filter)
418 // determine position
419 SwTwips nAttrRelPosY = nRelPosY - nAlignAreaOffset;
420 // set
421 if ( nAttrRelPosY != aVert.GetPos() )
423 aVert.SetPos( nAttrRelPosY );
424 const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
425 const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr( aVert );
426 const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
430 // determine absolute 'vertical' position, depending on layout-direction
431 // #i26791# - determine offset to 'vertical' frame
432 // anchor position, depending on layout-direction
433 if ( aRectFnSet.IsVert() )
435 aRelPos.setX( nRelPosY );
436 maOffsetToFrameAnchorPos.setX( nAlignAreaOffset );
438 else
440 aRelPos.setY( nRelPosY );
441 maOffsetToFrameAnchorPos.setY( nAlignAreaOffset );
445 // Determine upper of frame vertical position is oriented at.
446 // #i28701# - determine 'virtual' anchor frame.
447 // This frame is used in the following instead of the 'real' anchor
448 // frame <rAnchorTextFrame> for the 'vertical' position in all cases.
449 const SwLayoutFrame* pUpperOfOrientFrame = nullptr;
451 // #i28701# - As long as the anchor frame is on the
452 // same page as <pOrientFrame> and the vertical position isn't aligned
453 // automatic at the anchor character or the top of the line of the
454 // anchor character, the anchor frame determines the vertical position.
455 if ( &rAnchorTextFrame == pOrientFrame ||
456 ( rAnchorTextFrame.FindPageFrame() == pOrientFrame->FindPageFrame() &&
457 aVert.GetVertOrient() == text::VertOrientation::NONE &&
458 aVert.GetRelationOrient() != text::RelOrientation::CHAR &&
459 aVert.GetRelationOrient() != text::RelOrientation::TEXT_LINE ) )
461 pUpperOfOrientFrame = rAnchorTextFrame.GetUpper();
462 pAnchorFrameForVertPos = &rAnchorTextFrame;
464 else
466 pUpperOfOrientFrame = pOrientFrame->GetUpper();
467 pAnchorFrameForVertPos = pOrientFrame;
471 // ignore one-column sections.
472 // #i23512# - correction: also ignore one-columned
473 // sections with footnotes/endnotes
474 if ( pUpperOfOrientFrame->IsInSct() )
476 const SwSectionFrame* pSctFrame = pUpperOfOrientFrame->FindSctFrame();
477 const bool bIgnoreSection = pUpperOfOrientFrame->IsSctFrame() ||
478 ( pSctFrame->Lower()->IsColumnFrame() &&
479 !pSctFrame->Lower()->GetNext() );
480 if ( bIgnoreSection )
481 pUpperOfOrientFrame = pSctFrame->GetUpper();
484 if ( aVert.GetVertOrient() == text::VertOrientation::NONE )
486 // local variable <nRelPosY> for calculation of relative vertical
487 // distance to anchor.
488 SwTwips nRelPosY = 0;
489 // #i26791# - local variable <nVertOffsetToFrameAnchorPos>
490 // for determination of the 'vertical' offset to the frame anchor
491 // position
492 SwTwips nVertOffsetToFrameAnchorPos( 0 );
493 // #i22341# - add special case for vertical alignment
494 // at top of line.
495 if ( mbAnchorToChar &&
496 ( aVert.GetRelationOrient() == text::RelOrientation::CHAR ||
497 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) )
499 // #i11860# - use new method <GetTopForObjPos>
500 // to get top of frame for object positioning.
501 SwTwips nTopOfOrient = GetTopForObjPos( *pOrientFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
502 if ( aVert.GetRelationOrient() == text::RelOrientation::CHAR )
504 nVertOffsetToFrameAnchorPos = aRectFnSet.YDiff(
505 aRectFnSet.GetBottom(*ToCharRect()),
506 nTopOfOrient );
508 else
510 nVertOffsetToFrameAnchorPos = aRectFnSet.YDiff( ToCharTopOfLine(),
511 nTopOfOrient );
513 nRelPosY = nVertOffsetToFrameAnchorPos - aVert.GetPos();
515 else
517 // #i28701# - correction: use <pAnchorFrameForVertPos>
518 // instead of <pOrientFrame> and do not adjust relative position
519 // to get correct vertical position.
520 nVertOffsetToFrameAnchorPos = 0;
521 // #i11860# - use new method <GetTopForObjPos>
522 // to get top of frame for object positioning.
523 const SwTwips nTopOfOrient =
524 GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
525 // Increase <nRelPosY> by margin height,
526 // if position is vertical aligned to "paragraph text area"
527 if ( aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
529 // #i11860# - consider upper space amount of previous frame
530 SwTwips nTopMargin = aRectFnSet.GetTopMargin(*pAnchorFrameForVertPos);
531 if ( pAnchorFrameForVertPos->IsTextFrame() )
533 nTopMargin -= pAnchorFrameForVertPos->
534 GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
536 nVertOffsetToFrameAnchorPos += nTopMargin;
538 // #i18732# - adjust <nRelPosY> by difference
539 // between 'page area' and 'anchor' frame, if position is
540 // vertical aligned to 'page areas'
541 else if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_FRAME
542 || aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_TOP)
544 nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(
545 aRectFnSet.GetTop(rPageAlignLayFrame.getFrameArea()),
546 nTopOfOrient );
548 else if ( aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
550 SwRect aPgPrtRect( rPageAlignLayFrame.getFrameArea() );
551 if ( rPageAlignLayFrame.IsPageFrame() )
553 aPgPrtRect =
554 static_cast<const SwPageFrame&>(rPageAlignLayFrame).PrtWithoutHeaderAndFooter();
556 nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(
557 aRectFnSet.GetTop(aPgPrtRect),
558 nTopOfOrient );
560 else if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
562 // The anchored object is relative from the bottom of the page's print area.
563 SwRect aPgPrtRect(rPageAlignLayFrame.getFrameArea());
564 if (rPageAlignLayFrame.IsPageFrame())
566 auto& rPageFrame = static_cast<const SwPageFrame&>(rPageAlignLayFrame);
567 aPgPrtRect = rPageFrame.PrtWithoutHeaderAndFooter();
569 SwTwips nPageBottom = aRectFnSet.GetBottom(aPgPrtRect);
570 nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(nPageBottom, nTopOfOrient);
572 nRelPosY = nVertOffsetToFrameAnchorPos + aVert.GetPos();
575 // <pUpperOfOrientFrame>: layout frame, at which the position has to
576 // is oriented at
577 // <nRelPosY>: rest of the relative distance in the current
578 // layout frame
579 // <nAvail>: space, which is available in the current
580 // layout frame
582 // #i26791# - determine offset to 'vertical'
583 // frame anchor position, depending on layout-direction
584 if ( aRectFnSet.IsVert() )
585 maOffsetToFrameAnchorPos.setX( nVertOffsetToFrameAnchorPos );
586 else
587 maOffsetToFrameAnchorPos.setY( nVertOffsetToFrameAnchorPos );
588 // #i11860# - use new method <GetTopForObjPos>
589 // to get top of frame for object positioning.
590 const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
591 if( nRelPosY <= 0 )
593 // Allow negative position, but keep it
594 // inside environment layout frame.
595 const SwLayoutFrame& rVertEnvironLayFrame =
596 aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
597 // #i31805# - do not check, if bottom of
598 // anchored object would fit into environment layout frame, if
599 // anchored object has to follow the text flow.
600 const bool bCheckBottom = !DoesObjFollowsTextFlow();
601 nRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
602 rVertEnvironLayFrame, nRelPosY,
603 DoesObjFollowsTextFlow(),
604 bCheckBottom );
605 if ( aRectFnSet.IsVert() )
606 aRelPos.setX( nRelPosY );
607 else
608 aRelPos.setY( nRelPosY );
610 else
612 aRectFnSet.Refresh(pAnchorFrameForVertPos);
613 SwTwips nAvail =
614 aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
615 nTopOfAnch );
616 const bool bInFootnote = pAnchorFrameForVertPos->IsInFootnote();
617 while ( nRelPosY )
619 // #i23512# - correction:
620 // consider section frame for grow in online layout.
621 // use new local method <lcl_DoesVertPosFits(..)>
622 SwLayoutFrame* pLayoutFrameToGrow = nullptr;
623 const bool bDoesVertPosFits = lcl_DoesVertPosFits(
624 nRelPosY, nAvail, pUpperOfOrientFrame, bBrowse,
625 bGrow, pLayoutFrameToGrow );
627 if ( bDoesVertPosFits )
629 SwTwips nTmpRelPosY =
630 aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
631 nTopOfAnch ) -
632 nAvail + nRelPosY;
633 // #i28701# - adjust calculated
634 // relative vertical position to object's environment.
635 const SwFrame& rVertEnvironLayFrame =
636 aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
637 // Do not check, if bottom of
638 // anchored object would fit into environment layout
639 // frame, if anchored object has to follow the text flow.
640 const bool bCheckBottom = !DoesObjFollowsTextFlow();
641 nTmpRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
642 rVertEnvironLayFrame,
643 nTmpRelPosY,
644 DoesObjFollowsTextFlow(),
645 bCheckBottom );
646 if ( aRectFnSet.IsVert() )
647 aRelPos.setX( nTmpRelPosY );
648 else
649 aRelPos.setY( nTmpRelPosY );
651 // #i23512# - use local variable
652 // <pLayoutFrameToGrow> provided by new method
653 // <lcl_DoesVertPosFits(..)>.
654 if ( pLayoutFrameToGrow )
656 // No need to grow the anchor cell in case the follow-text-flow object
657 // is wrap-though.
658 if (!GetAnchorFrame().IsInTab() || !DoesObjFollowsTextFlow() || !bWrapThrough)
660 pLayoutFrameToGrow->Grow( nRelPosY - nAvail );
663 nRelPosY = 0;
665 else
667 // #i26495# - floating screen objects,
668 // which are anchored inside a table, doesn't follow
669 // the text flow.
670 if ( DoesObjFollowsTextFlow() &&
671 ( aVert.GetRelationOrient() != text::RelOrientation::PAGE_FRAME &&
672 aVert.GetRelationOrient() != text::RelOrientation::PAGE_PRINT_AREA ) &&
673 !GetAnchorFrame().IsInTab() )
675 if ( bMoveable )
677 // follow the text flow
678 nRelPosY -= nAvail;
679 MakePageType eMakePage = bInFootnote ? MAKEPAGE_NONE
680 : MAKEPAGE_APPEND;
681 const bool bInSct = pUpperOfOrientFrame->IsInSct();
682 if( bInSct )
683 eMakePage = MAKEPAGE_NOSECTION;
685 const SwLayoutFrame* pTmp =
686 pUpperOfOrientFrame->GetLeaf( eMakePage, true, &rAnchorTextFrame );
687 if ( pTmp &&
688 ( !bInSct ||
689 pUpperOfOrientFrame->FindSctFrame()->IsAnFollow( pTmp->FindSctFrame() ) ) )
691 pUpperOfOrientFrame = pTmp;
692 bMoveable = rAnchorTextFrame.IsMoveable( pUpperOfOrientFrame );
693 aRectFnSet.Refresh(pUpperOfOrientFrame);
694 nAvail = aRectFnSet.GetHeight(pUpperOfOrientFrame->getFramePrintArea());
696 else
698 // if there isn't enough space in the (columned)
699 // section, leave it and set available space <nAvail>
700 // to the space below the section.
701 // if the new available space isn't also enough,
702 // new pages can be created.
703 if( bInSct )
705 const SwFrame* pSct = pUpperOfOrientFrame->FindSctFrame();
706 pUpperOfOrientFrame = pSct->GetUpper();
707 nAvail = aRectFnSet.YDiff(
708 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
709 aRectFnSet.GetPrtBottom(*pSct) );
711 else
713 #if OSL_DEBUG_LEVEL > 1
714 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - !bInSct" );
715 #endif
716 nRelDiff = nRelPosY;
717 nRelPosY = 0;
721 else
723 nRelPosY = 0;
726 else
728 // #i18732# - do not follow text flow respectively
729 // align at 'page areas', but stay inside given environment
730 const SwFrame& rVertEnvironLayFrame =
731 aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
732 nRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
733 rVertEnvironLayFrame,
734 nRelPosY,
735 DoesObjFollowsTextFlow() );
736 if( aRectFnSet.IsVert() )
737 aRelPos.setX( nRelPosY );
738 else
739 aRelPos.setY( nRelPosY );
740 nRelPosY = 0;
743 } // end of <while ( nRelPosY )>
744 } // end of else <nRelPosY <= 0>
745 } // end of <aVert.GetVertOrient() == text::VertOrientation::NONE>
747 // We need to calculate the part's absolute position, in order for
748 // it to be put onto the right page and to be pulled into the
749 // LayLeaf's PrtArea
750 const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
751 if( aRectFnSet.IsVert() )
753 // --> OD 2009-08-31 #monglianlayout#
754 if ( !aRectFnSet.IsVertL2R() )
756 GetAnchoredObj().SetObjLeft( nTopOfAnch -
757 ( aRelPos.X() - nRelDiff ) -
758 aObjBoundRect.Width() );
760 else
762 GetAnchoredObj().SetObjLeft( nTopOfAnch +
763 ( aRelPos.X() - nRelDiff ) );
766 else
768 GetAnchoredObj().SetObjTop( nTopOfAnch +
769 ( aRelPos.Y() - nRelDiff ) );
772 // grow environment under certain conditions
773 // ignore one-column sections.
774 // #i23512# - correction: also ignore one-columned
775 // sections with footnotes/endnotes
776 if ( pUpperOfOrientFrame->IsInSct() )
778 const SwSectionFrame* pSctFrame = pUpperOfOrientFrame->FindSctFrame();
779 const bool bIgnoreSection = pUpperOfOrientFrame->IsSctFrame() ||
780 ( pSctFrame->Lower()->IsColumnFrame() &&
781 !pSctFrame->Lower()->GetNext() );
782 if ( bIgnoreSection )
783 pUpperOfOrientFrame = pSctFrame->GetUpper();
785 SwTwips nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
786 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
787 if( nDist < 0 )
789 // #i23512# - correction:
790 // consider section frame for grow in online layout and
791 // consider page alignment for grow in table.
792 SwLayoutFrame* pLayoutFrameToGrow = nullptr;
793 if ( bBrowse && rAnchorTextFrame.IsMoveable() )
795 if ( pUpperOfOrientFrame->IsInSct() )
797 pLayoutFrameToGrow = const_cast<SwLayoutFrame*>(
798 pUpperOfOrientFrame->FindSctFrame()->GetUpper());
799 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
800 aRectFnSet.GetPrtBottom(*pLayoutFrameToGrow) );
801 if ( nDist >= 0 )
803 pLayoutFrameToGrow = nullptr;
806 else
808 pLayoutFrameToGrow =
809 const_cast<SwLayoutFrame*>(pUpperOfOrientFrame);
812 else if ( rAnchorTextFrame.IsInTab() && bGrow )
814 pLayoutFrameToGrow = const_cast<SwLayoutFrame*>(pUpperOfOrientFrame);
816 if ( pLayoutFrameToGrow )
818 // No need to grow the anchor cell in case the follow-text-flow object
819 // is wrap-though.
820 if (!GetAnchorFrame().IsInTab() || !DoesObjFollowsTextFlow() || !bWrapThrough)
822 pLayoutFrameToGrow->Grow( -nDist );
827 if ( DoesObjFollowsTextFlow() &&
828 ( aVert.GetRelationOrient() != text::RelOrientation::PAGE_FRAME &&
829 aVert.GetRelationOrient() != text::RelOrientation::PAGE_PRINT_AREA ) )
832 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
833 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
834 // #i26945# - floating screen objects, which are
835 // anchored inside a table, doesn't follow the text flow. But, they
836 // have to stay inside its layout environment.
837 if ( nDist < 0 && pOrientFrame->IsInTab() )
839 // If the anchor frame is the first content of the table cell
840 // and has no follow, the table frame is notified,
841 // that the object doesn't fit into the table cell.
842 // Adjustment of position isn't needed in this case.
843 if ( pOrientFrame == &rAnchorTextFrame &&
844 !pOrientFrame->GetFollow() &&
845 !pOrientFrame->GetIndPrev() )
847 const_cast<SwTabFrame*>(pOrientFrame->FindTabFrame())
848 ->SetDoesObjsFit( false );
850 else
852 SwTwips nTmpRelPosY( 0 );
853 if ( aRectFnSet.IsVert() )
854 nTmpRelPosY = aRelPos.X() - nDist;
855 else
856 nTmpRelPosY = aRelPos.Y() + nDist;
857 const SwLayoutFrame& rVertEnvironLayFrame =
858 aEnvOfObj.GetVertEnvironmentLayoutFrame( *pUpperOfOrientFrame );
859 nTmpRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
860 rVertEnvironLayFrame,
861 nTmpRelPosY,
862 DoesObjFollowsTextFlow(),
863 false );
864 if ( aRectFnSet.IsVert() )
866 aRelPos.setX( nTmpRelPosY );
867 // --> OD 2009-08-31 #mongolianlayout#
868 if ( !aRectFnSet.IsVertL2R() )
870 GetAnchoredObj().SetObjLeft( nTopOfAnch -
871 aRelPos.X() -
872 aObjBoundRect.Width() );
874 else
876 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
879 else
881 aRelPos.setY( nTmpRelPosY );
882 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
884 // If the anchor frame is the first content of the table cell
885 // and the object still doesn't fit, the table frame is notified,
886 // that the object doesn't fit into the table cell.
887 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
888 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
889 if ( nDist < 0 &&
890 pOrientFrame == &rAnchorTextFrame && !pOrientFrame->GetIndPrev() )
892 const_cast<SwTabFrame*>(pOrientFrame->FindTabFrame())
893 ->SetDoesObjsFit( false );
897 else
899 // follow text flow
900 const bool bInFootnote = rAnchorTextFrame.IsInFootnote();
901 while( bMoveable && nDist < 0 )
903 bool bInSct = pUpperOfOrientFrame->IsInSct();
904 if ( bInSct )
906 const SwLayoutFrame* pTmp = pUpperOfOrientFrame->FindSctFrame()->GetUpper();
907 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
908 aRectFnSet.GetPrtBottom(*pTmp) );
909 // #i23129# - Try to flow into next
910 // section|section column. Thus, do *not* leave section
911 // area, if anchored object doesn't fit into upper of section.
912 // But the anchored object is allowed to overlap bottom
913 // section|section column.
914 if ( nDist >= 0 )
916 break;
919 if ( !bInSct &&
920 aRectFnSet.GetTop(GetAnchoredObj().GetObjRect()) ==
921 aRectFnSet.GetPrtTop(*pUpperOfOrientFrame) )
922 // It doesn't fit, moving it would not help either anymore
923 break;
925 const SwLayoutFrame* pNextLay = pUpperOfOrientFrame->GetLeaf(
926 ( bInSct
927 ? MAKEPAGE_NOSECTION
928 : ( bInFootnote ? MAKEPAGE_NONE : MAKEPAGE_APPEND ) ),
929 true, &rAnchorTextFrame );
930 // correction:
931 // If anchor is in footnote and proposed next layout environment
932 // isn't a footnote frame, object can't follow the text flow
933 if ( bInFootnote && pNextLay && !pNextLay->IsFootnoteFrame() )
935 pNextLay = nullptr;
937 if ( pNextLay )
939 SwRectFnSet fnRectX(pNextLay);
940 if ( !bInSct ||
941 ( pUpperOfOrientFrame->FindSctFrame()->IsAnFollow( pNextLay->FindSctFrame() ) &&
942 fnRectX.GetHeight(pNextLay->getFramePrintArea()) ) )
944 SwTwips nTmpRelPosY =
945 aRectFnSet.YDiff( aRectFnSet.GetPrtTop(*pNextLay),
946 nTopOfAnch );
947 if ( aRectFnSet.IsVert() )
948 aRelPos.setX( nTmpRelPosY );
949 else
950 aRelPos.setY( nTmpRelPosY );
951 pUpperOfOrientFrame = pNextLay;
952 aRectFnSet.Refresh(pUpperOfOrientFrame);
953 bMoveable = rAnchorTextFrame.IsMoveable( pUpperOfOrientFrame );
954 if( fnRectX.IsVert() )
956 // --> OD 2009-08-31 #mongolianlayout#
957 if ( !aRectFnSet.IsVertL2R() )
959 GetAnchoredObj().SetObjLeft( nTopOfAnch -
960 aRelPos.X() -
961 aObjBoundRect.Width() );
963 else
965 GetAnchoredObj().SetObjLeft( nTopOfAnch +
966 aRelPos.X() );
969 else
970 GetAnchoredObj().SetObjTop( nTopOfAnch +
971 aRelPos.Y() );
972 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
973 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
975 // #i23129# - leave section area
976 else if ( bInSct )
978 const SwLayoutFrame* pTmp = pUpperOfOrientFrame->FindSctFrame()->GetUpper();
979 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
980 aRectFnSet.GetPrtBottom(*pTmp) );
981 if( nDist < 0 )
982 pUpperOfOrientFrame = pTmp;
983 else
984 break;
987 else if ( bInSct )
989 // If we don't have enough room within the Area, we take a look at
990 // the Page
991 const SwLayoutFrame* pTmp = pUpperOfOrientFrame->FindSctFrame()->GetUpper();
992 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
993 aRectFnSet.GetPrtBottom(*pTmp) );
994 if( nDist < 0 )
995 pUpperOfOrientFrame = pTmp;
996 else
997 break;
999 else
1000 bMoveable = false;
1005 // keep layout frame vertical position is oriented at.
1006 mpVertPosOrientFrame = pUpperOfOrientFrame;
1008 // If it was requested to not overlap with already formatted objects, take care of that
1009 // here.
1010 CalcOverlap(pAnchorFrameForVertPos, aRelPos, nTopOfAnch);
1013 // determine 'horizontal' position
1015 // determine horizontal positioning and alignment attributes
1016 SwFormatHoriOrient aHori( rFrameFormat.GetHoriOrient() );
1018 // set calculated vertical position in order to determine correct
1019 // frame, the horizontal position is oriented at.
1020 const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
1021 if( aRectFnSet.IsVert() )
1023 // --> OD 2009-08-31 #mongolianlayout#
1024 if ( !aRectFnSet.IsVertL2R() )
1026 GetAnchoredObj().SetObjLeft( nTopOfAnch -
1027 aRelPos.X() - aObjBoundRect.Width() );
1029 else
1031 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
1034 else
1035 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
1037 // determine frame, horizontal position is oriented at.
1038 // #i28701# - If floating screen object doesn't follow
1039 // the text flow, its horizontal position is oriented at <pOrientFrame>.
1040 const SwFrame* pHoriOrientFrame = DoesObjFollowsTextFlow()
1041 ? &GetHoriVirtualAnchor( *mpVertPosOrientFrame )
1042 : pOrientFrame;
1044 // #i26791# - get 'horizontal' offset to frame anchor position.
1045 SwTwips nHoriOffsetToFrameAnchorPos( 0 );
1046 SwTwips nRelPosX = CalcRelPosX( *pHoriOrientFrame, aEnvOfObj,
1047 aHori, rLR, rUL, bWrapThrough,
1048 ( aRectFnSet.IsVert() ? aRelPos.X() : aRelPos.Y() ),
1049 nHoriOffsetToFrameAnchorPos );
1051 // #i26791# - determine offset to 'horizontal' frame
1052 // anchor position, depending on layout-direction
1053 if ( aRectFnSet.IsVert() )
1055 aRelPos.setY( nRelPosX );
1056 maOffsetToFrameAnchorPos.setY( nHoriOffsetToFrameAnchorPos );
1058 else
1060 aRelPos.setX( nRelPosX );
1061 maOffsetToFrameAnchorPos.setX( nHoriOffsetToFrameAnchorPos );
1064 // save calculated horizontal position - needed for filters
1065 // (including the xml-filter)
1067 SwTwips nAttrRelPosX = nRelPosX - nHoriOffsetToFrameAnchorPos;
1068 if ( aHori.GetHoriOrient() != text::HoriOrientation::NONE &&
1069 aHori.GetPos() != nAttrRelPosX )
1071 aHori.SetPos( nAttrRelPosX );
1072 const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
1073 const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr( aHori );
1074 const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
1079 // set absolute position at object
1080 const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
1081 if( aRectFnSet.IsVert() )
1083 // --> OD 2009-08-31 #mongolianlayout#
1084 if ( !aRectFnSet.IsVertL2R() )
1086 GetAnchoredObj().SetObjLeft( nTopOfAnch -
1087 aRelPos.X() - aObjBoundRect.Width() );
1089 else
1091 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
1093 GetAnchoredObj().SetObjTop( rAnchorTextFrame.getFrameArea().Top() +
1094 aRelPos.Y() );
1096 else
1098 GetAnchoredObj().SetObjLeft( rAnchorTextFrame.getFrameArea().Left() +
1099 aRelPos.X() );
1100 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
1103 // set relative position at object
1104 GetAnchoredObj().SetCurrRelPos( aRelPos );
1107 void SwToContentAnchoredObjectPosition::CalcOverlap(const SwTextFrame* pAnchorFrameForVertPos,
1108 Point& rRelPos, const SwTwips nTopOfAnch)
1110 const SwFrameFormat& rFrameFormat = GetFrameFormat();
1111 bool bAllowOverlap = rFrameFormat.GetWrapInfluenceOnObjPos().GetAllowOverlap();
1112 if (bAllowOverlap)
1114 return;
1117 if (rFrameFormat.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH)
1119 // This is explicit wrap through: allowed to overlap.
1120 return;
1123 if (SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT))
1125 // This is the frame part of a textbox, just take the offset from the textbox's shape part.
1126 SwFrameFormat* pShapeOfTextBox
1127 = SwTextBoxHelper::getOtherTextBoxFormat(&rFrameFormat, RES_FLYFRMFMT);
1128 if (pShapeOfTextBox)
1130 SwTwips nYDiff = pShapeOfTextBox->GetWrapInfluenceOnObjPos().GetOverlapVertOffset();
1131 if (nYDiff > 0)
1133 rRelPos.setY(rRelPos.getY() + nYDiff + 1);
1134 GetAnchoredObj().SetObjTop(nTopOfAnch + rRelPos.Y());
1137 return;
1140 // Get the list of objects.
1141 auto pSortedObjs = pAnchorFrameForVertPos->GetDrawObjs();
1142 if (!pSortedObjs)
1144 return;
1147 for (const auto& pAnchoredObj : *pSortedObjs)
1149 if (pAnchoredObj == &GetAnchoredObj())
1151 // We found ourselves, stop iterating.
1152 break;
1155 if (SwTextBoxHelper::isTextBox(&pAnchoredObj->GetFrameFormat(), RES_FLYFRMFMT))
1157 // Overlapping with the frame of a textbox is fine.
1158 continue;
1161 css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat().GetSurround().GetSurround();
1162 if (eWrap == css::text::WrapTextMode_THROUGH)
1164 // The other object is wrap through: allowed to overlap.
1165 continue;
1168 if (!GetAnchoredObj().GetObjRect().IsOver(pAnchoredObj->GetObjRect()))
1170 // Found an already positioned object, but it doesn't overlap, ignore.
1171 continue;
1174 // Already formatted, overlaps: resolve the conflict by shifting ourselves down.
1175 SwTwips nYDiff = pAnchoredObj->GetObjRect().Bottom() - GetAnchoredObj().GetObjRect().Top();
1176 rRelPos.setY(rRelPos.getY() + nYDiff + 1);
1177 GetAnchoredObj().SetObjTop(nTopOfAnch + rRelPos.Y());
1179 // Store our offset that avoids the overlap. If this is a shape of a textbox, then the frame
1180 // of the textbox will use it.
1181 SwFormatWrapInfluenceOnObjPos aInfluence(rFrameFormat.GetWrapInfluenceOnObjPos());
1182 aInfluence.SetOverlapVertOffset(nYDiff);
1183 const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
1184 const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr(aInfluence);
1185 const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
1190 * Determine frame for horizontal position
1192 const SwFrame& SwToContentAnchoredObjectPosition::GetHoriVirtualAnchor(
1193 const SwLayoutFrame& _rProposedFrame ) const
1195 const SwFrame* pHoriVirtAnchFrame = &_rProposedFrame;
1197 // Search for first lower content frame, which is the anchor or a follow
1198 // of the anchor (Note: <Anchor.IsAnFollow( Anchor )> is true)
1199 // If none found, <_rProposedFrame> is returned.
1200 const SwFrame* pFrame = _rProposedFrame.Lower();
1201 while ( pFrame )
1203 if ( pFrame->IsContentFrame() &&
1204 GetAnchorTextFrame().IsAnFollow( static_cast<const SwContentFrame*>(pFrame) ) )
1206 pHoriVirtAnchFrame = pFrame;
1207 break;
1209 pFrame = pFrame->GetNext();
1212 return *pHoriVirtAnchFrame;
1216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */