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  return;
348 
349  SwRect aPageRect( GetPageFrame()->getFrameArea() );
350  SwRect aObjRect( GetObjRect() );
351  if ( aObjRect.Right() >= aPageRect.Right() + 10 )
352  {
353  Size aSize( aPageRect.Right() - aObjRect.Right(), 0 );
354  DrawObj()->Move( aSize );
355  aObjRect = GetObjRect();
356  }
357 
358  if ( aObjRect.Left() + 10 <= aPageRect.Left() )
359  {
360  Size aSize( aPageRect.Left() - aObjRect.Left(), 0 );
361  DrawObj()->Move( aSize );
362  }
363 
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  return;
528 
529  if ( !_pPageFrame->GetUpper() )
530  return;
531 
532  // --> #i35007# - correct invalidation for as-character
533  // anchored objects.
534  if ( GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR )
535  {
536  _pPageFrame->InvalidateFlyInCnt();
537  }
538  else
539  {
540  _pPageFrame->InvalidateFlyLayout();
541  }
542 
543  SwRootFrame* pRootFrame = static_cast<SwRootFrame*>(_pPageFrame->GetUpper());
544  pRootFrame->DisallowTurbo();
545  if ( pRootFrame->GetTurbo() )
546  {
547  const SwContentFrame* pTmpFrame = pRootFrame->GetTurbo();
548  pRootFrame->ResetTurbo();
549  pTmpFrame->InvalidatePage();
550  }
551  pRootFrame->SetIdleFlags();
552 }
553 
555 {
556  // --> #i28701# - check, if invalidation is allowed
557  if ( !(mbValidPos &&
559  return;
560 
561  mbValidPos = false;
562  // --> #i68520#
564 
565  // --> #i44339# - check, if anchor frame exists.
566  if ( !GetAnchorFrame() )
567  return;
568 
569  // --> #118547# - notify anchor frame of as-character
570  // anchored object, because its positioned by the format of its anchor frame.
571  // --> #i44559# - assure, that text hint is already
572  // existing in the text frame
573  if ( dynamic_cast< const SwTextFrame* >(GetAnchorFrame()) != nullptr &&
574  (GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) )
575  {
576  SwTextFrame* pAnchorTextFrame( static_cast<SwTextFrame*>(AnchorFrame()) );
577  if (pAnchorTextFrame->CalcFlyPos(&GetFrameFormat()) != TextFrameIndex(COMPLETE_STRING))
578  {
580  }
581  }
582 
583  SwPageFrame* pPageFrame = AnchorFrame()->FindPageFrame();
584  InvalidatePage_( pPageFrame );
585 
586  // --> #i32270# - also invalidate page frame, at which the
587  // drawing object is registered at.
588  SwPageFrame* pPageFrameRegisteredAt = GetPageFrame();
589  if ( pPageFrameRegisteredAt &&
590  pPageFrameRegisteredAt != pPageFrame )
591  {
592  InvalidatePage_( pPageFrameRegisteredAt );
593  }
594  // #i33751#, #i34060# - method <GetPageFrameOfAnchor()>
595  // is replaced by method <FindPageFrameOfAnchor()>. It's return value
596  // have to be checked.
597  SwPageFrame* pPageFrameOfAnchor = FindPageFrameOfAnchor();
598  if ( pPageFrameOfAnchor &&
599  pPageFrameOfAnchor != pPageFrame &&
600  pPageFrameOfAnchor != pPageFrameRegisteredAt )
601  {
602  InvalidatePage_( pPageFrameOfAnchor );
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  tools::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  tools::Long nTargetWidth = aCurrObjRect.GetWidth( );
654  if ( GetDrawObj( )->GetRelativeWidth( ) )
655  {
656  tools::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  bool bCheck = GetDrawObj()->GetRelativeHeight();
686  if (bCheck)
687  {
688  auto pObjCustomShape = dynamic_cast<const SdrObjCustomShape*>(GetDrawObj());
689  bCheck = !pObjCustomShape || !pObjCustomShape->IsAutoGrowHeight();
690  }
691 
692  tools::Long nTargetHeight = aCurrObjRect.GetHeight();
693  if (bCheck)
694  {
695  tools::Long nHeight = 0;
696  if (GetDrawObj()->GetRelativeHeightRelation() == text::RelOrientation::FRAME)
697  // Exclude margins.
698  nHeight = GetPageFrame()->getFramePrintArea().SVRect().GetHeight();
699  else if (GetDrawObj()->GetRelativeHeightRelation() == text::RelOrientation::PAGE_PRINT_AREA)
700  {
701  // count required height: print area top = top margin + header
702  SwRect aHeaderRect;
703  const SwHeaderFrame* pHeaderFrame = GetPageFrame()->GetHeaderFrame();
704  if (pHeaderFrame)
705  aHeaderRect = pHeaderFrame->GetPaintArea();
706  nHeight = GetPageFrame()->GetTopMargin() + aHeaderRect.Height();
707  }
708  else if (GetDrawObj()->GetRelativeHeightRelation() == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
709  {
710  // count required height: print area bottom = bottom margin + footer
711  SwRect aFooterRect;
712  auto pFooterFrame = GetPageFrame()->GetFooterFrame();
713  if (pFooterFrame)
714  aFooterRect = pFooterFrame->GetPaintArea();
715  nHeight = GetPageFrame()->GetBottomMargin() + aFooterRect.Height();
716  }
717  else
718  nHeight = GetPageFrame( )->GetBoundRect( GetPageFrame()->getRootFrame()->GetCurrShell()->GetOut() ).SVRect().GetHeight();
719  nTargetHeight = nHeight * (*GetDrawObj()->GetRelativeHeight());
720  }
721 
722  if ( nTargetWidth != aCurrObjRect.GetWidth( ) || nTargetHeight != aCurrObjRect.GetHeight( ) )
723  {
724  SwDoc* pDoc = const_cast<SwDoc*>(GetPageFrame()->GetFormat()->GetDoc());
725 
726  bool bEnableSetModified = pDoc->getIDocumentState().IsEnableSetModified();
728  auto pObject = const_cast<SdrObject*>(GetDrawObj());
729  pObject->Resize( aCurrObjRect.TopLeft(),
730  Fraction( nTargetWidth, aCurrObjRect.GetWidth() ),
731  Fraction( nTargetHeight, aCurrObjRect.GetHeight() ), false );
732 
733  if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject))
734  {
735  if (SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT))
736  {
737  // Shape has relative size and also a textbox, update its text area as well.
738  uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
740  uno::makeAny(xShape->getSize()));
741  }
742  }
743 
744  pDoc->getIDocumentState().SetEnableSetModified(bEnableSetModified);
745  }
746  }
747  return GetDrawObj()->GetCurrentBoundRect();
748 }
749 
750 // --> #i68520#
752 {
753  SwTwips nDiff = _nTop - GetObjRect().Top();
754  DrawObj()->Move( Size( 0, nDiff ) );
755 
756  return nDiff != 0;
757 }
759 {
760  SwTwips nDiff = _nLeft - GetObjRect().Left();
761  DrawObj()->Move( Size( nDiff, 0 ) );
762 
763  return nDiff != 0;
764 }
765 
771  const SwRect* _pNewObjRect )
772 {
773  SwTwips nHoriRelPos = 0;
774  SwTwips nVertRelPos = 0;
775  const Point aAnchorPos = _pNewAnchorFrame->GetFrameAnchorPos( ::HasWrap( GetDrawObj() ) );
776  // --> #i33313#
777  const SwRect aObjRect( _pNewObjRect ? *_pNewObjRect : GetObjRect() );
778  const bool bVert = _pNewAnchorFrame->IsVertical();
779  const bool bR2L = _pNewAnchorFrame->IsRightToLeft();
780  if ( bVert )
781  {
782  nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
783  nVertRelPos = aAnchorPos.X() - aObjRect.Right();
784  }
785  else if ( bR2L )
786  {
787  nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
788  nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
789  }
790  else
791  {
792  nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
793  nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
794  }
795 
796  SwFormatHoriOrient hori(nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME);
797  SwFormatVertOrient vert(nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME);
798  SfxItemSet items(GetFrameFormat().GetDoc()->GetAttrPool(), svl::Items<RES_VERT_ORIENT, RES_HORI_ORIENT>());
799  items.Put(hori);
800  items.Put(vert);
802 }
803 
804 // --> #i34748# - change return type.
805 // If member <mpLastObjRect> is NULL, create one.
807 {
808  maLastObjRect = _rNewLastRect;
809 }
810 
812 {
813  // --> #i31698#
815 
817  {
819  }
820 }
821 
832 {
833  SwDrawContact* pDrawContact =
834  static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() ));
835 
836  if ( !pDrawContact->ObjAnchoredAsChar() )
837  {
838  SwRect aObjRect( GetObjRect() );
839 
840  SwTwips nHoriPos = aObjRect.Left();
841  SwTwips nVertPos = aObjRect.Top();
842  // #i44334#, #i44681#
843  // perform conversion only if position is in horizontal-left-to-right-layout.
844  if ( GetFrameFormat().GetPositionLayoutDir() ==
845  text::PositionLayoutDir::PositionInHoriL2R )
846  {
848  switch ( eLayoutDir )
849  {
851  {
852  // nothing to do
853  }
854  break;
856  {
857  nHoriPos = -aObjRect.Left() - aObjRect.Width();
858  }
859  break;
861  {
862  nHoriPos = aObjRect.Top();
863  nVertPos = -aObjRect.Left() - aObjRect.Width();
864  }
865  break;
866  default:
867  {
868  assert(!"<SwAnchoredDrawObject::SetPositioningAttr()> - unsupported layout direction");
869  }
870  }
871  }
872 
873  // --> #i71182#
874  // only change position - do not lose other attributes
875 
876  SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() );
877  if (nHoriPos != aHori.GetPos()) {
878  aHori.SetPos( nHoriPos );
880  GetFrameFormat().SetFormatAttr( aHori );
881  }
882 
883  SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() );
884  if (nVertPos != aVert.GetPos()) {
885  aVert.SetPos( nVertPos );
887  GetFrameFormat().SetFormatAttr( aVert );
888  }
889 
890  // --> #i36010# - set layout direction of the position
892  text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
893  }
894  // --> #i65798# - also for as-character anchored objects
895  // --> #i45952# - indicate that position
896  // attributes are set now.
897  static_cast<SwDrawFrameFormat&>(GetFrameFormat()).PosAttrSet();
898 }
899 
901  const SwRect& _rRect,
902  PrepareHint _eHint )
903 {
904  ::Notify_Background( GetDrawObj(), _pPageFrame, _rRect, _eHint, true );
905 }
906 
913 {
914  SwPageFrame* pPageFrame( nullptr );
915  if ( GetVertPosOrientFrame() )
916  {
917  pPageFrame = const_cast<SwPageFrame*>(GetVertPosOrientFrame()->FindPageFrame());
918  }
919  if ( pPageFrame && GetPageFrame() != pPageFrame )
920  {
921  if ( GetPageFrame() )
923  pPageFrame->AppendDrawObjToPage( *this );
924  }
925 }
926 
927 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Point TopLeft() const
Base class of the Writer layout elements.
Definition: frame.hxx:298
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 ...
void Right(const tools::Long nRight)
Definition: swrect.hxx:200
void ChkPage()
Definition: dcontact.cxx:1935
Point GetPos(const SwRect &rRect) const
Definition: frame.hxx:1364
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:588
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:1093
Definition: doc.hxx:186
void InvalidatePage_(SwPageFrame *_pPageFrame)
method to invalidate the given page frame
void InvalidatePos()
Definition: frame.hxx:1024
tools::Long GetWidth() const
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:3268
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:359
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:191
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed...
Definition: ssfrm.cxx:588
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)
#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:450
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:1215
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:196
const SdrObject * GetDrawObj() const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
const SwFooterFrame * GetFooterFrame() const
Definition: pagechg.cxx:2555
virtual SwRect GetObjRect() const override
virtual SwFrameFormat::tLayoutDir GetLayoutDir() const
Definition: atrfrm.cxx:2807
SwRect GetBoundRect(OutputDevice const *pOutputDevice) const
Definition: paintfrm.cxx:6106
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
SwPageFrame * FindPageFrame()
Definition: frame.hxx:663
RndStdIds GetAnchorId() const
Definition: dcontact.hxx:145
void AppendDrawObjToPage(SwAnchoredObject &_rNewObj)
Definition: flylay.cxx:1044
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:598
SwLayoutFrame * GetUpper()
Definition: frame.hxx:661
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:119
tools::Long GetBottomMargin() const
Definition: ssfrm.cxx:42
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document settings interface.
Definition: format.cxx:736
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
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 ...
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:461
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:46
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:968
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: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
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:40
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
tools::Long GetHeight() const
virtual void MakeObjPos() override
method to determine position for the object and set the position at the object
bool IsVertical() const
Definition: frame.hxx:954
virtual void SetEnableSetModified(bool bEnableSetModified)=0
bool IsInDtor() const
Definition: doc.hxx:400
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:44
void SetVertPosOrientFrame(const SwLayoutFrame &_rVertPosOrientFrame)
virtual void CalcPosition() override
calculate position for object
const SwHeaderFrame * GetHeaderFrame() const
Definition: pagechg.cxx:2543
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:290
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:2822
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:662
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:394