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
42using namespace ::com::sun::star;
43
44namespace {
45
48class 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
64SwPosNotify::SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj ) :
65 mpAnchoredDrawObj( _pAnchoredDrawObj )
66{
67 maOldObjRect = mpAnchoredDrawObj->GetObjRect();
68 // --> #i35640# - determine correct page frame
69 mpOldPageFrame = mpAnchoredDrawObj->GetPageFrame();
70}
71
72SwPosNotify::~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#
138Point const & SwPosNotify::LastObjPos() const
139{
140 return maOldObjRect.Pos();
141}
142
143namespace {
144
145// #i32795#
147class 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
162SwObjPosOscillationControl::SwObjPosOscillationControl(
163 const SwAnchoredDrawObject& _rAnchoredDrawObj )
164 : mpAnchoredDrawObj( &_rAnchoredDrawObj )
165{
166}
167
168bool 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{
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() &&
342 GetAnchorFrame()->isFrameAreaDefinitionValid() )
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 {
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
628namespace
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 {
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.
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.
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 {
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);
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: */
@ DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE
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...
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
virtual void SetEnableSetModified(bool bEnableSetModified)=0
virtual bool IsEnableSetModified() const =0
virtual bool IsAutoGrowHeight() const override
virtual void SetAnchorPos(const Point &rPnt)
const Point & GetAnchorPos() const
const double * GetRelativeHeight() const
virtual void Move(const Size &rSiz)
virtual const tools::Rectangle & GetCurrentBoundRect() const
const double * GetRelativeWidth() const
sal_Int16 GetRelativeHeightRelation() const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
class for the positioning of drawing objects
void MakeObjPosAnchoredAtLayout()
method for the intrinsic positioning of an at-page|at-frame anchored drawing object
virtual SwFrameFormat & GetFrameFormat() override
virtual bool SetObjTop_(const SwTwips _nTop) override
virtual void NotifyBackground(SwPageFrame *_pPageFrame, const SwRect &_rRect, PrepareHint _eHint) override
method to notify background of drawing object
virtual ~SwAnchoredDrawObject() override
virtual void UpdateLayoutDir() override
method update layout direction the layout direction, the anchored object is assigned to
virtual void MakeObjPos() override
method to determine position for the object and set the position at the object
virtual bool SetObjLeft_(const SwTwips _nLeft) override
std::optional< tools::Rectangle > maLastObjRect
void SetLastObjRect(const tools::Rectangle &_rNewObjRect)
void SetDrawObjAnchor()
method to set internal anchor position of <SdrObject> instance of the drawing object
virtual SwRect GetObjRect() const override
void SetPositioningAttr()
method to set positioning attributes (not for as-character anchored)
virtual void InvalidateObjPos() override
method to invalidate position of the anchored object
void AdjustPositioningAttr(const SwFrame *_pNewAnchorFrame, const SwRect *_pNewObjRect=nullptr)
adjust positioning and alignment attributes for new anchor frame
void MakeObjPosAnchoredAtPara()
method for the intrinsic positioning of an at-paragraph|at-character anchored drawing object
virtual void RegisterAtCorrectPage() override
method to assure that anchored object is registered at the correct page frame
virtual void RegisterAtPage(SwPageFrame &) override
virtual void ObjectAttachedToAnchorFrame() override
method to indicate, that anchored object is attached to an anchor frame
virtual SwRect GetObjBoundRect() const override
void InvalidatePage_(SwPageFrame *_pPageFrame)
method to invalidate the given page frame
const SwFrame * GetAnchorFrame() const
bool ConsiderForTextWrap() const
void SetObjTop(const SwTwips _nTop)
bool InvalidationOfPosAllowed() const
method to determine, if invalidation of position is allowed
virtual void ObjectAttachedToAnchorFrame()
method to indicate, that anchored object is attached to an anchor frame
SwFrame * AnchorFrame()
void SetVertPosOrientFrame(const SwLayoutFrame &_rVertPosOrientFrame)
SwFrame * GetAnchorFrameContainingAnchPos()
determine anchor frame containing the anchor position
const SwLayoutFrame * GetVertPosOrientFrame() const
void SetTmpConsiderWrapInfluence(const bool _bTmpConsiderWrapInfluence)
void SetCurrRelPos(Point _aRelPos)
void SetObjLeft(const SwTwips _nLeft)
bool OverlapsPrevColumn() const
method to determine, if the anchored object is overlapping with a previous column
bool ConsiderObjWrapInfluenceOnObjPos() const
method to determine, if wrapping style influence of the anchored object has to be considered on the o...
SwPageFrame * GetPageFrame()
SwPageFrame * FindPageFrameOfAnchor()
method to determine the page frame, on which the 'anchor' of the given anchored object is.
void SetConsiderForTextWrap(const bool _bConsiderForTextWrap)
const SwRect & GetObjRectWithSpaces() const
method to determine object area inclusive its spacing
virtual void UpdateLayoutDir()
method update layout direction the layout direction, the anchored object is assigned to
void InvalidateObjRectWithSpaces() const
bool ConsiderObjWrapInfluenceOfOtherObjs() const
method to determine, if other anchored objects, also attached at to the anchor frame,...
const SdrObject * GetDrawObj() const
SdrObject * DrawObj()
void SetRestartLayoutProcess(const bool _bRestartLayoutProcess)
bool IsPositioningInProgress() const
is positioning of anchored object in progress
const Point & GetCurrRelPos() const
bool ObjAnchoredAsChar() const
Definition: dcontact.hxx:150
virtual void MoveObjToVisibleLayer(SdrObject *_pDrawObj)
method to move drawing object to corresponding visible layer
Definition: dcontact.cxx:210
RndStdIds GetAnchorId() const
Definition: dcontact.hxx:145
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:58
Definition: doc.hxx:194
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:400
bool IsInDtor() const
Definition: doc.hxx:412
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
ContactObject for connection of formats as representatives of draw objects in SwClient and the object...
Definition: dcontact.hxx:304
void ChkPage()
Definition: dcontact.cxx:2043
new class for re-direct methods calls at a 'virtual' drawing object to its referenced object.
Definition: dcontact.hxx:211
Defines the horizontal position of a fly frame.
Definition: fmtornt.hxx:73
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:100
SwTwips GetPos() const
Definition: fmtornt.hxx:99
Defines the vertical position of a fly frame.
Definition: fmtornt.hxx:37
SwTwips GetPos() const
Definition: fmtornt.hxx:62
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:63
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:447
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document settings interface.
Definition: format.cxx:711
const SwRect & getFrameArea() const
Definition: frame.hxx:179
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
Style of a layout element.
Definition: frmfmt.hxx:62
virtual void SetPositionLayoutDir(const sal_Int16 _nPositionLayoutDir)
Definition: atrfrm.cxx:2852
virtual SwFrameFormat::tLayoutDir GetLayoutDir() const
Definition: atrfrm.cxx:2837
Base class of the Writer layout elements.
Definition: frame.hxx:315
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed.
Definition: ssfrm.cxx:593
bool IsTextFrame() const
Definition: frame.hxx:1234
tools::Long GetLeftMargin() const
Definition: ssfrm.cxx:47
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:603
tools::Long GetRightMargin() const
Definition: ssfrm.cxx:49
Point GetFrameAnchorPos(bool bIgnoreFlysAnchoredAtThisFrame) const
returns the position for anchors based on frame direction
Definition: ssfrm.cxx:293
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1799
bool IsRightToLeft() const
Definition: frame.hxx:987
void InvalidatePos()
Definition: frame.hxx:1043
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
tools::Long GetBottomMargin() const
Definition: ssfrm.cxx:45
bool IsVertical() const
Definition: frame.hxx:973
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:613
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:43
Header in the document layout, inside a page.
Definition: hffrm.hxx:44
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:399
Helper class for notify that positioning of an anchored object is in progress.
A page of the document layout.
Definition: pagefrm.hxx:58
void InvalidateFlyLayout() const
Validate, invalidate and query the Page status Layout/Content and Fly/non-Fly respectively are inspec...
Definition: pagefrm.hxx:364
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:204
void InvalidateFlyInCnt() const
Definition: pagefrm.hxx:372
void RemoveDrawObjFromPage(SwAnchoredObject &_rToRemoveObj)
Definition: flylay.cxx:1098
const SwFooterFrame * GetFooterFrame() const
Definition: pagechg.cxx:2583
void AppendDrawObjToPage(SwAnchoredObject &_rNewObj)
Definition: flylay.cxx:1049
const SwHeaderFrame * GetHeaderFrame() const
Definition: pagechg.cxx:2571
SwRect GetBoundRect(OutputDevice const *pOutputDevice) const
Definition: paintfrm.cxx:6311
Point GetPos(const SwRect &rRect) const
Definition: frame.hxx:1382
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:57
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool HasArea() const
Definition: swrect.hxx:300
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void Pos(const Point &rNew)
Definition: swrect.hxx:171
tools::Rectangle SVRect() const
Definition: swrect.hxx:292
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
const SwContentFrame * GetTurbo() const
Definition: rootfrm.hxx:352
bool IsAnyShellAccessible() const
Definition: rootfrm.hxx:389
void SetIdleFlags()
Definition: rootfrm.hxx:248
void DisallowTurbo() const
Definition: rootfrm.hxx:347
void ResetTurbo()
Definition: rootfrm.hxx:351
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.
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
Is the frame format a text box?
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
TextFrameIndex CalcFlyPos(SwFrameFormat const *pSearch)
Calculates the position of FlyInContentFrames.
Definition: porfly.cxx:184
void MoveAccessible(const SwFrame *pFrame, const SdrObject *pObj, const SwRect &rOldFrame)
Move a frame's position in the accessible view.
Definition: viewimp.cxx:390
SwViewShellImp * Imp()
Definition: viewsh.hxx:190
virtual void CalcPosition() override
calculate position of object
const SwLayoutFrame & GetVertPosOrientFrame() const
frame, at which the vertical position is oriented at
const Point & GetRelPos() const
calculated relative position for object
virtual void CalcPosition() override
calculate position for object
constexpr tools::Long GetWidth() const
constexpr Point TopLeft() const
constexpr tools::Long GetHeight() const
SwFrameFormat * FindFrameFormat(SdrObject *pObj)
The Get reverse way: seeks the format to the specified object.
Definition: dcontact.cxx:121
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:172
bool HasWrap(const SdrObject *pObj)
Definition: dcontact.cxx:140
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
EmbeddedObjectRef * pObject
void Notify_Background(const SdrObject *pObj, SwPageFrame *pPage, const SwRect &rRect, const PrepareHint eHint, const bool bInva)
Definition: frmtool.cxx:3390
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
#define Y
tools::Long SwTwips
Definition: swtypes.hxx:51
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
PrepareHint
Definition: swtypes.hxx:204
@ FlyFrameAttributesChanged
void ClrContourCache(const SdrObject *pObj)
Definition: txtfly.cxx:137
#define MID_FRMSIZE_SIZE
Definition: unomid.h:70