Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / layout / anchoredobject.cxx
blob5f8a307867bfea9bd4ab7f67853035c80807d9ad
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 <txtfrm.hxx>
21 #include <frmatr.hxx>
22 #include <fmtornt.hxx>
23 #include <doc.hxx>
24 #include <IDocumentSettingAccess.hxx>
25 #include <IDocumentDrawModelAccess.hxx>
26 #include <fmtsrnd.hxx>
27 #include <dcontact.hxx>
28 #include <editeng/ulspitem.hxx>
29 #include <editeng/lrspitem.hxx>
30 #include <sortedobjs.hxx>
31 #include <pagefrm.hxx>
32 #include <layouter.hxx>
33 #include <osl/diagnose.h>
34 #include <flyfrms.hxx>
36 using namespace ::com::sun::star;
38 // --> #i28701# -
39 // implementation of helper class <SwObjPositioningInProgress>
41 SwObjPositioningInProgress::SwObjPositioningInProgress( SdrObject& _rSdrObj ) :
42 mpAnchoredObj( nullptr ),
43 // --> #i52904#
44 mbOldObjPositioningInProgress( false )
46 mpAnchoredObj = ::GetUserCall( &_rSdrObj )->GetAnchoredObj( &_rSdrObj );
47 // --> #i52904#
48 mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
49 mpAnchoredObj->SetPositioningInProgress( true );
51 SwObjPositioningInProgress::SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj ) :
52 mpAnchoredObj( &_rAnchoredObj ),
53 // --> #i52904#
54 mbOldObjPositioningInProgress( false )
56 // --> #i52904#
57 mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
58 mpAnchoredObj->SetPositioningInProgress( true );
61 SwObjPositioningInProgress::~SwObjPositioningInProgress()
63 if ( mpAnchoredObj )
65 // --> #i52904#
66 mpAnchoredObj->SetPositioningInProgress( mbOldObjPositioningInProgress );
71 SwAnchoredObject::SwAnchoredObject() :
72 mpAnchorFrame( nullptr ),
73 // --> #i28701#
74 mpPageFrame( nullptr ),
75 mnLastTopOfLine( 0 ),
76 mpVertPosOrientFrame( nullptr ),
77 // --> #i28701#
78 mbPositioningInProgress( false ),
79 mbConsiderForTextWrap( false ),
80 mbPositionLocked( false ),
81 // --> #i40147#
82 mbKeepPositionLockedForSection( false ),
83 mbRestartLayoutProcess( false ),
84 // --> #i35911#
85 mbClearedEnvironment( false ),
86 // --> #i3317#
87 mbTmpConsiderWrapInfluence( false ),
88 mbObjRectWithSpacesValid( false )
92 void SwAnchoredObject::ClearVertPosOrientFrame()
94 if (mpVertPosOrientFrame)
96 const_cast<SwLayoutFrame*>(mpVertPosOrientFrame)->ClearVertPosOrientFrameFor(this);
97 mpVertPosOrientFrame = nullptr;
101 SwAnchoredObject::~SwAnchoredObject()
103 ClearVertPosOrientFrame();
106 void SwAnchoredObject::SetDrawObj( SdrObject& _rDrawObj )
108 mpDrawObj = &_rDrawObj;
112 void SwAnchoredObject::ChgAnchorFrame( SwFrame* _pNewAnchorFrame )
114 mpAnchorFrame = _pNewAnchorFrame;
116 if ( mpAnchorFrame )
118 ObjectAttachedToAnchorFrame();
122 /** determine anchor frame containing the anchor position
124 #i26945#
125 the anchor frame, which is determined, is <mpAnchorFrame>
126 for an at-page, at-frame or at-paragraph anchored object
127 and the anchor character frame for an at-character and as-character
128 anchored object.
130 SwFrame* SwAnchoredObject::GetAnchorFrameContainingAnchPos()
132 SwFrame* pAnchorFrameContainingAnchPos = FindAnchorCharFrame();
133 if ( !pAnchorFrameContainingAnchPos )
135 pAnchorFrameContainingAnchPos = AnchorFrame();
138 return pAnchorFrameContainingAnchPos;
142 void SwAnchoredObject::SetPageFrame( SwPageFrame* _pNewPageFrame )
144 if ( mpPageFrame == _pNewPageFrame )
145 return;
147 // clear member, which denotes the layout frame at which the vertical
148 // position is oriented at, if it doesn't fit to the new page frame.
149 if ( GetVertPosOrientFrame() &&
150 ( !_pNewPageFrame ||
151 _pNewPageFrame != GetVertPosOrientFrame()->FindPageFrame() ) )
153 ClearVertPosOrientFrame();
156 // assign new page frame
157 mpPageFrame = _pNewPageFrame;
161 SwTwips SwAnchoredObject::GetRelCharX( const SwFrame* pFrame ) const
163 return maLastCharRect.Left() - pFrame->getFrameArea().Left();
166 SwTwips SwAnchoredObject::GetRelCharY( const SwFrame* pFrame ) const
168 return maLastCharRect.Bottom() - pFrame->getFrameArea().Top();
171 void SwAnchoredObject::AddLastCharY( tools::Long nDiff )
173 maLastCharRect.Pos().AdjustY(nDiff );
176 void SwAnchoredObject::ResetLastCharRectHeight()
178 maLastCharRect.Height( 0 );
181 void SwAnchoredObject::SetVertPosOrientFrame( const SwLayoutFrame& _rVertPosOrientFrame )
183 ClearVertPosOrientFrame();
185 mpVertPosOrientFrame = &_rVertPosOrientFrame;
186 const_cast<SwLayoutFrame*>(mpVertPosOrientFrame)->SetVertPosOrientFrameFor(this);
188 // #i28701# - take over functionality of deleted method
189 // <SwFlyAtContentFrame::AssertPage()>: assure for at-paragraph and at-character
190 // an anchored object, that it is registered at the correct page frame
191 RegisterAtCorrectPage();
195 // #i28701# - follow-up of #i22341#
196 void SwAnchoredObject::AddLastTopOfLineY( SwTwips _nDiff )
198 mnLastTopOfLine += _nDiff;
201 /** check anchor character rectangle and top of line
203 #i26791
204 For to-character anchored Writer fly frames the members <maLastCharRect>
205 and <maLastTopOfLine> are updated. These are checked for change and
206 depending on the applied positioning, it's decided, if the Writer fly
207 frame has to be invalidated.
209 add parameter <_bCheckForParaPorInf>, default value <true>
211 void SwAnchoredObject::CheckCharRectAndTopOfLine(
212 const bool _bCheckForParaPorInf )
214 if ( !(GetAnchorFrame() &&
215 GetAnchorFrame()->IsTextFrame()) )
216 return;
218 const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor();
219 if ( !((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) &&
220 rAnch.GetAnchorNode()) )
221 return;
223 // --> if requested, assure that anchor frame,
224 // which contains the anchor character, has a paragraph portion information.
225 // The paragraph portion information is needed to determine the
226 // anchor character rectangle respectively the top of the line.
227 // Thus, a format of this frame is avoided to determine the
228 // paragraph portion information.
229 // --> #i26945# - use new method <FindAnchorCharFrame()>
230 const SwTextFrame& aAnchorCharFrame = *(FindAnchorCharFrame());
231 if ( !_bCheckForParaPorInf || aAnchorCharFrame.HasPara() )
233 CheckCharRect( rAnch, aAnchorCharFrame );
234 CheckTopOfLine( rAnch, aAnchorCharFrame );
238 /** check anchor character rectangle
240 #i22341#
241 helper method for method <CheckCharRectAndTopOfLine()>
242 For to-character anchored Writer fly frames the member <maLastCharRect>
243 is updated. This is checked for change and depending on the applied
244 positioning, it's decided, if the Writer fly frame has to be invalidated.
246 improvement - add second parameter <_rAnchorCharFrame>
248 void SwAnchoredObject::CheckCharRect( const SwFormatAnchor& _rAnch,
249 const SwTextFrame& _rAnchorCharFrame )
251 // determine rectangle of anchor character. If not exist, abort operation
252 SwRect aCharRect;
253 if ( !_rAnchorCharFrame.GetAutoPos( aCharRect, *_rAnch.GetContentAnchor() ) )
255 return;
257 // check, if anchor character rectangle has changed
258 if ( aCharRect == maLastCharRect )
259 return;
261 // check positioning and alignment for invalidation of position
263 SwRectFnSet aRectFnSet(&_rAnchorCharFrame);
264 // determine positioning and alignment
265 SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() );
266 SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() );
267 // check for anchor character rectangle changes for certain
268 // positionings and alignments
269 // add condition to invalidate position,
270 // if vertical aligned at frame/page area and vertical position
271 // of anchor character has changed.
272 const sal_Int16 eVertRelOrient = aVert.GetRelationOrient();
273 if ( ( aHori.GetRelationOrient() == text::RelOrientation::CHAR &&
274 aRectFnSet.GetLeft(aCharRect) != aRectFnSet.GetLeft(maLastCharRect) ) ||
275 ( eVertRelOrient == text::RelOrientation::CHAR &&
276 ( aRectFnSet.GetTop(aCharRect) != aRectFnSet.GetTop(maLastCharRect) ||
277 aRectFnSet.GetHeight(aCharRect) != aRectFnSet.GetHeight(maLastCharRect) ) ) ||
278 ( ( ( eVertRelOrient == text::RelOrientation::FRAME ) ||
279 ( eVertRelOrient == text::RelOrientation::PRINT_AREA ) ||
280 ( eVertRelOrient == text::RelOrientation::PAGE_FRAME ) ||
281 ( eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA ) ) &&
282 ( aRectFnSet.GetTop(aCharRect) != aRectFnSet.GetTop(maLastCharRect) ) ) )
284 // #i26945#, #i35911# - unlock position of
285 // anchored object, if it isn't registered at the page,
286 // where its anchor character frame is on.
287 if ( GetPageFrame() != _rAnchorCharFrame.FindPageFrame() )
289 UnlockPosition();
291 InvalidateObjPos();
294 // keep new anchor character rectangle
295 maLastCharRect = aCharRect;
298 /** check top of line
300 #i22341#
301 helper method for method <CheckCharRectAndTopOfLine()>
302 For to-character anchored Writer fly frames the member <mnLastTopOfLine>
303 is updated. This is checked for change and depending on the applied
304 positioning, it's decided, if the Writer fly frame has to be invalidated.
306 improvement - add second parameter <_rAnchorCharFrame>
308 void SwAnchoredObject::CheckTopOfLine( const SwFormatAnchor& _rAnch,
309 const SwTextFrame& _rAnchorCharFrame )
311 SwTwips nTopOfLine = 0;
312 if ( !_rAnchorCharFrame.GetTopOfLine( nTopOfLine, *_rAnch.GetContentAnchor() ) )
313 return;
315 if ( nTopOfLine == mnLastTopOfLine )
316 return;
318 // check alignment for invalidation of position
319 if ( GetFrameFormat().GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE )
321 // #i26945#, #i35911# - unlock position of
322 // anchored object, if it isn't registered at the page,
323 // where its anchor character frame is on.
324 if ( GetPageFrame() != _rAnchorCharFrame.FindPageFrame() )
326 UnlockPosition();
328 InvalidateObjPos();
330 // keep new top of line value
331 mnLastTopOfLine = nTopOfLine;
334 void SwAnchoredObject::ClearCharRectAndTopOfLine()
336 maLastCharRect.Clear();
337 mnLastTopOfLine = 0;
340 void SwAnchoredObject::SetCurrRelPos( Point _aRelPos )
342 maRelPos = _aRelPos;
345 void SwAnchoredObject::ObjectAttachedToAnchorFrame()
347 // default behaviour:
348 // update layout direction, the anchored object is assigned to
349 UpdateLayoutDir();
352 /** method update layout direction the layout direction, the anchored
353 object is in
355 #i31698#
356 method has typically to be called, if the anchored object gets its
357 anchor frame assigned.
359 void SwAnchoredObject::UpdateLayoutDir()
361 SwFrameFormat::tLayoutDir nLayoutDir = SwFrameFormat::HORI_L2R;
362 const SwFrame* pAnchorFrame = GetAnchorFrame();
363 if ( pAnchorFrame )
365 const bool bVert = pAnchorFrame->IsVertical();
366 const bool bR2L = pAnchorFrame->IsRightToLeft();
367 if ( bVert )
369 nLayoutDir = SwFrameFormat::VERT_R2L;
371 else if ( bR2L )
373 nLayoutDir = SwFrameFormat::HORI_R2L;
376 GetFrameFormat().SetLayoutDir( nLayoutDir );
379 /** method to perform necessary invalidations for the positioning of
380 objects, for whose the wrapping style influence has to be considered
381 on the object positioning.
383 #i28701#
385 void SwAnchoredObject::InvalidateObjPosForConsiderWrapInfluence()
387 if ( ConsiderObjWrapInfluenceOnObjPos() )
389 // indicate that object has not to be considered for text wrap
390 SetConsiderForTextWrap( false );
391 // unlock position
392 UnlockPosition();
393 // invalidate position
394 InvalidateObjPos();
395 // invalidate 'background'
396 NotifyBackground( GetPageFrame(), GetObjRectWithSpaces(), PrepareHint::FlyFrameLeave );
400 /** method to determine, if wrapping style influence of the anchored
401 object has to be considered on the object positioning
403 #i28701#
404 Note: result of this method also decides, if the booleans for the
405 layout process are of relevance.
407 bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const
409 bool bRet( false );
411 const SwFrameFormat& rObjFormat = GetFrameFormat();
413 // --> #i3317# - add condition <IsTmpConsiderWrapInfluence()>
414 // --> #i55204#
415 // - correction: wrapping style influence has been considered, if condition
416 // <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type
417 // or its wrapping style.
418 if ( IsTmpConsiderWrapInfluence() )
420 bRet = true;
422 else if ( rObjFormat.getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
424 const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor();
425 if ( ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) ||
426 (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)) &&
427 rObjFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH )
429 // --> #i34520# - text also wraps around anchored
430 // objects in the layer Hell - see the text formatting.
431 // Thus, it hasn't to be checked here.
432 bRet = true;
436 return bRet;
439 /** method to determine, if other anchored objects, also attached at
440 to the anchor frame, have to consider its wrap influence.
442 // --> #i43255#
444 bool SwAnchoredObject::ConsiderObjWrapInfluenceOfOtherObjs() const
446 bool bRet( false );
448 const SwSortedObjs* pObjs = GetAnchorFrame()->GetDrawObjs();
449 if ( pObjs->size() > 1 )
451 for (SwAnchoredObject* pAnchoredObj : *pObjs)
453 if ( pAnchoredObj != this &&
454 pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
456 bRet = true;
457 break;
462 return bRet;
465 bool SwAnchoredObject::ConsiderForTextWrap() const
467 if ( ConsiderObjWrapInfluenceOnObjPos() )
468 return mbConsiderForTextWrap;
469 else
470 return true;
473 void SwAnchoredObject::SetConsiderForTextWrap( const bool _bConsiderForTextWrap )
475 mbConsiderForTextWrap = _bConsiderForTextWrap;
478 bool SwAnchoredObject::PositionLocked() const
480 if ( ConsiderObjWrapInfluenceOnObjPos() )
481 return mbPositionLocked;
482 else
483 return false;
486 bool SwAnchoredObject::RestartLayoutProcess() const
488 if ( ConsiderObjWrapInfluenceOnObjPos() )
489 return mbRestartLayoutProcess;
490 else
491 return false;
494 void SwAnchoredObject::SetRestartLayoutProcess( const bool _bRestartLayoutProcess )
496 mbRestartLayoutProcess = _bRestartLayoutProcess;
499 // --> #i35911#
500 bool SwAnchoredObject::ClearedEnvironment() const
502 if ( ConsiderObjWrapInfluenceOnObjPos() )
503 return mbClearedEnvironment;
504 else
505 return false;
507 void SwAnchoredObject::SetClearedEnvironment( const bool _bClearedEnvironment )
509 mbClearedEnvironment = _bClearedEnvironment;
512 /** method to determine, if due to anchored object size and wrapping
513 style, its layout environment is cleared.
515 #i35911#
517 bool SwAnchoredObject::HasClearedEnvironment() const
519 bool bHasClearedEnvironment( false );
521 // --> #i43913# - layout frame, vertical position is orient at, has to be set.
522 OSL_ENSURE( GetVertPosOrientFrame(),
523 "<SwAnchoredObject::HasClearedEnvironment()> - layout frame missing, at which the vertical position is oriented at." );
524 if ( GetVertPosOrientFrame() &&
525 GetAnchorFrame()->IsTextFrame() &&
526 !static_cast<const SwTextFrame*>(GetAnchorFrame())->IsFollow() &&
527 static_cast<const SwTextFrame*>(GetAnchorFrame())->FindPageFrame()->GetPhyPageNum() >=
528 GetPageFrame()->GetPhyPageNum() )
530 const SwFrame* pTmpFrame = GetVertPosOrientFrame()->Lower();
531 while ( pTmpFrame && pTmpFrame->IsLayoutFrame() && !pTmpFrame->IsTabFrame() )
533 pTmpFrame = static_cast<const SwLayoutFrame*>(pTmpFrame)->Lower();
535 if ( !pTmpFrame )
537 bHasClearedEnvironment = true;
539 else if ( pTmpFrame->IsTextFrame() && !pTmpFrame->GetNext() )
541 const SwTextFrame* pTmpTextFrame = static_cast<const SwTextFrame*>(pTmpFrame);
542 if ( pTmpTextFrame->IsUndersized() ||
543 ( pTmpTextFrame->GetFollow() &&
544 pTmpTextFrame->GetFollow()->GetOffset() == TextFrameIndex(0)))
546 bHasClearedEnvironment = true;
551 return bHasClearedEnvironment;
554 /** method to add spacing to object area
556 #i28701#
557 #i68520# - return constant reference and use cache
559 const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const
561 if ( mbObjRectWithSpacesValid &&
562 maLastObjRect != GetObjRect() )
564 OSL_FAIL( "<SwAnchoredObject::GetObjRectWithSpaces> - cache for object rectangle inclusive spaces marked as valid, but it couldn't be. Missing invalidation of cache." );
565 InvalidateObjRectWithSpaces();
567 if ( !mbObjRectWithSpacesValid )
569 maObjRectWithSpaces = GetObjBoundRect();
570 const SwFrameFormat& rFormat = GetFrameFormat();
571 const SvxULSpaceItem& rUL = rFormat.GetULSpace();
572 const SvxLRSpaceItem& rLR = rFormat.GetLRSpace();
574 maObjRectWithSpaces.Top ( std::max( maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), tools::Long(0) ));
575 maObjRectWithSpaces.Left( std::max( maObjRectWithSpaces.Left()- rLR.GetLeft(), tools::Long(0) ));
576 maObjRectWithSpaces.AddHeight(rUL.GetLower() );
577 maObjRectWithSpaces.AddWidth(rLR.GetRight() );
580 mbObjRectWithSpacesValid = true;
581 maLastObjRect = GetObjRect();
584 return maObjRectWithSpaces;
587 // --> #i68520#
588 void SwAnchoredObject::SetObjTop( const SwTwips _nTop)
590 const bool bTopChanged( SetObjTop_( _nTop ) );
591 if ( bTopChanged )
593 mbObjRectWithSpacesValid = false;
597 void SwAnchoredObject::SetObjLeft( const SwTwips _nLeft)
599 const bool bLeftChanged( SetObjLeft_( _nLeft ) );
600 if ( bLeftChanged )
602 mbObjRectWithSpacesValid = false;
606 /** method to update anchored object in the <SwSortedObjs> lists
608 #i28701#
609 If document compatibility option 'Consider wrapping style influence
610 on object positioning' is ON, additionally all anchored objects
611 at the anchor frame and all following anchored objects on the page
612 frame are invalidated.
615 void SwAnchoredObject::UpdateObjInSortedList()
617 if(!GetAnchorFrame())
618 return;
620 if ( GetFrameFormat().getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
622 // invalidate position of all anchored objects at anchor frame
623 if ( GetAnchorFrame()->GetDrawObjs() )
625 const SwSortedObjs* pObjs = GetAnchorFrame()->GetDrawObjs();
626 for(auto it = pObjs->begin(); it != pObjs->end(); ++it)
628 SwAnchoredObject* pAnchoredObj = *it;
629 if(pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos())
630 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence();
631 else
632 pAnchoredObj->InvalidateObjPos();
635 // invalidate all following anchored objects on the page frame
636 if ( GetPageFrame() && GetPageFrame()->GetSortedObjs() )
638 const SwSortedObjs* pObjs = GetPageFrame()->GetSortedObjs();
639 // determine start index
640 for ( size_t i = pObjs->ListPosOf( *this ) + 1; i < pObjs->size(); ++i )
642 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
643 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
644 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence();
645 else
646 pAnchoredObj->InvalidateObjPos();
650 // update its position in the sorted object list of its anchor frame
651 AnchorFrame()->GetDrawObjs()->Update( *this );
652 // update its position in the sorted object list of its page frame
653 // note: as-character anchored object aren't registered at a page frame
654 if ( GetPageFrame() && GetPageFrame()->GetSortedObjs() &&
655 GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR )
657 GetPageFrame()->GetSortedObjs()->Update( *this );
661 /** method to determine, if invalidation of position is allowed
663 #i28701#
665 bool SwAnchoredObject::InvalidationOfPosAllowed() const
667 // --> Check, if page frame layout is in progress,
668 // isn't needed, because of anchored object, whose are moved forward.
669 return !PositionLocked();
672 /** method to determine the page frame, on which the 'anchor' of
673 the given anchored object is.
675 #i28701#
676 #i33751#, #i34060#
677 Adjust meaning of method and thus its name: If the anchored object
678 or its anchor isn't correctly inserted in the layout, no page frame
679 can be found. Thus, the return type changed to be a pointer and can
680 be NULL.
682 SwPageFrame* SwAnchoredObject::FindPageFrameOfAnchor()
684 SwPageFrame* pRetPageFrame = nullptr;
686 // --> #i44339# - check, if anchor frame exists.
687 if ( mpAnchorFrame )
689 // --> #i26945# - use new method <GetAnchorFrameContainingAnchPos()>
690 pRetPageFrame = GetAnchorFrameContainingAnchPos()->FindPageFrame();
693 return pRetPageFrame;
696 /** get frame, which contains the anchor character, if the object
697 is anchored at-character or as-character.
699 #i26945#
701 @return SwTextFrame*
702 text frame containing the anchor character. It's NULL, if the object
703 isn't anchored at-character resp. as-character.
705 SwTextFrame* SwAnchoredObject::FindAnchorCharFrame()
707 SwTextFrame* pAnchorCharFrame( nullptr );
709 // --> #i44339# - check, if anchor frame exists.
710 if ( mpAnchorFrame )
712 const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor();
713 if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) ||
714 (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR))
716 SwTextFrame *const pFrame(static_cast<SwTextFrame*>(AnchorFrame()));
717 TextFrameIndex const nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor()));
718 pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset);
720 else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame())
722 // See if this fly is split. If so, then the anchor is also split. All anchors are
723 // empty, except the last follow.
724 if (pFlyFrame->IsFlySplitAllowed())
726 auto pFlyAtContentFrame = static_cast<SwFlyAtContentFrame*>(pFlyFrame);
727 SwFlyAtContentFrame* pFly = pFlyAtContentFrame;
728 SwTextFrame* pAnchor = static_cast<SwTextFrame*>(AnchorFrame());
729 // If we have to jump back N frames to find the master fly, then we have to step N
730 // frames from the master anchor to reach the correct follow anchor.
731 while (pFly->GetPrecede())
733 pFly = pFly->GetPrecede();
734 if (!pAnchor)
736 SAL_WARN("sw.layout", "SwAnchoredObject::FindAnchorCharFrame: fly chain "
737 "length is longer then anchor chain length");
738 break;
740 pAnchor = pAnchor->GetFollow();
742 if (pAnchor)
744 pAnchorCharFrame = pAnchor;
750 return pAnchorCharFrame;
753 /** method to determine, if a format on the anchored object is possible
755 #i28701#
756 A format is possible, if anchored object is in an invisible layer.
757 Note: method is virtual to refine the conditions for the sub-classes.
759 bool SwAnchoredObject::IsFormatPossible() const
761 return GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetDrawObj()->GetLayer() );
764 bool SwAnchoredObject::IsDraggingOffPageAllowed(const SwFrameFormat* pFrameFormat)
766 OSL_ASSERT(pFrameFormat);
767 const bool bDisablePositioning = pFrameFormat->getIDocumentSettingAccess().get(DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING);
768 const bool bIsWrapThrough = pFrameFormat->GetSurround().GetSurround() == text::WrapTextMode::WrapTextMode_THROUGH;
770 return bDisablePositioning && bIsWrapThrough;
773 // --> #i3317#
774 void SwAnchoredObject::SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrapInfluence )
776 mbTmpConsiderWrapInfluence = _bTmpConsiderWrapInfluence;
777 // --> #i35911#
778 if ( mbTmpConsiderWrapInfluence )
780 SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrameFormat().GetDoc()),
781 *this );
785 void SwAnchoredObject::ClearTmpConsiderWrapInfluence()
787 mbTmpConsiderWrapInfluence = false;
788 mbClearedEnvironment = false;
789 SetClearedEnvironment( false );
790 SwLayouter::RemoveObjForTmpConsiderWrapInfluence( *(GetFrameFormat().GetDoc()),
791 *this );
793 void SwAnchoredObject::SetTmpConsiderWrapInfluenceOfOtherObjs()
795 const SwSortedObjs* pObjs = GetAnchorFrame()->GetDrawObjs();
796 if ( pObjs->size() > 1 )
798 for (SwAnchoredObject* pAnchoredObj : *pObjs)
800 if ( pAnchoredObj != this )
802 pAnchoredObj->SetTmpConsiderWrapInfluence( true/*bTmpConsiderWrapInfluence*/ );
808 /** method to determine, if the anchored object is overlapping with a
809 previous column
811 #i3317#
812 overlapping with a previous column means, that the object overlaps
813 with a column, which is a previous one of the column its anchor
814 frame is in.
815 Only applied for at-paragraph and at-character anchored objects.
817 bool SwAnchoredObject::OverlapsPrevColumn() const
819 bool bOverlapsPrevColumn( false );
821 if ( mpAnchorFrame && mpAnchorFrame->IsTextFrame() )
823 const SwFrame* pColFrame = mpAnchorFrame->FindColFrame();
824 if ( pColFrame && pColFrame->GetPrev() )
826 const SwFrame* pTmpColFrame = pColFrame->GetPrev();
827 SwRect aChkRect;
828 while ( pTmpColFrame )
830 aChkRect.Union( pTmpColFrame->getFrameArea() );
831 pTmpColFrame = pTmpColFrame->GetPrev();
833 bOverlapsPrevColumn = GetObjRect().Overlaps( aChkRect );
837 return bOverlapsPrevColumn;
840 /** method to determine position of anchored object relative to
841 anchor frame
843 #i30669#
844 Usage: Needed layout information for WW8 export
846 Point SwAnchoredObject::GetRelPosToAnchorFrame() const
848 Point aRelPos;
850 assert(GetAnchorFrame());
851 aRelPos = GetObjRect().Pos();
852 aRelPos -= GetAnchorFrame()->getFrameArea().Pos();
854 return aRelPos;
857 /** method to determine position of anchored object relative to
858 page frame
860 #i30669#
861 Usage: Needed layout information for WW8 export
862 #i33818# - add parameters <_bFollowTextFlow> and
863 <_obRelToTableCell>
864 If <_bFollowTextFlow> is set and object is anchored inside table,
865 the position relative to the table cell is determined. Output
866 parameter <_obRelToTableCell> reflects this situation
868 Point SwAnchoredObject::GetRelPosToPageFrame( const bool _bFollowTextFlow,
869 bool& _obRelToTableCell ) const
871 Point aRelPos;
872 _obRelToTableCell = false;
874 assert(GetAnchorFrame());
875 assert(GetAnchorFrame()->FindPageFrame());
877 aRelPos = GetObjRect().Pos();
878 // --> #i33818# - search for cell frame, if object has to
879 // follow the text flow.
880 const SwFrame* pFrame( nullptr );
881 if ( _bFollowTextFlow && !GetAnchorFrame()->IsPageFrame() )
883 pFrame = GetAnchorFrame()->GetUpper();
884 while ( !pFrame->IsCellFrame() && !pFrame->IsPageFrame() )
886 pFrame = pFrame->GetUpper();
889 else
891 pFrame = GetAnchorFrame()->FindPageFrame();
893 if ( pFrame->IsCellFrame() )
895 aRelPos -= pFrame->getFrameArea().Pos() + pFrame->getFramePrintArea().Pos();
896 _obRelToTableCell = true;
898 else
900 aRelPos -= pFrame->getFrameArea().Pos();
903 return aRelPos;
906 /** method to determine position of anchored object relative to
907 anchor character
909 #i30669#
910 Usage: Needed layout information for WW8 export
912 Point SwAnchoredObject::GetRelPosToChar() const
914 Point aRelPos = GetObjRect().Pos();
915 aRelPos -= GetLastCharRect().Pos();
917 return aRelPos;
920 /** method to determine position of anchored object relative to
921 top of line
923 #i30669#
924 Usage: Needed layout information for WW8 export
926 Point SwAnchoredObject::GetRelPosToLine() const
928 Point aRelPos = GetObjRect().Pos();
929 aRelPos.AdjustY( -(GetLastTopOfLine()) );
931 return aRelPos;
934 const SwFlyFrame* SwAnchoredObject::DynCastFlyFrame() const
936 return nullptr;
939 SwFlyFrame* SwAnchoredObject::DynCastFlyFrame()
941 return nullptr;
944 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */