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