LibreOffice Module sw (master)  1
anchoreddrawobject.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 
20 #include <dcontact.hxx>
21 #include <rootfrm.hxx>
22 #include <pagefrm.hxx>
25 #include <frmtool.hxx>
26 #include <fmtornt.hxx>
27 #include <txtfrm.hxx>
28 #include <vector>
29 #include <svx/svdogrp.hxx>
30 #include <tools/fract.hxx>
32 #include <IDocumentState.hxx>
33 #include <txtfly.hxx>
34 #include <viewimp.hxx>
35 #include <textboxhelper.hxx>
36 #include <unomid.h>
37 #include <svx/svdoashp.hxx>
38 #include <osl/diagnose.h>
39 
40 using namespace ::com::sun::star;
41 
42 namespace {
43 
46 class SwPosNotify
47 {
48  private:
49  SwAnchoredDrawObject* mpAnchoredDrawObj;
50  SwRect maOldObjRect;
51  SwPageFrame* mpOldPageFrame;
52 
53  public:
54  explicit SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj );
55  ~SwPosNotify() COVERITY_NOEXCEPT_FALSE;
56  // #i32795#
57  Point const & LastObjPos() const;
58 };
59 
60 }
61 
62 SwPosNotify::SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj ) :
63  mpAnchoredDrawObj( _pAnchoredDrawObj )
64 {
65  maOldObjRect = mpAnchoredDrawObj->GetObjRect();
66  // --> #i35640# - determine correct page frame
67  mpOldPageFrame = mpAnchoredDrawObj->GetPageFrame();
68 }
69 
70 SwPosNotify::~SwPosNotify() COVERITY_NOEXCEPT_FALSE
71 {
72  if ( maOldObjRect != mpAnchoredDrawObj->GetObjRect() )
73  {
74  if( maOldObjRect.HasArea() && mpOldPageFrame )
75  {
76  mpAnchoredDrawObj->NotifyBackground( mpOldPageFrame, maOldObjRect,
78  }
79  SwRect aNewObjRect( mpAnchoredDrawObj->GetObjRect() );
80  if( aNewObjRect.HasArea() )
81  {
82  // --> #i35640# - determine correct page frame
83  SwPageFrame* pNewPageFrame = mpAnchoredDrawObj->GetPageFrame();
84  if( pNewPageFrame )
85  mpAnchoredDrawObj->NotifyBackground( pNewPageFrame, aNewObjRect,
87  }
88 
89  ::ClrContourCache( mpAnchoredDrawObj->GetDrawObj() );
90 
91  // --> #i35640# - additional notify anchor text frame
92  // Needed for negative positioned drawing objects
93  // --> #i43255# - refine condition to avoid unneeded
94  // invalidations: anchored object had to be on the page of its anchor
95  // text frame.
96  if ( mpAnchoredDrawObj->GetAnchorFrame()->IsTextFrame() &&
97  mpOldPageFrame == mpAnchoredDrawObj->GetAnchorFrame()->FindPageFrame() )
98  {
99  mpAnchoredDrawObj->AnchorFrame()->Prepare( PrepareHint::FlyFrameLeave );
100  }
101 
102  // indicate a restart of the layout process
103  mpAnchoredDrawObj->SetRestartLayoutProcess( true );
104  }
105  else
106  {
107  // lock position
108  mpAnchoredDrawObj->LockPosition();
109 
110  if ( !mpAnchoredDrawObj->ConsiderForTextWrap() )
111  {
112  // indicate that object has to be considered for text wrap
113  mpAnchoredDrawObj->SetConsiderForTextWrap( true );
114  // invalidate 'background' in order to allow its 'background'
115  // to wrap around it.
116  mpAnchoredDrawObj->NotifyBackground( mpAnchoredDrawObj->GetPageFrame(),
117  mpAnchoredDrawObj->GetObjRectWithSpaces(),
119  // invalidate position of anchor frame in order to force
120  // a re-format of the anchor frame, which also causes a
121  // re-format of the invalid previous frames of the anchor frame.
122  mpAnchoredDrawObj->AnchorFrame()->InvalidatePos();
123  }
124  }
125  // tdf#101464 notify SwAccessibleMap about new drawing object position
126  if (mpOldPageFrame && mpOldPageFrame->getRootFrame()->IsAnyShellAccessible())
127  {
128  mpOldPageFrame->getRootFrame()->GetCurrShell()->Imp()->MoveAccessible(
129  nullptr, mpAnchoredDrawObj->GetDrawObj(), maOldObjRect);
130  }
131 }
132 
133 // --> #i32795#
134 Point const & SwPosNotify::LastObjPos() const
135 {
136  return maOldObjRect.Pos();
137 }
138 
139 namespace {
140 
141 // #i32795#
143 class SwObjPosOscillationControl
144 {
145  private:
146  const SwAnchoredDrawObject* mpAnchoredDrawObj;
147 
148  std::vector<Point> maObjPositions;
149 
150  public:
151  explicit SwObjPosOscillationControl( const SwAnchoredDrawObject& _rAnchoredDrawObj );
152 
153  bool OscillationDetected();
154 };
155 
156 }
157 
158 SwObjPosOscillationControl::SwObjPosOscillationControl(
159  const SwAnchoredDrawObject& _rAnchoredDrawObj )
160  : mpAnchoredDrawObj( &_rAnchoredDrawObj )
161 {
162 }
163 
164 bool SwObjPosOscillationControl::OscillationDetected()
165 {
166  bool bOscillationDetected = false;
167 
168  if ( maObjPositions.size() == 20 )
169  {
170  // position stack is full -> oscillation
171  bOscillationDetected = true;
172  }
173  else
174  {
175  Point aNewObjPos = mpAnchoredDrawObj->GetObjRect().Pos();
176  for ( auto const & pt : maObjPositions )
177  {
178  if ( aNewObjPos == pt )
179  {
180  // position already occurred -> oscillation
181  bOscillationDetected = true;
182  break;
183  }
184  }
185  if ( !bOscillationDetected )
186  {
187  maObjPositions.push_back( aNewObjPos );
188  }
189  }
190 
191  return bOscillationDetected;
192 }
193 
194 
197  mbValidPos( false ),
198  mbNotYetAttachedToAnchorFrame( true ),
199  // --> #i28749#
200  mbNotYetPositioned( true ),
201  // --> #i62875#
202  mbCaptureAfterLayoutDirChange( false )
203 {
204 }
205 
207 {
208 }
209 
210 // --> #i62875#
212 {
213  SwFrameFormat::tLayoutDir nOldLayoutDir( GetFrameFormat().GetLayoutDir() );
214 
216 
217  if ( !NotYetPositioned() &&
218  GetFrameFormat().GetLayoutDir() != nOldLayoutDir &&
219  GetFrameFormat().GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
220  !IsOutsidePage() )
221  {
223  }
224 }
225 
226 // --> #i62875#
228 {
229  bool bOutsidePage( false );
230 
231  if ( !NotYetPositioned() && GetPageFrame() )
232  {
233  SwRect aTmpRect( GetObjRect() );
234  bOutsidePage =
235  ( aTmpRect.Intersection( GetPageFrame()->getFrameArea() ) != GetObjRect() );
236  }
237 
238  return bOutsidePage;
239 }
240 
242 {
243  if ( IsPositioningInProgress() )
244  {
245  // nothing to do - positioning already in progress
246  return;
247  }
248 
249  if ( mbValidPos )
250  {
251  // nothing to do - position is valid
252  return;
253  }
254 
255  // --> #i28749# - anchored drawing object has to be attached
256  // to anchor frame
258  {
259  OSL_FAIL( "<SwAnchoredDrawObject::MakeObjPos() - drawing object not yet attached to anchor frame -> no positioning" );
260  return;
261  }
262 
263  SwDrawContact* pDrawContact =
264  static_cast<SwDrawContact*>(::GetUserCall( GetDrawObj() ));
265 
266  // --> #i28749# - if anchored drawing object hasn't been yet
267  // positioned, convert its positioning attributes, if its positioning
268  // attributes are given in horizontal left-to-right layout.
269  // --> #i36010# - Note: horizontal left-to-right layout is made
270  // the default layout direction for <SwDrawFrameFormat> instances. Thus, it has
271  // to be adjusted manually, if no adjustment of the positioning attributes
272  // have to be performed here.
273  // --> #i35635# - additionally move drawing object to the visible layer.
274  if ( mbNotYetPositioned )
275  {
276  // --> #i35635#
277  pDrawContact->MoveObjToVisibleLayer( DrawObj() );
278  // --> perform conversion of positioning
279  // attributes only for 'master' drawing objects
280  // #i44334#, #i44681# - check, if positioning
281  // attributes already have been set.
282  if ( dynamic_cast< const SwDrawVirtObj* >(GetDrawObj()) == nullptr &&
283  !static_cast<SwDrawFrameFormat&>(GetFrameFormat()).IsPosAttrSet() )
284  {
286  }
287  // -->
288  // - reset internal flag after all needed actions are performed to
289  // avoid callbacks from drawing layer
290  mbNotYetPositioned = false;
291  }
292 
293  // indicate that positioning is in progress
294  {
295  SwObjPositioningInProgress aObjPosInProgress( *this );
296 
297  // determine relative position of drawing object and set it
298  switch ( pDrawContact->GetAnchorId() )
299  {
300  case RndStdIds::FLY_AS_CHAR:
301  {
302  // indicate that position will be valid after positioning is performed
303  mbValidPos = true;
304  // nothing to do, because as-character anchored objects are positioned
305  // during the format of its anchor frame - see <SwFlyCntPortion::SetBase(..)>
306  }
307  break;
308  case RndStdIds::FLY_AT_PARA:
309  case RndStdIds::FLY_AT_CHAR:
310  {
311  // --> #i32795# - move intrinsic positioning to
312  // helper method <MakeObjPosAnchoredAtPara()>
314  }
315  break;
316  case RndStdIds::FLY_AT_PAGE:
317  case RndStdIds::FLY_AT_FLY:
318  {
319  // --> #i32795# - move intrinsic positioning to
320  // helper method <MakeObjPosAnchoredAtLayout()>
322  }
323  break;
324  default:
325  {
326  assert(!"<SwAnchoredDrawObject::MakeObjPos()> - unknown anchor type.");
327  }
328  }
329 
330  // keep, current object rectangle
331  // --> #i34748# - use new method <SetLastObjRect(..)>
332  SetLastObjRect( GetObjRect().SVRect() );
333 
334  // Assure for 'master' drawing object, that it's registered at the correct page.
335  // Perform check not for as-character anchored drawing objects and only if
336  // the anchor frame is valid.
337  if ( dynamic_cast< const SwDrawVirtObj* >(GetDrawObj()) == nullptr &&
338  !pDrawContact->ObjAnchoredAsChar() &&
340  {
341  pDrawContact->ChkPage();
342  }
343  }
344 
345  // --> #i62875#
347  GetPageFrame()) )
348  return;
349 
350  SwRect aPageRect( GetPageFrame()->getFrameArea() );
351  SwRect aObjRect( GetObjRect() );
352  if ( aObjRect.Right() >= aPageRect.Right() + 10 )
353  {
354  Size aSize( aPageRect.Right() - aObjRect.Right(), 0 );
355  DrawObj()->Move( aSize );
356  aObjRect = GetObjRect();
357  }
358 
359  if ( aObjRect.Left() + 10 <= aPageRect.Left() )
360  {
361  Size aSize( aPageRect.Left() - aObjRect.Left(), 0 );
362  DrawObj()->Move( aSize );
363  }
364 
366 }
367 
374 {
375  // --> #i32795# - adopt positioning algorithm from Writer
376  // fly frames, which are anchored at paragraph|at character
377 
378  // Determine, if anchor frame can/has to be formatted.
379  // If yes, after each object positioning the anchor frame is formatted.
380  // If after the anchor frame format the object position isn't valid, the
381  // object is positioned again.
382  // --> #i43255# - refine condition: anchor frame format not
383  // allowed, if another anchored object, has to be consider its wrap influence
384  // --> #i50356# - format anchor frame containing the anchor
385  // position. E.g., for at-character anchored object this can be the follow
386  // frame of the anchor frame, which contains the anchor character.
387  bool bJoinLocked
388  = static_cast<const SwTextFrame*>(GetAnchorFrameContainingAnchPos())->IsAnyJoinLocked();
389  const bool bFormatAnchor = !bJoinLocked && !ConsiderObjWrapInfluenceOnObjPos()
391 
392  // Format of anchor is needed for (vertical) fly offsets, otherwise the
393  // lack of fly portions will result in an incorrect 0 offset.
394  bool bAddVerticalFlyOffsets = GetFrameFormat().getIDocumentSettingAccess().get(
396  bool bFormatAnchorOnce = !bJoinLocked && bAddVerticalFlyOffsets;
397 
398  if (bFormatAnchor || bFormatAnchorOnce)
399  {
400  // --> #i50356#
401  GetAnchorFrameContainingAnchPos()->Calc(GetAnchorFrameContainingAnchPos()->getRootFrame()->GetCurrShell()->GetOut());
402  }
403 
404  bool bOscillationDetected = false;
405  SwObjPosOscillationControl aObjPosOscCtrl( *this );
406  // --> #i3317# - boolean, to apply temporarily the
407  // 'straightforward positioning process' for the frame due to its
408  // overlapping with a previous column.
409  bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
410  do {
411  // indicate that position will be valid after positioning is performed
412  mbValidPos = true;
413 
414  // --> #i35640# - correct scope for <SwPosNotify> instance
415  {
416  // create instance of <SwPosNotify> for correct notification
417  SwPosNotify aPosNotify( this );
418 
419  // determine and set position
421  aObjPositioning( *DrawObj() );
422  aObjPositioning.CalcPosition();
423 
424  // get further needed results of the positioning algorithm
425  SetVertPosOrientFrame ( aObjPositioning.GetVertPosOrientFrame() );
427 
428  // check for object position oscillation, if position has changed.
429  if ( GetObjRect().Pos() != aPosNotify.LastObjPos() )
430  {
431  bOscillationDetected = aObjPosOscCtrl.OscillationDetected();
432  }
433  }
434  // format anchor frame, if requested.
435  // Note: the format of the anchor frame can cause the object position
436  // to be invalid.
437  if ( bFormatAnchor )
438  {
439  // --> #i50356#
440  GetAnchorFrameContainingAnchPos()->Calc(GetAnchorFrameContainingAnchPos()->getRootFrame()->GetCurrShell()->GetOut());
441  }
442 
443  // --> #i3317#
446  {
447  bConsiderWrapInfluenceDueToOverlapPrevCol = true;
448  }
449  } while ( !mbValidPos && !bOscillationDetected &&
450  !bConsiderWrapInfluenceDueToOverlapPrevCol );
451 
452  // --> #i3317# - consider a detected oscillation and overlapping
453  // with previous column.
454  // temporarily consider the anchored objects wrapping style influence
455  if ( bOscillationDetected || bConsiderWrapInfluenceDueToOverlapPrevCol )
456  {
458  SetRestartLayoutProcess( true );
459  }
460 }
461 
468 {
469  // indicate that position will be valid after positioning is performed
470  mbValidPos = true;
471 
472  // create instance of <SwPosNotify> for correct notification
473  SwPosNotify aPosNotify( this );
474 
475  // determine position
477  aObjPositioning( *DrawObj() );
478  aObjPositioning.CalcPosition();
479 
480  // set position
481 
482  // --> #i31698#
483  // --> #i34995# - setting anchor position needed for filters,
484  // especially for the xml-filter to the OpenOffice.org file format
485  {
486  const Point aNewAnchorPos =
488  DrawObj()->SetAnchorPos( aNewAnchorPos );
489  // --> #i70122# - missing invalidation
491  }
492  SetCurrRelPos( aObjPositioning.GetRelPos() );
493  const SwFrame* pAnchorFrame = GetAnchorFrame();
494  SwRectFnSet aRectFnSet(pAnchorFrame);
495  const Point aAnchPos( aRectFnSet.GetPos(pAnchorFrame->getFrameArea()) );
496  SetObjLeft( aAnchPos.X() + GetCurrRelPos().X() );
497  SetObjTop( aAnchPos.Y() + GetCurrRelPos().Y() );
498 }
499 
501 {
502  // new anchor position
503  // --> #i31698# -
504  Point aNewAnchorPos =
506  Point aCurrAnchorPos = GetDrawObj()->GetAnchorPos();
507  if ( aNewAnchorPos != aCurrAnchorPos )
508  {
509  // determine movement to be applied after setting the new anchor position
510  Size aMove( aCurrAnchorPos.getX() - aNewAnchorPos.getX(),
511  aCurrAnchorPos.getY() - aNewAnchorPos.getY() );
512  // set new anchor position
513  DrawObj()->SetAnchorPos( aNewAnchorPos );
514  // correct object position, caused by setting new anchor position
515  DrawObj()->Move( aMove );
516  // --> #i70122# - missing invalidation
518  }
519 }
520 
526 {
527  if ( !_pPageFrame || _pPageFrame->GetFormat()->GetDoc()->IsInDtor() )
528  return;
529 
530  if ( !_pPageFrame->GetUpper() )
531  return;
532 
533  // --> #i35007# - correct invalidation for as-character
534  // anchored objects.
535  if ( GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR )
536  {
537  _pPageFrame->InvalidateFlyInCnt();
538  }
539  else
540  {
541  _pPageFrame->InvalidateFlyLayout();
542  }
543 
544  SwRootFrame* pRootFrame = static_cast<SwRootFrame*>(_pPageFrame->GetUpper());
545  pRootFrame->DisallowTurbo();
546  if ( pRootFrame->GetTurbo() )
547  {
548  const SwContentFrame* pTmpFrame = pRootFrame->GetTurbo();
549  pRootFrame->ResetTurbo();
550  pTmpFrame->InvalidatePage();
551  }
552  pRootFrame->SetIdleFlags();
553 }
554 
556 {
557  // --> #i28701# - check, if invalidation is allowed
558  if ( !(mbValidPos &&
560  return;
561 
562  mbValidPos = false;
563  // --> #i68520#
565 
566  // --> #i44339# - check, if anchor frame exists.
567  if ( !GetAnchorFrame() )
568  return;
569 
570  // --> #118547# - notify anchor frame of as-character
571  // anchored object, because its positioned by the format of its anchor frame.
572  // --> #i44559# - assure, that text hint is already
573  // existing in the text frame
574  if ( dynamic_cast< const SwTextFrame* >(GetAnchorFrame()) != nullptr &&
575  (GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) )
576  {
577  SwTextFrame* pAnchorTextFrame( static_cast<SwTextFrame*>(AnchorFrame()) );
578  if (pAnchorTextFrame->CalcFlyPos(&GetFrameFormat()) != TextFrameIndex(COMPLETE_STRING))
579  {
581  }
582  }
583 
584  SwPageFrame* pPageFrame = AnchorFrame()->FindPageFrame();
585  InvalidatePage_( pPageFrame );
586 
587  // --> #i32270# - also invalidate page frame, at which the
588  // drawing object is registered at.
589  SwPageFrame* pPageFrameRegisteredAt = GetPageFrame();
590  if ( pPageFrameRegisteredAt &&
591  pPageFrameRegisteredAt != pPageFrame )
592  {
593  InvalidatePage_( pPageFrameRegisteredAt );
594  }
595  // #i33751#, #i34060# - method <GetPageFrameOfAnchor()>
596  // is replaced by method <FindPageFrameOfAnchor()>. It's return value
597  // have to be checked.
598  SwPageFrame* pPageFrameOfAnchor = FindPageFrameOfAnchor();
599  if ( pPageFrameOfAnchor &&
600  pPageFrameOfAnchor != pPageFrame &&
601  pPageFrameOfAnchor != pPageFrameRegisteredAt )
602  {
603  InvalidatePage_( pPageFrameOfAnchor );
604  }
605 }
606 
608 {
609  assert(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat());
610  return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat());
611 }
613 {
614  assert(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat());
615  return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat());
616 }
617 
619 {
620  // use geometry of drawing object
621  //return GetDrawObj()->GetCurrentBoundRect();
622  return GetDrawObj()->GetSnapRect();
623 }
624 
625 namespace
626 {
627  // Imagine an open book, inside margin is the one that is at the inner side of the pages, at the center of the book,
628  // outside margin is at the two opposite edges of the book.
629  // outside --text-- inside | inside --text-- outside
630  // With mirrored margins, when relating the size of an object from the inside margin for example, on the
631  // first page we calculate the new size of the object using the size of the right margin,
632  // on second page the left margin, third page right margin, etc.
633  tools::Long getInsideOutsideRelativeWidth(bool isOutside, const SwPageFrame* const pPageFrame)
634  {
635  // Alternating between the only two possible cases: inside and outside.
636  // Inside = false, Outside = true.
637  auto nPageNum = pPageFrame->GetPhyPageNum();
638  if (nPageNum % 2 == (isOutside ? 0 : 1))
639  return pPageFrame->GetRightMargin();
640  else
641  return pPageFrame->GetLeftMargin();
642  }
643 }
644 
645 // --> #i70122#
647 {
648  bool bGroupShape = dynamic_cast<const SdrObjGroup*>( GetDrawObj() );
649  // Resize objects with relative width or height
650  if ( !bGroupShape && GetPageFrame( ) && ( GetDrawObj( )->GetRelativeWidth( ) || GetDrawObj()->GetRelativeHeight( ) ) )
651  {
652  tools::Rectangle aCurrObjRect = GetDrawObj()->GetCurrentBoundRect();
653 
654  tools::Long nTargetWidth = aCurrObjRect.GetWidth( );
655  if ( GetDrawObj( )->GetRelativeWidth( ) )
656  {
657  tools::Long nWidth = 0;
658  if (GetDrawObj()->GetRelativeWidthRelation() == text::RelOrientation::FRAME)
659  // Exclude margins.
660  nWidth = GetPageFrame()->getFramePrintArea().SVRect().GetWidth();
661  // Here we handle the relative size of the width of some shape.
662  // The size of the shape's width is going to be relative to the size of the left margin.
663  // E.g.: (left margin = 8 && relative size = 150%) -> width of some shape = 12.
664  else if (GetDrawObj()->GetRelativeWidthRelation() == text::RelOrientation::PAGE_LEFT)
665  {
666  if (GetPageFrame()->GetPageDesc()->GetUseOn() == UseOnPage::Mirror)
667  // We want to get the width of whatever is going through here using the size of the
668  // outside margin.
669  nWidth = getInsideOutsideRelativeWidth(true, GetPageFrame());
670  else
671  nWidth = GetPageFrame()->GetLeftMargin();
672  }
673  // Same as the left margin above.
674  else if (GetDrawObj()->GetRelativeWidthRelation() == text::RelOrientation::PAGE_RIGHT)
675  if (GetPageFrame()->GetPageDesc()->GetUseOn() == UseOnPage::Mirror)
676  // We want to get the width of whatever is going through here using the size of the
677  // inside margin.
678  nWidth = getInsideOutsideRelativeWidth(false, GetPageFrame());
679  else
680  nWidth = GetPageFrame()->GetRightMargin();
681  else
682  nWidth = GetPageFrame( )->GetBoundRect( GetPageFrame()->getRootFrame()->GetCurrShell()->GetOut() ).SVRect().GetWidth();
683  nTargetWidth = nWidth * (*GetDrawObj( )->GetRelativeWidth());
684  }
685 
686  bool bCheck = GetDrawObj()->GetRelativeHeight();
687  if (bCheck)
688  {
689  auto pObjCustomShape = dynamic_cast<const SdrObjCustomShape*>(GetDrawObj());
690  bCheck = !pObjCustomShape || !pObjCustomShape->IsAutoGrowHeight();
691  }
692 
693  tools::Long nTargetHeight = aCurrObjRect.GetHeight();
694  if (bCheck)
695  {
696  tools::Long nHeight = 0;
697  if (GetDrawObj()->GetRelativeHeightRelation() == text::RelOrientation::FRAME)
698  // Exclude margins.
699  nHeight = GetPageFrame()->getFramePrintArea().SVRect().GetHeight();
700  else if (GetDrawObj()->GetRelativeHeightRelation() == text::RelOrientation::PAGE_PRINT_AREA)
701  {
702  // count required height: print area top = top margin + header
703  SwRect aHeaderRect;
704  const SwHeaderFrame* pHeaderFrame = GetPageFrame()->GetHeaderFrame();
705  if (pHeaderFrame)
706  aHeaderRect = pHeaderFrame->GetPaintArea();
707  nHeight = GetPageFrame()->GetTopMargin() + aHeaderRect.Height();
708  }
709  else if (GetDrawObj()->GetRelativeHeightRelation() == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
710  {
711  // count required height: print area bottom = bottom margin + footer
712  SwRect aFooterRect;
713  auto pFooterFrame = GetPageFrame()->GetFooterFrame();
714  if (pFooterFrame)
715  aFooterRect = pFooterFrame->GetPaintArea();
716  nHeight = GetPageFrame()->GetBottomMargin() + aFooterRect.Height();
717  }
718  else
719  nHeight = GetPageFrame( )->GetBoundRect( GetPageFrame()->getRootFrame()->GetCurrShell()->GetOut() ).SVRect().GetHeight();
720  nTargetHeight = nHeight * (*GetDrawObj()->GetRelativeHeight());
721  }
722 
723  if ( nTargetWidth != aCurrObjRect.GetWidth( ) || nTargetHeight != aCurrObjRect.GetHeight( ) )
724  {
725  SwDoc* pDoc = const_cast<SwDoc*>(GetPageFrame()->GetFormat()->GetDoc());
726 
727  bool bEnableSetModified = pDoc->getIDocumentState().IsEnableSetModified();
729  auto pObject = const_cast<SdrObject*>(GetDrawObj());
730  pObject->Resize( aCurrObjRect.TopLeft(),
731  Fraction( nTargetWidth, aCurrObjRect.GetWidth() ),
732  Fraction( nTargetHeight, aCurrObjRect.GetHeight() ), false );
733 
734  if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject))
735  {
736  if (SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT))
737  {
738  // Shape has relative size and also a textbox, update its text area as well.
739  uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
741  uno::makeAny(xShape->getSize()));
742  }
743  }
744 
745  pDoc->getIDocumentState().SetEnableSetModified(bEnableSetModified);
746  }
747  }
748  return GetDrawObj()->GetCurrentBoundRect();
749 }
750 
751 // --> #i68520#
753 {
754  SwTwips nDiff = _nTop - GetObjRect().Top();
755  DrawObj()->Move( Size( 0, nDiff ) );
756 
757  return nDiff != 0;
758 }
760 {
761  SwTwips nDiff = _nLeft - GetObjRect().Left();
762  DrawObj()->Move( Size( nDiff, 0 ) );
763 
764  return nDiff != 0;
765 }
766 
772  const SwRect* _pNewObjRect )
773 {
774  SwTwips nHoriRelPos = 0;
775  SwTwips nVertRelPos = 0;
776  const Point aAnchorPos = _pNewAnchorFrame->GetFrameAnchorPos( ::HasWrap( GetDrawObj() ) );
777  // --> #i33313#
778  const SwRect aObjRect( _pNewObjRect ? *_pNewObjRect : GetObjRect() );
779  const bool bVert = _pNewAnchorFrame->IsVertical();
780  const bool bR2L = _pNewAnchorFrame->IsRightToLeft();
781  if ( bVert )
782  {
783  nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
784  nVertRelPos = aAnchorPos.X() - aObjRect.Right();
785  }
786  else if ( bR2L )
787  {
788  nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
789  nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
790  }
791  else
792  {
793  nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
794  nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
795  }
796 
797  SwFormatHoriOrient hori(nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME);
798  SwFormatVertOrient vert(nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME);
799  SfxItemSet items(GetFrameFormat().GetDoc()->GetAttrPool(), svl::Items<RES_VERT_ORIENT, RES_HORI_ORIENT>());
800  items.Put(hori);
801  items.Put(vert);
803 }
804 
805 // --> #i34748# - change return type.
806 // If member <mpLastObjRect> is NULL, create one.
808 {
809  maLastObjRect = _rNewLastRect;
810 }
811 
813 {
814  // --> #i31698#
816 
818  {
820  }
821 }
822 
833 {
834  SwDrawContact* pDrawContact =
835  static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() ));
836 
837  if ( !pDrawContact->ObjAnchoredAsChar() )
838  {
839  SwRect aObjRect( GetObjRect() );
840 
841  SwTwips nHoriPos = aObjRect.Left();
842  SwTwips nVertPos = aObjRect.Top();
843  // #i44334#, #i44681#
844  // perform conversion only if position is in horizontal-left-to-right-layout.
845  if ( GetFrameFormat().GetPositionLayoutDir() ==
846  text::PositionLayoutDir::PositionInHoriL2R )
847  {
849  switch ( eLayoutDir )
850  {
852  {
853  // nothing to do
854  }
855  break;
857  {
858  nHoriPos = -aObjRect.Left() - aObjRect.Width();
859  }
860  break;
862  {
863  nHoriPos = aObjRect.Top();
864  nVertPos = -aObjRect.Left() - aObjRect.Width();
865  }
866  break;
867  default:
868  {
869  assert(!"<SwAnchoredDrawObject::SetPositioningAttr()> - unsupported layout direction");
870  }
871  }
872  }
873 
874  // --> #i71182#
875  // only change position - do not lose other attributes
876 
877  SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() );
878  if (nHoriPos != aHori.GetPos()) {
879  aHori.SetPos( nHoriPos );
881  GetFrameFormat().SetFormatAttr( aHori );
882  }
883 
884  SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() );
885  if (nVertPos != aVert.GetPos()) {
886  aVert.SetPos( nVertPos );
888  GetFrameFormat().SetFormatAttr( aVert );
889  }
890 
891  // --> #i36010# - set layout direction of the position
893  text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
894  }
895  // --> #i65798# - also for as-character anchored objects
896  // --> #i45952# - indicate that position
897  // attributes are set now.
898  static_cast<SwDrawFrameFormat&>(GetFrameFormat()).PosAttrSet();
899 }
900 
902  const SwRect& _rRect,
903  PrepareHint _eHint )
904 {
905  ::Notify_Background( GetDrawObj(), _pPageFrame, _rRect, _eHint, true );
906 }
907 
914 {
915  SwPageFrame* pPageFrame( nullptr );
916  if ( GetVertPosOrientFrame() )
917  {
918  pPageFrame = const_cast<SwPageFrame*>(GetVertPosOrientFrame()->FindPageFrame());
919  }
920  if ( pPageFrame && GetPageFrame() != pPageFrame )
921  {
922  RegisterAtPage(*pPageFrame);
923  }
924 }
925 
927 {
928  assert(GetPageFrame() != &rPageFrame);
929  if (GetPageFrame())
930  {
932  }
933  rPageFrame.AppendDrawObjToPage( *this );
934 }
935 
936 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Base class of the Writer layout elements.
Definition: frame.hxx:313
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:157
bool OverlapsPrevColumn() const
method to determine, if the anchored object is overlapping with a previous column ...
void Right(const tools::Long nRight)
Definition: swrect.hxx:200
void ChkPage()
Definition: dcontact.cxx:1981
Point GetPos(const SwRect &rRect) const
Definition: frame.hxx:1379
class for the positioning of drawing objects
virtual const tools::Rectangle & GetCurrentBoundRect() const
virtual void NotifyBackground(SwPageFrame *_pPageFrame, const SwRect &_rRect, PrepareHint _eHint) override
method to notify background of drawing object
Header in the document layout, inside a page.
Definition: hffrm.hxx:43
bool IsAnyShellAccessible() const
Definition: rootfrm.hxx:388
SwViewShellImp * Imp()
Definition: viewsh.hxx:182
void Left(const tools::Long nLeft)
Definition: swrect.hxx:195
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:599
virtual void UpdateLayoutDir()
method update layout direction the layout direction, the anchored object is assigned to ...
SwTwips GetPos() const
Definition: fmtornt.hxx:92
long Long
const SwRect & getFramePrintArea() const
Definition: frame.hxx:179
void SetConsiderForTextWrap(const bool _bConsiderForTextWrap)
void RemoveDrawObjFromPage(SwAnchoredObject &_rToRemoveObj)
Definition: flylay.cxx:1079
Definition: doc.hxx:187
void InvalidatePage_(SwPageFrame *_pPageFrame)
method to invalidate the given page frame
void InvalidatePos()
Definition: frame.hxx:1039
void Pos(const Point &rNew)
Definition: swrect.hxx:169
Helper class for notify that positioning of an anchored object is in progress.
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Notify_Background(const SdrObject *pObj, SwPageFrame *pPage, const SwRect &rRect, const PrepareHint eHint, const bool bInva)
Definition: frmtool.cxx:3323
EmbeddedObjectRef * pObject
void MakeObjPosAnchoredAtLayout()
method for the intrinsic positioning of an at-page|at-frame anchored drawing object ...
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:171
void InvalidateFlyInCnt() const
Definition: pagefrm.hxx:372
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:170
virtual bool SetObjTop_(const SwTwips _nTop) override
virtual const tools::Rectangle & GetSnapRect() const
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:204
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed...
Definition: ssfrm.cxx:589
wrapper class for the positioning of Writer fly frames and drawing objects
virtual void InvalidateObjPos() override
method to invalidate position of the anchored object
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
void SetCurrRelPos(Point _aRelPos)
#define MID_FRMSIZE_SIZE
Definition: unomid.h:70
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual void SetAnchorPos(const Point &rPnt)
void SetAttr(const SfxPoolItem &, SwFormat &)
Set attribute in given format.1y If Undo is enabled, the old values is added to the Undo history...
Definition: docfmt.cxx:451
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:56
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType)
Is the frame format a text box?
void SetTmpConsiderWrapInfluence(const bool _bTmpConsiderWrapInfluence)
bool IsTextFrame() const
Definition: frame.hxx:1230
constexpr tools::Long GetWidth() const
void Width(tools::Long nNew)
Definition: swrect.hxx:187
SwFrameFormat * FindFrameFormat(SdrObject *pObj)
The Get reverse way: seeks the format to the specified object.
Definition: dcontact.cxx:120
virtual void ObjectAttachedToAnchorFrame()
method to indicate, that anchored object is attached to an anchor frame
SdrObject * DrawObj()
virtual bool IsEnableSetModified() const =0
void SetIdleFlags()
Definition: rootfrm.hxx:250
virtual void MoveObjToVisibleLayer(SdrObject *_pDrawObj)
method to move drawing object to corresponding visible layer
Definition: dcontact.cxx:209
SwFrame * AnchorFrame()
void SetObjTop(const SwTwips _nTop)
virtual void RegisterAtCorrectPage() override
method to assure that anchored object is registered at the correct page frame
virtual bool IsAutoGrowHeight() const override
void ResetTurbo()
Definition: rootfrm.hxx:350
bool ConsiderForTextWrap() const
virtual void ObjectAttachedToAnchorFrame() override
method to indicate, that anchored object is attached to an anchor frame
bool HasWrap(const SdrObject *pObj)
Definition: dcontact.cxx:139
virtual void CalcPosition() override
calculate position of object
Style of a layout element.
Definition: frmfmt.hxx:58
PrepareHint
Definition: swtypes.hxx:198
const SdrObject * GetDrawObj() const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
const SwFooterFrame * GetFooterFrame() const
Definition: pagechg.cxx:2561
virtual SwRect GetObjRect() const override
virtual SwFrameFormat::tLayoutDir GetLayoutDir() const
Definition: atrfrm.cxx:2781
SwRect GetBoundRect(OutputDevice const *pOutputDevice) const
Definition: paintfrm.cxx:6169
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
virtual void RegisterAtPage(SwPageFrame &) override
SwPageFrame * FindPageFrame()
Definition: frame.hxx:678
RndStdIds GetAnchorId() const
Definition: dcontact.hxx:145
void AppendDrawObjToPage(SwAnchoredObject &_rNewObj)
Definition: flylay.cxx:1030
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:60
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:609
SwLayoutFrame * GetUpper()
Definition: frame.hxx:676
bool HasArea() const
Definition: swrect.hxx:288
const SwRect & GetObjRectWithSpaces() const
method to determine object area inclusive its spacing
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
void SetDrawObjAnchor()
method to set internal anchor position of instance of the drawing object ...
virtual void Move(const Size &rSiz)
void SetLastObjRect(const tools::Rectangle &_rNewObjRect)
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:123
tools::Long GetBottomMargin() const
Definition: ssfrm.cxx:43
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document settings interface.
Definition: format.cxx:717
void InvalidateFlyLayout() const
Validate, invalidate and query the Page status Layout/Content and Fly/non-Fly respectively are inspec...
Definition: pagefrm.hxx:364
A page of the document layout.
Definition: pagefrm.hxx:57
const double * GetRelativeWidth() const
SwFrame * GetAnchorFrameContainingAnchPos()
determine anchor frame containing the anchor position
tools::Long SwTwips
Definition: swtypes.hxx:49
virtual ~SwAnchoredDrawObject() override
void MakeObjPosAnchoredAtPara()
method for the intrinsic positioning of an at-paragraph|at-character anchored drawing object ...
constexpr Point TopLeft() const
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:450
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SwLayoutFrame * GetVertPosOrientFrame() const
virtual SwFrameFormat & GetFrameFormat() override
const Point & GetCurrRelPos() const
tools::Rectangle SVRect() const
Definition: swrect.hxx:280
bool ConsiderObjWrapInfluenceOnObjPos() const
method to determine, if wrapping style influence of the anchored object has to be considered on the o...
bool InvalidationOfPosAllowed() const
method to determine, if invalidation of position is allowed
tools::Long GetRightMargin() const
Definition: ssfrm.cxx:47
SwPageFrame * FindPageFrameOfAnchor()
method to determine the page frame, on which the 'anchor' of the given anchored object is...
std::optional< tools::Rectangle > maLastObjRect
SwPageFrame * GetPageFrame()
void ClrContourCache(const SdrObject *pObj)
Definition: txtfly.cxx:134
SwTwips GetPos() const
Definition: fmtornt.hxx:59
virtual SwRect GetObjBoundRect() const override
void AdjustPositioningAttr(const SwFrame *_pNewAnchorFrame, const SwRect *_pNewObjRect=nullptr)
adjust positioning and alignment attributes for new anchor frame
bool IsRightToLeft() const
Definition: frame.hxx:983
void Top(const tools::Long nTop)
Definition: swrect.hxx:204
void InvalidateObjRectWithSpaces() const
bool ObjAnchoredAsChar() const
Definition: dcontact.hxx:150
TextFrameIndex CalcFlyPos(SwFrameFormat const *pSearch)
Calculates the position of FlyInContentFrames.
Definition: porfly.cxx:183
bool ConsiderObjWrapInfluenceOfOtherObjs() const
method to determine, if other anchored objects, also attached at to the anchor frame, have to consider its wrap influence.
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
const Point & GetAnchorPos() const
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:41
const SwContentFrame * GetTurbo() const
Definition: rootfrm.hxx:351
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:93
void SetObjLeft(const SwTwips _nLeft)
void DisallowTurbo() const
Definition: rootfrm.hxx:346
virtual void MakeObjPos() override
method to determine position for the object and set the position at the object
bool IsVertical() const
Definition: frame.hxx:969
virtual void SetEnableSetModified(bool bEnableSetModified)=0
bool IsInDtor() const
Definition: doc.hxx:403
static void syncProperty(SwFrameFormat *pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, const css::uno::Any &rValue)
Sync property of TextBox with the one of the shape.
virtual void UpdateLayoutDir() override
method update layout direction the layout direction, the anchored object is assigned to ...
void SetPositioningAttr()
method to set positioning attributes (not for as-character anchored)
const SwFrame * GetAnchorFrame() const
tools::Long GetLeftMargin() const
Definition: ssfrm.cxx:45
void SetVertPosOrientFrame(const SwLayoutFrame &_rVertPosOrientFrame)
virtual void CalcPosition() override
calculate position for object
const SwHeaderFrame * GetHeaderFrame() const
Definition: pagechg.cxx:2549
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
bool IsPositioningInProgress() const
is positioning of anchored object in progress
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
Point GetFrameAnchorPos(bool bIgnoreFlysAnchoredAtThisFrame) const
returns the position for anchors based on frame direction
Definition: ssfrm.cxx:291
virtual bool SetObjLeft_(const SwTwips _nLeft) override
void SetRestartLayoutProcess(const bool _bRestartLayoutProcess)
void Height(tools::Long nNew)
Definition: swrect.hxx:191
virtual void SetPositionLayoutDir(const sal_Int16 _nPositionLayoutDir)
Definition: atrfrm.cxx:2796
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:677
const Point & GetRelPos() const
calculated relative position for object
const SwLayoutFrame & GetVertPosOrientFrame() const
frame, at which the vertical position is oriented at
void MoveAccessible(const SwFrame *pFrame, const SdrObject *pObj, const SwRect &rOldFrame)
Move a frame's position in the accessible view.
Definition: viewimp.cxx:320
const double * GetRelativeHeight() const
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:395
constexpr tools::Long GetHeight() const