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>
38#include <osl/diagnose.h>
40#include <frmatr.hxx>
42#include <sortedobjs.hxx>
43#include <textboxhelper.hxx>
44
45using namespace ::com::sun::star;
46
47namespace objectpositioning
48{
50 : SwAnchoredObjectPosition ( _rDrawObj ),
51 mpVertPosOrientFrame( nullptr ),
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{
70}
71
73{
74 return mpToCharRect;
75}
76
77// #i22341#
79{
80 return mnToCharTopOfLine;
81}
82
84{
85 assert( dynamic_cast<const SwTextFrame*>( &GetAnchorFrame()) &&
86 "SwToContentAnchoredObjectPosition::GetAnchorTextFrame() - wrong anchor frame type" );
87
88 return static_cast<SwTextFrame&>(GetAnchorFrame());
89}
90
91// #i23512#
92static 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() ) ||
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.
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
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 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;
259
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() )
275 {
276 case text::VertOrientation::CHAR_BOTTOM:
277 {
278 if ( mbAnchorToChar )
279 {
280 // bottom (to character anchored)
281 nRelPosY += nAlignAreaHeight + nUpperSpace;
282 if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
283 {
284 nRelPosY += nObjHeight;
285 }
286 break;
287 }
288 [[fallthrough]];
289 }
290 case text::VertOrientation::TOP:
291 {
292 // #i22341# - special case for vertical
293 // alignment at top of line
294 if ( mbAnchorToChar &&
295 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
296 {
297 nRelPosY -= (nObjHeight + nLowerSpace);
298 }
299 else
300 {
301 nRelPosY += nUpperSpace;
302 }
303 }
304 break;
305 // #i22341#
306 case text::VertOrientation::LINE_TOP:
307 {
308 if ( mbAnchorToChar &&
309 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
310 {
311 nRelPosY -= (nObjHeight + nLowerSpace);
312 }
313 else
314 {
315 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
316 }
317 }
318 break;
319 case text::VertOrientation::CENTER:
320 {
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);
325 }
326 break;
327 // #i22341#
328 case text::VertOrientation::LINE_CENTER:
329 {
330 if ( mbAnchorToChar &&
331 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
332 {
333 nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2);
334 }
335 else
336 {
337 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
338 }
339 }
340 break;
341 case text::VertOrientation::BOTTOM:
342 {
343 if ( ( aVert.GetRelationOrient() == text::RelOrientation::FRAME ||
344 aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
345 bNoSurround )
346 {
347 // bottom (aligned to 'paragraph areas')
348 nRelPosY += nAlignAreaHeight + nUpperSpace;
349 }
350 else
351 {
352 // #i22341# - special case for vertical
353 // alignment at top of line
354 if ( mbAnchorToChar &&
355 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
356 {
357 nRelPosY += nUpperSpace;
358 }
359 else
360 {
361 if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_TOP)
362 nRelPosY = 0 - (nObjHeight + nLowerSpace) + nHeightBetweenOffsetAndMargin;
363 else
364 nRelPosY += nAlignAreaHeight - (nObjHeight + nLowerSpace);
365 }
366 }
367 }
368 break;
369 // #i22341#
370 case text::VertOrientation::LINE_BOTTOM:
371 {
372 if ( mbAnchorToChar &&
373 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
374 {
375 nRelPosY += nUpperSpace;
376 }
377 else
378 {
379 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." );
380 }
381 }
382 break;
383 default:
384 break;
385 }
386
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 )
392 {
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() ) );
398 }
399
400 // #i42124# - capture object inside vertical
401 // layout environment.
402 {
403 const SwTwips nTopOfAnch =
404 GetTopForObjPos( *pOrientFrame, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
405 const SwLayoutFrame& rVertEnvironLayFrame =
407 *(pOrientFrame->GetUpper()) );
408 const bool bCheckBottom = !DoesObjFollowsTextFlow();
409 nRelPosY = AdjustVertRelPos( nTopOfAnch, aRectFnSet.IsVert(), aRectFnSet.IsVertL2R(),
410 rVertEnvironLayFrame, nRelPosY,
412 bCheckBottom );
413 }
414
415 // keep calculated relative vertical position - needed for filters
416 // (including the xml-filter)
417 {
418 // determine position
419 SwTwips nAttrRelPosY = nRelPosY - nAlignAreaOffset;
420 // set
421 if ( nAttrRelPosY != aVert.GetPos() )
422 {
423 aVert.SetPos( nAttrRelPosY );
424 const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
425 const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr( aVert );
426 const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
427 }
428 }
429
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() )
434 {
435 aRelPos.setX( nRelPosY );
436 maOffsetToFrameAnchorPos.setX( nAlignAreaOffset );
437 }
438 else
439 {
440 aRelPos.setY( nRelPosY );
441 maOffsetToFrameAnchorPos.setY( nAlignAreaOffset );
442 }
443 }
444
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;
450 {
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() &&
458 aVert.GetRelationOrient() != text::RelOrientation::CHAR &&
459 aVert.GetRelationOrient() != text::RelOrientation::TEXT_LINE ) )
460 {
461 pUpperOfOrientFrame = rAnchorTextFrame.GetUpper();
462 pAnchorFrameForVertPos = &rAnchorTextFrame;
463 }
464 else
465 {
466 pUpperOfOrientFrame = pOrientFrame->GetUpper();
467 pAnchorFrameForVertPos = pOrientFrame;
468 }
469 }
470
471 // ignore one-column sections.
472 // #i23512# - correction: also ignore one-columned
473 // sections with footnotes/endnotes
474 if ( pUpperOfOrientFrame->IsInSct() )
475 {
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();
482 }
483
485 {
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 ) )
498 {
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 )
503 {
504 nVertOffsetToFrameAnchorPos = aRectFnSet.YDiff(
505 aRectFnSet.GetBottom(*ToCharRect()),
506 nTopOfOrient );
507 }
508 else
509 {
510 nVertOffsetToFrameAnchorPos = aRectFnSet.YDiff( ToCharTopOfLine(),
511 nTopOfOrient );
512 }
513 nRelPosY = nVertOffsetToFrameAnchorPos - aVert.GetPos();
514 }
515 else
516 {
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 )
528 {
529 // #i11860# - consider upper space amount of previous frame
530 SwTwips nTopMargin = aRectFnSet.GetTopMargin(*pAnchorFrameForVertPos);
531 if ( pAnchorFrameForVertPos->IsTextFrame() )
532 {
533 nTopMargin -= pAnchorFrameForVertPos->
534 GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
535 }
536 nVertOffsetToFrameAnchorPos += nTopMargin;
537 }
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)
543 {
544 nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(
545 aRectFnSet.GetTop(rPageAlignLayFrame.getFrameArea()),
546 nTopOfOrient );
547 }
548 else if ( aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
549 {
550 SwRect aPgPrtRect( rPageAlignLayFrame.getFrameArea() );
551 if ( rPageAlignLayFrame.IsPageFrame() )
552 {
553 aPgPrtRect =
554 static_cast<const SwPageFrame&>(rPageAlignLayFrame).PrtWithoutHeaderAndFooter();
555 }
556 nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(
557 aRectFnSet.GetTop(aPgPrtRect),
558 nTopOfOrient );
559 }
560 else if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
561 {
562 // The anchored object is relative from the bottom of the page's print area.
563 SwRect aPgPrtRect(rPageAlignLayFrame.getFrameArea());
564 if (rPageAlignLayFrame.IsPageFrame())
565 {
566 auto& rPageFrame = static_cast<const SwPageFrame&>(rPageAlignLayFrame);
567 aPgPrtRect = rPageFrame.PrtWithoutHeaderAndFooter();
568 }
569 SwTwips nPageBottom = aRectFnSet.GetBottom(aPgPrtRect);
570 nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(nPageBottom, nTopOfOrient);
571 }
572 nRelPosY = nVertOffsetToFrameAnchorPos + aVert.GetPos();
573 }
574
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
581
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 )
592 {
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,
604 bCheckBottom );
605 if ( aRectFnSet.IsVert() )
606 aRelPos.setX( nRelPosY );
607 else
608 aRelPos.setY( nRelPosY );
609 }
610 else
611 {
612 aRectFnSet.Refresh(pAnchorFrameForVertPos);
613 SwTwips nAvail =
614 aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
615 nTopOfAnch );
616 const bool bInFootnote = pAnchorFrameForVertPos->IsInFootnote();
617 while ( nRelPosY )
618 {
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 );
626
627 if ( bDoesVertPosFits )
628 {
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,
645 bCheckBottom );
646 if ( aRectFnSet.IsVert() )
647 aRelPos.setX( nTmpRelPosY );
648 else
649 aRelPos.setY( nTmpRelPosY );
650
651 // #i23512# - use local variable
652 // <pLayoutFrameToGrow> provided by new method
653 // <lcl_DoesVertPosFits(..)>.
654 if ( pLayoutFrameToGrow )
655 {
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)
659 {
660 pLayoutFrameToGrow->Grow( nRelPosY - nAvail );
661 }
662 }
663 nRelPosY = 0;
664 }
665 else
666 {
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() )
674 {
675 if ( bMoveable )
676 {
677 // follow the text flow
678 nRelPosY -= nAvail;
679 MakePageType eMakePage = bInFootnote ? MAKEPAGE_NONE
681 const bool bInSct = pUpperOfOrientFrame->IsInSct();
682 if( bInSct )
683 eMakePage = MAKEPAGE_NOSECTION;
684
685 const SwLayoutFrame* pTmp =
686 pUpperOfOrientFrame->GetLeaf( eMakePage, true, &rAnchorTextFrame );
687 if ( pTmp &&
688 ( !bInSct ||
689 pUpperOfOrientFrame->FindSctFrame()->IsAnFollow( pTmp->FindSctFrame() ) ) )
690 {
691 pUpperOfOrientFrame = pTmp;
692 bMoveable = rAnchorTextFrame.IsMoveable( pUpperOfOrientFrame );
693 aRectFnSet.Refresh(pUpperOfOrientFrame);
694 nAvail = aRectFnSet.GetHeight(pUpperOfOrientFrame->getFramePrintArea());
695 }
696 else
697 {
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 )
704 {
705 const SwFrame* pSct = pUpperOfOrientFrame->FindSctFrame();
706 pUpperOfOrientFrame = pSct->GetUpper();
707 nAvail = aRectFnSet.YDiff(
708 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame),
709 aRectFnSet.GetPrtBottom(*pSct) );
710 }
711 else
712 {
713#if OSL_DEBUG_LEVEL > 1
714 OSL_FAIL( "<SwToContentAnchoredObjectPosition::CalcPosition()> - !bInSct" );
715#endif
716 nRelDiff = nRelPosY;
717 nRelPosY = 0;
718 }
719 }
720 }
721 else
722 {
723 nRelPosY = 0;
724 }
725 }
726 else
727 {
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,
736 if( aRectFnSet.IsVert() )
737 aRelPos.setX( nRelPosY );
738 else
739 aRelPos.setY( nRelPosY );
740 nRelPosY = 0;
741 }
742 }
743 } // end of <while ( nRelPosY )>
744 } // end of else <nRelPosY <= 0>
745 } // end of <aVert.GetVertOrient() == text::VertOrientation::NONE>
746
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() )
752 {
753 // --> OD 2009-08-31 #monglianlayout#
754 if ( !aRectFnSet.IsVertL2R() )
755 {
756 GetAnchoredObj().SetObjLeft( nTopOfAnch -
757 ( aRelPos.X() - nRelDiff ) -
758 aObjBoundRect.Width() );
759 }
760 else
761 {
762 GetAnchoredObj().SetObjLeft( nTopOfAnch +
763 ( aRelPos.X() - nRelDiff ) );
764 }
765 }
766 else
767 {
768 GetAnchoredObj().SetObjTop( nTopOfAnch +
769 ( aRelPos.Y() - nRelDiff ) );
770 }
771
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() )
777 {
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();
784 }
785 SwTwips nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
786 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
787 if( nDist < 0 )
788 {
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() )
794 {
795 if ( pUpperOfOrientFrame->IsInSct() )
796 {
797 pLayoutFrameToGrow = const_cast<SwLayoutFrame*>(
798 pUpperOfOrientFrame->FindSctFrame()->GetUpper());
799 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
800 aRectFnSet.GetPrtBottom(*pLayoutFrameToGrow) );
801 if ( nDist >= 0 )
802 {
803 pLayoutFrameToGrow = nullptr;
804 }
805 }
806 else
807 {
808 pLayoutFrameToGrow =
809 const_cast<SwLayoutFrame*>(pUpperOfOrientFrame);
810 }
811 }
812 else if ( rAnchorTextFrame.IsInTab() && bGrow )
813 {
814 pLayoutFrameToGrow = const_cast<SwLayoutFrame*>(pUpperOfOrientFrame);
815 }
816 if ( pLayoutFrameToGrow )
817 {
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)
821 {
822 pLayoutFrameToGrow->Grow( -nDist );
823 }
824 }
825 }
826
827 if ( DoesObjFollowsTextFlow() &&
828 ( aVert.GetRelationOrient() != text::RelOrientation::PAGE_FRAME &&
829 aVert.GetRelationOrient() != text::RelOrientation::PAGE_PRINT_AREA ) )
830 {
831
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() )
838 {
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() )
846 {
847 const_cast<SwTabFrame*>(pOrientFrame->FindTabFrame())
848 ->SetDoesObjsFit( false );
849 }
850 else
851 {
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,
863 false );
864 if ( aRectFnSet.IsVert() )
865 {
866 aRelPos.setX( nTmpRelPosY );
867 // --> OD 2009-08-31 #mongolianlayout#
868 if ( !aRectFnSet.IsVertL2R() )
869 {
870 GetAnchoredObj().SetObjLeft( nTopOfAnch -
871 aRelPos.X() -
872 aObjBoundRect.Width() );
873 }
874 else
875 {
876 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
877 }
878 }
879 else
880 {
881 aRelPos.setY( nTmpRelPosY );
882 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
883 }
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() )
891 {
892 const_cast<SwTabFrame*>(pOrientFrame->FindTabFrame())
893 ->SetDoesObjsFit( false );
894 }
895 }
896 }
897 else
898 {
899 // follow text flow
900 const bool bInFootnote = rAnchorTextFrame.IsInFootnote();
901 while( bMoveable && nDist < 0 )
902 {
903 bool bInSct = pUpperOfOrientFrame->IsInSct();
904 if ( bInSct )
905 {
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 )
915 {
916 break;
917 }
918 }
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;
924
925 const SwLayoutFrame* pNextLay = pUpperOfOrientFrame->GetLeaf(
926 ( bInSct
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() )
934 {
935 pNextLay = nullptr;
936 }
937 if ( pNextLay )
938 {
939 SwRectFnSet fnRectX(pNextLay);
940 if ( !bInSct ||
941 ( pUpperOfOrientFrame->FindSctFrame()->IsAnFollow( pNextLay->FindSctFrame() ) &&
942 fnRectX.GetHeight(pNextLay->getFramePrintArea()) ) )
943 {
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() )
955 {
956 // --> OD 2009-08-31 #mongolianlayout#
957 if ( !aRectFnSet.IsVertL2R() )
958 {
959 GetAnchoredObj().SetObjLeft( nTopOfAnch -
960 aRelPos.X() -
961 aObjBoundRect.Width() );
962 }
963 else
964 {
965 GetAnchoredObj().SetObjLeft( nTopOfAnch +
966 aRelPos.X() );
967 }
968 }
969 else
970 GetAnchoredObj().SetObjTop( nTopOfAnch +
971 aRelPos.Y() );
972 nDist = aRectFnSet.BottomDist( GetAnchoredObj().GetObjRect(),
973 aRectFnSet.GetPrtBottom(*pUpperOfOrientFrame) );
974 }
975 // #i23129# - leave section area
976 else if ( bInSct )
977 {
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;
985 }
986 }
987 else if ( bInSct )
988 {
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;
998 }
999 else
1000 bMoveable = false;
1001 }
1002 }
1003 }
1004
1005 // keep layout frame vertical position is oriented at.
1006 mpVertPosOrientFrame = pUpperOfOrientFrame;
1007
1008 // If it was requested to not overlap with already formatted objects, take care of that
1009 // here.
1010 CalcOverlap(pAnchorFrameForVertPos, aRelPos, nTopOfAnch);
1011 }
1012
1013 // determine 'horizontal' position
1014 {
1015 // determine horizontal positioning and alignment attributes
1016 SwFormatHoriOrient aHori( rFrameFormat.GetHoriOrient() );
1017
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() )
1022 {
1023 // --> OD 2009-08-31 #mongolianlayout#
1024 if ( !aRectFnSet.IsVertL2R() )
1025 {
1026 GetAnchoredObj().SetObjLeft( nTopOfAnch -
1027 aRelPos.X() - aObjBoundRect.Width() );
1028 }
1029 else
1030 {
1031 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
1032 }
1033 }
1034 else
1035 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
1036
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()
1042 : pOrientFrame;
1043
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 );
1050
1051 // #i26791# - determine offset to 'horizontal' frame
1052 // anchor position, depending on layout-direction
1053 if ( aRectFnSet.IsVert() )
1054 {
1055 aRelPos.setY( nRelPosX );
1056 maOffsetToFrameAnchorPos.setY( nHoriOffsetToFrameAnchorPos );
1057 }
1058 else
1059 {
1060 aRelPos.setX( nRelPosX );
1061 maOffsetToFrameAnchorPos.setX( nHoriOffsetToFrameAnchorPos );
1062 }
1063
1064 // save calculated horizontal position - needed for filters
1065 // (including the xml-filter)
1066 {
1067 SwTwips nAttrRelPosX = nRelPosX - nHoriOffsetToFrameAnchorPos;
1069 aHori.GetPos() != nAttrRelPosX )
1070 {
1071 aHori.SetPos( nAttrRelPosX );
1072 const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
1073 const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr( aHori );
1074 const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
1075 }
1076 }
1077 }
1078
1079 // set absolute position at object
1080 const SwTwips nTopOfAnch = GetTopForObjPos( *pAnchorFrameForVertPos, aRectFnSet.FnRect(), aRectFnSet.IsVert() );
1081 if( aRectFnSet.IsVert() )
1082 {
1083 // --> OD 2009-08-31 #mongolianlayout#
1084 if ( !aRectFnSet.IsVertL2R() )
1085 {
1086 GetAnchoredObj().SetObjLeft( nTopOfAnch -
1087 aRelPos.X() - aObjBoundRect.Width() );
1088 }
1089 else
1090 {
1091 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() );
1092 }
1093 GetAnchoredObj().SetObjTop( rAnchorTextFrame.getFrameArea().Top() +
1094 aRelPos.Y() );
1095 }
1096 else
1097 {
1098 GetAnchoredObj().SetObjLeft( rAnchorTextFrame.getFrameArea().Left() +
1099 aRelPos.X() );
1100 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() );
1101 }
1102
1103 // set relative position at object
1104 GetAnchoredObj().SetCurrRelPos( aRelPos );
1105}
1106
1108 Point& rRelPos, const SwTwips nTopOfAnch)
1109{
1110 const SwFrameFormat& rFrameFormat = GetFrameFormat();
1111 bool bAllowOverlap = rFrameFormat.GetWrapInfluenceOnObjPos().GetAllowOverlap();
1112 if (bAllowOverlap)
1113 {
1114 return;
1115 }
1116
1117 if (rFrameFormat.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH)
1118 {
1119 // This is explicit wrap through: allowed to overlap.
1120 return;
1121 }
1122
1123 if (SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT))
1124 {
1125 // This is the frame part of a textbox, just take the offset from the textbox's shape part.
1126 SwFrameFormat* pShapeOfTextBox
1128 if (pShapeOfTextBox)
1129 {
1130 SwTwips nYDiff = pShapeOfTextBox->GetWrapInfluenceOnObjPos().GetOverlapVertOffset();
1131 if (nYDiff > 0)
1132 {
1133 rRelPos.setY(rRelPos.getY() + nYDiff + 1);
1134 GetAnchoredObj().SetObjTop(nTopOfAnch + rRelPos.Y());
1135 }
1136 }
1137 return;
1138 }
1139
1140 // Get the list of objects.
1141 auto pSortedObjs = pAnchorFrameForVertPos->GetDrawObjs();
1142 if (!pSortedObjs)
1143 {
1144 return;
1145 }
1146
1147 for (const auto& pAnchoredObj : *pSortedObjs)
1148 {
1149 if (pAnchoredObj == &GetAnchoredObj())
1150 {
1151 // We found ourselves, stop iterating.
1152 break;
1153 }
1154
1155 if (SwTextBoxHelper::isTextBox(&pAnchoredObj->GetFrameFormat(), RES_FLYFRMFMT))
1156 {
1157 // Overlapping with the frame of a textbox is fine.
1158 continue;
1159 }
1160
1161 css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat().GetSurround().GetSurround();
1162 if (eWrap == css::text::WrapTextMode_THROUGH)
1163 {
1164 // The other object is wrap through: allowed to overlap.
1165 continue;
1166 }
1167
1168 if (!GetAnchoredObj().GetObjRect().Overlaps(pAnchoredObj->GetObjRect()))
1169 {
1170 // Found an already positioned object, but it doesn't overlap, ignore.
1171 continue;
1172 }
1173
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());
1178
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.
1182 aInfluence.SetOverlapVertOffset(nYDiff);
1183 const_cast<SwFrameFormat&>(rFrameFormat).LockModify();
1184 const_cast<SwFrameFormat&>(rFrameFormat).SetFormatAttr(aInfluence);
1185 const_cast<SwFrameFormat&>(rFrameFormat).UnlockModify();
1186 }
1187}
1188
1193 const SwLayoutFrame& _rProposedFrame ) const
1194{
1195 const SwFrame* pHoriVirtAnchFrame = &_rProposedFrame;
1196
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 )
1202 {
1203 if ( pFrame->IsContentFrame() &&
1204 GetAnchorTextFrame().IsAnFollow( static_cast<const SwContentFrame*>(pFrame) ) )
1205 {
1206 pHoriVirtAnchFrame = pFrame;
1207 break;
1208 }
1209 pFrame = pFrame->GetNext();
1210 }
1211
1212 return *pHoriVirtAnchFrame;
1213}
1214
1215}
1216
1217/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
tools::Long GetRight() const
tools::Long GetLeft() const
sal_uInt16 GetUpper() const
sal_uInt16 GetLower() const
void SetObjTop(const SwTwips _nTop)
void CheckCharRectAndTopOfLine(const bool _bCheckForParaPorInf)
check anchor character rectangle and top of line
void SetCurrRelPos(Point _aRelPos)
void SetObjLeft(const SwTwips _nLeft)
const SwRect & GetLastCharRect() const
SwTwips GetLastTopOfLine() const
virtual SwRect GetObjRect() const =0
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:58
FlyAnchors.
Definition: fmtanchr.hxx:37
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:74
sal_uInt8 GetHeightPercent() const
Definition: fmtfsize.hxx:88
Defines the horizontal position of a fly frame.
Definition: fmtornt.hxx:73
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:100
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:94
SwTwips GetPos() const
Definition: fmtornt.hxx:99
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
Defines the vertical position of a fly frame.
Definition: fmtornt.hxx:37
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:58
SwTwips GetPos() const
Definition: fmtornt.hxx:62
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:63
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:57
Allows positioning of floating screen objects without considering their own wrapping type and the wra...
void SetOverlapVertOffset(SwTwips nOverlapVertOffset)
const SwFormatWrapInfluenceOnObjPos & GetWrapInfluenceOnObjPos(bool=true) const
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:113
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:88
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:115
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:76
const SwRect & getFrameArea() const
Definition: frame.hxx:179
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
Style of a layout element.
Definition: frmfmt.hxx:62
Base class of the Writer layout elements.
Definition: frame.hxx:315
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1510
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed.
Definition: ssfrm.cxx:593
bool IsTextFrame() const
Definition: frame.hxx:1234
SwFrame * GetIndPrev() const
Definition: frame.hxx:724
bool IsInDocBody() const
Definition: frame.hxx:943
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
SwFrame * GetNext()
Definition: frame.hxx:676
bool IsPageFrame() const
Definition: frame.hxx:1178
bool IsColumnFrame() const
Definition: frame.hxx:1182
bool IsInFootnote() const
Definition: frame.hxx:949
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
bool IsInTab() const
Definition: frame.hxx:955
bool IsMoveable(const SwLayoutFrame *_pLayoutFrame=nullptr) const
determine, if frame is moveable in given environment
Definition: findfrm.cxx:1416
bool IsFooterFrame() const
Definition: frame.hxx:1194
bool IsFootnoteFrame() const
Definition: frame.hxx:1202
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
SwLayoutFrame * GetLeaf(MakePageType eMakePage, bool bFwd)
Definition: flowfrm.cxx:842
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
bool IsContentFrame() const
Definition: frame.hxx:1230
bool IsSctFrame() const
Definition: frame.hxx:1214
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:602
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:43
bool IsInSct() const
Definition: frame.hxx:967
Header in the document layout, inside a page.
Definition: hffrm.hxx:44
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Definition: layfrm.hxx:36
const SwFrame * Lower() const
Definition: layfrm.hxx:101
A page of the document layout.
Definition: pagefrm.hxx:58
const SwHeaderFrame * GetHeaderFrame() const
Definition: pagechg.cxx:2571
bool IsVert() const
Definition: frame.hxx:1366
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1402
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1376
SwRectFn FnRect() const
Definition: frame.hxx:1368
bool IsVertL2R() const
Definition: frame.hxx:1367
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1422
tools::Long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1408
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1377
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1413
void Refresh(const SwFrame *pFrame)
Definition: frame.hxx:1358
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1409
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Height(tools::Long nNew)
Definition: swrect.hxx:193
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:47
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
If we have an associated TextFrame, then return that.
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
Is the frame format a text box?
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:861
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1267
bool getBrowseMode() const
Definition: viewopt.hxx:580
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:433
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
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.
void GetVertAlignmentValues(const SwFrame &_rVertOrientFrame, const SwFrame &_rPageAlignLayFrame, const sal_Int16 _eRelOrient, SwTwips &_orAlignAreaHeight, SwTwips &_orAlignAreaOffset) 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
const SwLayoutFrame & GetVertEnvironmentLayoutFrame(const SwFrame &_rVertOrientFrame) const
determine environment layout frame for possible vertical object positions respectively for alignments...
const SwFrame & GetHoriVirtualAnchor(const SwLayoutFrame &_pProposedFrame) const
determine frame for horizontal position
virtual void CalcPosition() override
calculate position of object
void CalcOverlap(const SwTextFrame *pAnchorFrameForVertPos, Point &rRelPos, const SwTwips nTopOfAnch)
In case overlap is not allowed, re-position the current object.
MakePageType
Definition: frame.hxx:113
@ MAKEPAGE_NONE
Definition: frame.hxx:114
@ MAKEPAGE_NOSECTION
Definition: frame.hxx:118
@ MAKEPAGE_APPEND
Definition: frame.hxx:115
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(156)
tools::Long const nTopMargin
static bool lcl_DoesVertPosFits(const SwTwips _nRelPosY, const SwTwips _nAvail, const SwLayoutFrame *_pUpperOfOrientFrame, const bool _bBrowse, const bool _bGrowInTable, SwLayoutFrame *&_orpLayoutFrameToGrow)
tools::Long SwTwips
Definition: swtypes.hxx:51