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