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