Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx
Warning:line 1445, column 31
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name flylay.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx
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 <pagefrm.hxx>
21#include <rootfrm.hxx>
22#include <cntfrm.hxx>
23#include <dflyobj.hxx>
24#include <dcontact.hxx>
25#include <ftnfrm.hxx>
26#include <frmatr.hxx>
27#include <frmtool.hxx>
28#include <hints.hxx>
29#include <sectfrm.hxx>
30#include <notxtfrm.hxx>
31#include <txtfly.hxx>
32
33#include <svx/svdpage.hxx>
34#include <editeng/ulspitem.hxx>
35#include <fmtornt.hxx>
36#include <fmtfsize.hxx>
37#include <ndole.hxx>
38#include <tabfrm.hxx>
39#include <flyfrms.hxx>
40#include <fmtfollowtextflow.hxx>
41#include <environmentofanchoredobject.hxx>
42#include <sortedobjs.hxx>
43#include <viewimp.hxx>
44#include <IDocumentSettingAccess.hxx>
45#include <IDocumentDrawModelAccess.hxx>
46#include <pam.hxx>
47#include <ndindex.hxx>
48#include <basegfx/matrix/b2dhommatrixtools.hxx>
49#include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
50
51using namespace ::com::sun::star;
52
53SwFlyFreeFrame::SwFlyFreeFrame( SwFlyFrameFormat *pFormat, SwFrame* pSib, SwFrame *pAnch )
54: SwFlyFrame( pFormat, pSib, pAnch ),
55 // #i34753#
56 mbNoMakePos( false ),
57 // #i37068#
58 mbNoMoveOnCheckClip( false ),
59 maUnclippedFrame(),
60 // RotateFlyFrame3
61 mpTransformableSwFrame()
62{
63}
64
65void SwFlyFreeFrame::DestroyImpl()
66{
67 // #i28701# - use new method <GetPageFrame()>
68 if( GetPageFrame() )
69 {
70 if( GetFormat()->GetDoc()->IsInDtor() )
71 {
72 // #i29879# - remove also to-frame anchored Writer
73 // fly frame from page.
74 const bool bRemoveFromPage =
75 GetPageFrame()->GetSortedObjs() &&
76 ( IsFlyAtContentFrame() ||
77 ( GetAnchorFrame() && GetAnchorFrame()->IsFlyFrame() ) );
78 if ( bRemoveFromPage )
79 {
80 GetPageFrame()->GetSortedObjs()->Remove( *this );
81 }
82 }
83 else
84 {
85 SwRect aTmp( GetObjRectWithSpaces() );
86 SwFlyFreeFrame::NotifyBackground( GetPageFrame(), aTmp, PrepareHint::FlyFrameLeave );
87 }
88 }
89
90 SwFlyFrame::DestroyImpl();
91}
92
93SwFlyFreeFrame::~SwFlyFreeFrame()
94{
95#if 0
96 // we are possibly in ContourCache, make sure we vanish
97 ::ClrContourCache(GetVirtDrawObj());
98#endif
99}
100
101// #i28701#
102/** Notifies the background (all ContentFrames that currently are overlapping).
103 *
104 * Additionally, the window is also directly invalidated (especially where
105 * there are no overlapping ContentFrames).
106 * This also takes ContentFrames within other Flys into account.
107 */
108void SwFlyFreeFrame::NotifyBackground( SwPageFrame *pPageFrame,
109 const SwRect& rRect, PrepareHint eHint )
110{
111 ::Notify_Background( GetVirtDrawObj(), pPageFrame, rRect, eHint, true );
112}
113
114void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
115{
116 if ( !GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
117 {
118 return;
119 }
120
121 if ( !GetAnchorFrame() || IsLocked() || IsColLocked() )
122 {
123 return;
124 }
125
126 // #i28701# - use new method <GetPageFrame()>
127 if( !GetPageFrame() && GetAnchorFrame()->IsInFly() )
128 {
129 SwFlyFrame* pFly = AnchorFrame()->FindFlyFrame();
130 SwPageFrame *pPageFrame = pFly ? pFly->FindPageFrame() : nullptr;
131 if( pPageFrame )
132 pPageFrame->AppendFlyToPage( this );
133 }
134
135 if( !GetPageFrame() )
136 {
137 return;
138 }
139
140 Lock(); // The curtain drops
141
142 // takes care of the notification in the dtor
143 const SwFlyNotify aNotify( this );
144
145 if ( IsClipped() )
146 {
147 setFrameAreaSizeValid(false);
148 m_bHeightClipped = m_bWidthClipped = false;
149 // no invalidation of position,
150 // if anchored object is anchored inside a Writer fly frame,
151 // its position is already locked, and it follows the text flow.
152 // #i34753# - add condition:
153 // no invalidation of position, if no direct move is requested in <CheckClip(..)>
154 if ( !IsNoMoveOnCheckClip() &&
155 !( PositionLocked() &&
156 GetAnchorFrame()->IsInFly() &&
157 GetFrameFormat().GetFollowTextFlow().GetValue() ) )
158 {
159 setFrameAreaPositionValid(false);
160 }
161 }
162
163 // #i81146# new loop control
164 int nLoopControlRuns = 0;
165 const int nLoopControlMax = 10;
166
167 // RotateFlyFrame3 - outer frame
168 const double fRotation(getLocalFrameRotation());
169 const bool bRotated(!basegfx::fTools::equalZero(fRotation));
170
171 if(bRotated)
172 {
173 // Re-layout may be partially (see all isFrameAreaDefinitionValid() flags),
174 // so resetting the local SwFrame(s) in the local SwFrameAreaDefinition is
175 // needed. Reset to BoundAreas will be done below automatically
176 if(isTransformableSwFrame())
177 {
178 getTransformableSwFrame()->restoreFrameAreas();
179 }
180 }
181
182 while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() || m_bFormatHeightOnly || !m_bValidContentPos )
183 {
184 SwRectFnSet aRectFnSet(this);
185 const SwFormatFrameSize *pSz;
186 { // Additional scope, so aAccess will be destroyed before the check!
187
188 SwBorderAttrAccess aAccess( SwFrame::GetCache(), this );
189 const SwBorderAttrs &rAttrs = *aAccess.Get();
190 pSz = &rAttrs.GetAttrSet().GetFrameSize();
191
192 // Only set when the flag is set!
193 if ( !isFrameAreaSizeValid() )
194 {
195 setFramePrintAreaValid(false);
196 }
197
198 if ( !isFramePrintAreaValid() )
199 {
200 MakePrtArea( rAttrs );
201 m_bValidContentPos = false;
202 }
203
204 if ( !isFrameAreaSizeValid() || m_bFormatHeightOnly )
205 {
206 setFrameAreaSizeValid(false);
207 Format( getRootFrame()->GetCurrShell()->GetOut(), &rAttrs );
208 m_bFormatHeightOnly = false;
209 }
210 }
211
212 if ( !isFrameAreaPositionValid() )
213 {
214 const Point aOldPos( aRectFnSet.GetPos(getFrameArea()) );
215 // #i26791# - use new method <MakeObjPos()>
216 // #i34753# - no positioning, if requested.
217 if ( IsNoMakePos() )
218 {
219 setFrameAreaPositionValid(true);
220 }
221 else
222 // #i26791# - use new method <MakeObjPos()>
223 MakeObjPos();
224 if( aOldPos == aRectFnSet.GetPos(getFrameArea()) )
225 {
226 if( !isFrameAreaPositionValid() && GetAnchorFrame()->IsInSct() &&
227 !GetAnchorFrame()->FindSctFrame()->isFrameAreaDefinitionValid() )
228 {
229 setFrameAreaPositionValid(true);
230 }
231 }
232 else
233 {
234 setFrameAreaSizeValid(false);
235 }
236 }
237
238 if ( !m_bValidContentPos )
239 {
240 SwBorderAttrAccess aAccess( SwFrame::GetCache(), this );
241 const SwBorderAttrs &rAttrs = *aAccess.Get();
242 MakeContentPos( rAttrs );
243 }
244
245 if ( isFrameAreaPositionValid() && isFrameAreaSizeValid() )
246 {
247 ++nLoopControlRuns;
248
249 OSL_ENSURE( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrame::MakeAll" )do { if (true && (!(nLoopControlRuns < nLoopControlMax
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "249" ": "), "%s", "LoopControl in SwFlyFreeFrame::MakeAll"
); } } while (false)
;
250
251 if ( nLoopControlRuns < nLoopControlMax )
252 CheckClip( *pSz );
253 }
254 else
255 nLoopControlRuns = 0;
256 }
257
258 // RotateFlyFrame3 - outer frame
259 // Do not refresh transforms/Areas self here, this will be done
260 // when inner and outer frame are layouted, in SwNoTextFrame::MakeAll
261 if(bRotated)
262 {
263 // RotateFlyFrame3: Safe changes locally
264 // get center from outer frame (layout frame) to be on the safe side
265 const Point aCenter(getFrameArea().Center());
266 const basegfx::B2DPoint aB2DCenter(aCenter.X(), aCenter.Y());
267
268 if(!mpTransformableSwFrame)
269 {
270 mpTransformableSwFrame.reset(new TransformableSwFrame(*this));
271 }
272
273 getTransformableSwFrame()->createFrameAreaTransformations(
274 fRotation,
275 aB2DCenter);
276 getTransformableSwFrame()->adaptFrameAreasToTransformations();
277 }
278 else
279 {
280 // RotateFlyFrame3: Also need to clear ContourCache (if used),
281 // usually done in SwFlyFrame::NotifyDrawObj, but there relies on
282 // being in transform mode which is already reset then
283 if(isTransformableSwFrame())
284 {
285 ::ClrContourCache(GetVirtDrawObj());
286 }
287
288 // reset transformations to show that they are not used
289 mpTransformableSwFrame.reset();
290 }
291
292 Unlock();
293
294#if OSL_DEBUG_LEVEL1 > 0
295 SwRectFnSet aRectFnSet(this);
296 OSL_ENSURE( m_bHeightClipped || ( aRectFnSet.GetHeight(getFrameArea()) > 0 &&do { if (true && (!(m_bHeightClipped || ( aRectFnSet.
GetHeight(getFrameArea()) > 0 && aRectFnSet.GetHeight
(getFramePrintArea()) > 0)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "298" ": "), "%s", "SwFlyFreeFrame::Format(), flipping Fly."
); } } while (false)
297 aRectFnSet.GetHeight(getFramePrintArea()) > 0),do { if (true && (!(m_bHeightClipped || ( aRectFnSet.
GetHeight(getFrameArea()) > 0 && aRectFnSet.GetHeight
(getFramePrintArea()) > 0)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "298" ": "), "%s", "SwFlyFreeFrame::Format(), flipping Fly."
); } } while (false)
298 "SwFlyFreeFrame::Format(), flipping Fly." )do { if (true && (!(m_bHeightClipped || ( aRectFnSet.
GetHeight(getFrameArea()) > 0 && aRectFnSet.GetHeight
(getFramePrintArea()) > 0)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "298" ": "), "%s", "SwFlyFreeFrame::Format(), flipping Fly."
); } } while (false)
;
299
300#endif
301}
302
303bool SwFlyFreeFrame::supportsAutoContour() const
304{
305 static bool bOverrideHandleContourToAlwaysOff(true); // loplugin:constvars:ignore
306
307 // RotateFlyFrameFix: For LO6.0 we need to deactivate the AutoContour feature again, it is simply
308 // not clear how/if to use and save/load it in ODF. This has to be discussed.
309 // The reason not to remove is that this may be used as-is now, using a new switch.
310 // Even when not, the detection if it is possible will be needed in any case later.
311 if(bOverrideHandleContourToAlwaysOff)
312 {
313 return false;
314 }
315
316 if(!isTransformableSwFrame())
317 {
318 // support only when transformed, else there is no free space
319 return false;
320 }
321
322 // Check for Borders. If we have Borders, do (currently) not support,
323 // since borders do not transform with the object.
324 // (Will need to be enhanced to take into account if we have Borders and if these
325 // transform with the object)
326 SwBorderAttrAccess aAccess(SwFrame::GetCache(), this);
327 const SwBorderAttrs &rAttrs(*aAccess.Get());
328
329 if(rAttrs.IsLine())
330 {
331 return false;
332 }
333
334 // Check for Padding. Do not support when padding is used, this will
335 // produce a covered space around the object (filled with fill defines)
336 const SfxPoolItem* pItem(nullptr);
337
338 if(GetFormat() && SfxItemState::SET == GetFormat()->GetItemState(RES_BOX, false, &pItem))
339 {
340 const SvxBoxItem& rBox = *static_cast< const SvxBoxItem* >(pItem);
341
342 if(rBox.HasBorder(/*bTreatPaddingAsBorder*/true))
343 {
344 return false;
345 }
346 }
347
348 // check for Fill - if we have fill, it will fill the gaps and we will not
349 // support AutoContour
350 if(GetFormat() && GetFormat()->supportsFullDrawingLayerFillAttributeSet())
351 {
352 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(GetFormat()->getSdrAllFillAttributesHelper());
353
354 if(aFillAttributes && aFillAttributes->isUsed())
355 {
356 return false;
357 }
358 }
359 else
360 {
361 const std::unique_ptr<SvxBrushItem> aBack(GetFormat()->makeBackgroundBrushItem());
362
363 if(aBack && aBack->isUsed())
364 {
365 return false;
366 }
367 }
368
369 // else, support
370 return true;
371}
372
373// RotateFlyFrame3 - Support for Transformations - outer frame
374basegfx::B2DHomMatrix SwFlyFreeFrame::getFrameAreaTransformation() const
375{
376 if(isTransformableSwFrame())
377 {
378 // use pre-created transformation
379 return getTransformableSwFrame()->getLocalFrameAreaTransformation();
380 }
381
382 // call parent
383 return SwFlyFrame::getFrameAreaTransformation();
384}
385
386basegfx::B2DHomMatrix SwFlyFreeFrame::getFramePrintAreaTransformation() const
387{
388 if(isTransformableSwFrame())
389 {
390 // use pre-created transformation
391 return getTransformableSwFrame()->getLocalFramePrintAreaTransformation();
392 }
393
394 // call parent
395 return SwFlyFrame::getFramePrintAreaTransformation();
396}
397
398// RotateFlyFrame3 - Support for Transformations
399void SwFlyFreeFrame::transform_translate(const Point& rOffset)
400{
401 // call parent - this will do the basic transform for SwRect(s)
402 // in the SwFrameAreaDefinition
403 SwFlyFrame::transform_translate(rOffset);
404
405 // check if the Transformations need to be adapted
406 if(isTransformableSwFrame())
407 {
408 const basegfx::B2DHomMatrix aTransform(
409 basegfx::utils::createTranslateB2DHomMatrix(
410 rOffset.X(), rOffset.Y()));
411
412 // transform using TransformableSwFrame
413 getTransformableSwFrame()->transform(aTransform);
414 }
415}
416
417// RotateFlyFrame3 - outer frame
418double getLocalFrameRotation_from_SwNoTextFrame(const SwNoTextFrame& rNoTextFrame)
419{
420 return rNoTextFrame.getLocalFrameRotation();
421}
422
423double SwFlyFreeFrame::getLocalFrameRotation() const
424{
425 // SwLayoutFrame::Lower() != SwFrame::GetLower(), but SwFrame::GetLower()
426 // calls SwLayoutFrame::Lower() when it's a SwLayoutFrame - so use GetLower()
427 const SwNoTextFrame* pSwNoTextFrame(dynamic_cast< const SwNoTextFrame* >(GetLower()));
428
429 if(nullptr != pSwNoTextFrame)
430 {
431 return getLocalFrameRotation_from_SwNoTextFrame(*pSwNoTextFrame);
432 }
433
434 // no rotation
435 return 0.0;
436}
437
438/** determines, if direct environment of fly frame has 'auto' size
439
440 #i17297#
441 start with anchor frame and search via <GetUpper()> for a header, footer,
442 row or fly frame stopping at page frame.
443 return <true>, if such a frame is found and it has 'auto' size.
444 otherwise <false> is returned.
445
446 @return boolean indicating, that direct environment has 'auto' size
447*/
448bool SwFlyFreeFrame::HasEnvironmentAutoSize() const
449{
450 bool bRetVal = false;
451
452 const SwFrame* pToBeCheckedFrame = GetAnchorFrame();
453 while ( pToBeCheckedFrame &&
454 !pToBeCheckedFrame->IsPageFrame() )
455 {
456 if ( pToBeCheckedFrame->IsHeaderFrame() ||
457 pToBeCheckedFrame->IsFooterFrame() ||
458 pToBeCheckedFrame->IsRowFrame() ||
459 pToBeCheckedFrame->IsFlyFrame() )
460 {
461 bRetVal = SwFrameSize::Fixed !=
462 pToBeCheckedFrame->GetAttrSet()->GetFrameSize().GetHeightSizeType();
463 break;
464 }
465 else
466 {
467 pToBeCheckedFrame = pToBeCheckedFrame->GetUpper();
468 }
469 }
470
471 return bRetVal;
472}
473
474void SwFlyFreeFrame::CheckClip( const SwFormatFrameSize &rSz )
475{
476 // It's probably time now to take appropriate measures, if the Fly
477 // doesn't fit into its surrounding.
478 // First, the Fly gives up its position, then it's formatted.
479 // Only if it still doesn't fit after giving up its position, the
480 // width or height are given up as well. The frame will be squeezed
481 // as much as needed.
482
483 const SwVirtFlyDrawObj *pObj = GetVirtDrawObj();
484 SwRect aClip, aTmpStretch;
485 ::CalcClipRect( pObj, aClip );
486 ::CalcClipRect( pObj, aTmpStretch, false );
487 aClip.Intersection_( aTmpStretch );
488
489 const long nBot = getFrameArea().Top() + getFrameArea().Height();
490 const long nRig = getFrameArea().Left() + getFrameArea().Width();
491 const long nClipBot = aClip.Top() + aClip.Height();
492 const long nClipRig = aClip.Left() + aClip.Width();
493
494 const bool bBot = nBot > nClipBot;
495 const bool bRig = nRig > nClipRig;
496 if (( bBot || bRig ) && !IsDraggingOffPageAllowed(FindFrameFormat(GetDrawObj())))
497 {
498 bool bAgain = false;
499 // #i37068# - no move, if it's requested
500 if ( bBot && !IsNoMoveOnCheckClip() &&
501 !GetDrawObjs() && !GetAnchorFrame()->IsInTab() )
502 {
503 SwFrame* pHeader = FindFooterOrHeader();
504 // In a header, correction of the position is no good idea.
505 // If the fly moves, some paragraphs have to be formatted, this
506 // could cause a change of the height of the headerframe,
507 // now the flyframe can change its position and so on ...
508 if ( !pHeader || !pHeader->IsHeaderFrame() )
509 {
510 const long nOld = getFrameArea().Top();
511
512 // tdf#112443 disable positioning if content is completely off page
513 bool bDisableOffPagePositioning = GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING);
514 if ( !bDisableOffPagePositioning || nOld <= nClipBot)
515 {
516 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
517 aFrm.Pos().setY( std::max( aClip.Top(), nClipBot - aFrm.Height() ) );
518 }
519
520 if ( getFrameArea().Top() != nOld )
521 {
522 bAgain = true;
523 }
524
525 m_bHeightClipped = true;
526 }
527 }
528 if ( bRig )
529 {
530 const long nOld = getFrameArea().Left();
531
532 // tdf#112443 disable positioning if content is completely off page
533 bool bDisableOffPagePositioning = GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING);
534 if ( !bDisableOffPagePositioning || nOld <= nClipRig )
535 {
536 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
537 aFrm.Pos().setX( std::max( aClip.Left(), nClipRig - aFrm.Width() ) );
538 }
539
540 if ( getFrameArea().Left() != nOld )
541 {
542 const SwFormatHoriOrient &rH = GetFormat()->GetHoriOrient();
543 // Left-aligned ones may not be moved to the left when they
544 // are avoiding another one.
545 if( rH.GetHoriOrient() == text::HoriOrientation::LEFT )
546 {
547 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
548 aFrm.Pos().setX( nOld );
549 }
550 else
551 {
552 bAgain = true;
553 }
554 }
555 m_bWidthClipped = true;
556 }
557 if ( bAgain )
558 {
559 setFrameAreaSizeValid(false);
560 }
561 else
562 {
563 // If we reach this branch, the Frame protrudes into forbidden
564 // areas, and correcting the position is not allowed or not
565 // possible or not required.
566
567 // For Flys with OLE objects as lower, we make sure that
568 // we always resize proportionally
569 Size aOldSize( getFrameArea().SSize() );
570
571 // First, setup the FrameRect, then transfer it to the Frame.
572 SwRect aFrameRect( getFrameArea() );
573
574 if ( bBot )
575 {
576 long nDiff = nClipBot;
577 nDiff -= aFrameRect.Top(); // nDiff represents the available distance
578 nDiff = aFrameRect.Height() - nDiff;
579 aFrameRect.Height( aFrameRect.Height() - nDiff );
580 m_bHeightClipped = true;
581 }
582 if ( bRig )
583 {
584 long nDiff = nClipRig;
585 nDiff -= aFrameRect.Left();// nDiff represents the available distance
586 nDiff = aFrameRect.Width() - nDiff;
587 aFrameRect.Width( aFrameRect.Width() - nDiff );
588 m_bWidthClipped = true;
589 }
590
591 // #i17297# - no proportional
592 // scaling of graphics in environments, which determines its size
593 // by its content ('auto' size). Otherwise layout loops can occur and
594 // layout sizes of the environment can be incorrect.
595 // Such environment are:
596 // (1) header and footer frames with 'auto' size
597 // (2) table row frames with 'auto' size
598 // (3) fly frames with 'auto' size
599 // Note: section frames seems to be not critical - didn't found
600 // any critical layout situation so far.
601 if ( Lower() && Lower()->IsNoTextFrame() &&
602 (static_cast<SwNoTextFrame*>(Lower())->GetNode()->GetOLENode() ||
603 !HasEnvironmentAutoSize() ) )
604 {
605 // If width and height got adjusted, then the bigger
606 // change is relevant.
607 if ( aFrameRect.Width() != aOldSize.Width() &&
608 aFrameRect.Height()!= aOldSize.Height() )
609 {
610 if ( (aOldSize.Width() - aFrameRect.Width()) >
611 (aOldSize.Height()- aFrameRect.Height()) )
612 aFrameRect.Height( aOldSize.Height() );
613 else
614 aFrameRect.Width( aOldSize.Width() );
615 }
616
617 // Adjusted the width? change height proportionally
618 if( aFrameRect.Width() != aOldSize.Width() )
619 {
620 aFrameRect.Height( aFrameRect.Width() * aOldSize.Height() /
621 aOldSize.Width() );
622 m_bHeightClipped = true;
623 }
624 // Adjusted the height? change width proportionally
625 else if( aFrameRect.Height() != aOldSize.Height() )
626 {
627 aFrameRect.Width( aFrameRect.Height() * aOldSize.Width() /
628 aOldSize.Height() );
629 m_bWidthClipped = true;
630 }
631
632 // #i17297# - reactivate change
633 // of size attribute for fly frames containing an ole object.
634
635 // Added the aFrameRect.HasArea() hack, because
636 // the environment of the ole object does not have to be valid
637 // at this moment, or even worse, it does not have to have a
638 // reasonable size. In this case we do not want to change to
639 // attributes permanently. Maybe one day somebody dares to remove
640 // this code.
641 if ( aFrameRect.HasArea() &&
642 static_cast<SwNoTextFrame*>(Lower())->GetNode()->GetOLENode() &&
643 ( m_bWidthClipped || m_bHeightClipped ) )
644 {
645 SwFlyFrameFormat *pFormat = GetFormat();
646 pFormat->LockModify();
647 SwFormatFrameSize aFrameSize( rSz );
648 aFrameSize.SetWidth( aFrameRect.Width() );
649 aFrameSize.SetHeight( aFrameRect.Height() );
650 pFormat->SetFormatAttr( aFrameSize );
651 pFormat->UnlockModify();
652 }
653 }
654
655 // Now change the Frame; for columns, we put the new values into the attributes,
656 // otherwise we'll end up with unwanted side-effects/oscillations
657 const long nPrtHeightDiff = getFrameArea().Height() - getFramePrintArea().Height();
658 const long nPrtWidthDiff = getFrameArea().Width() - getFramePrintArea().Width();
659 maUnclippedFrame = getFrameArea();
660
661 {
662 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
663 aFrm.Height( aFrameRect.Height() );
664 aFrm.Width ( std::max( long(MINLAY23), aFrameRect.Width() ) );
665 }
666
667 if ( Lower() && Lower()->IsColumnFrame() )
668 {
669 ColLock(); //lock grow/shrink
670 const Size aTmpOldSize( getFramePrintArea().SSize() );
671
672 {
673 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
674 aPrt.Height( getFrameArea().Height() - nPrtHeightDiff );
675 aPrt.Width ( getFrameArea().Width() - nPrtWidthDiff );
676 }
677
678 ChgLowersProp( aTmpOldSize );
679 SwFrame *pLow = Lower();
680 do
681 {
682 pLow->Calc(getRootFrame()->GetCurrShell()->GetOut());
683 // also calculate the (Column)BodyFrame
684 static_cast<SwLayoutFrame*>(pLow)->Lower()->Calc(getRootFrame()->GetCurrShell()->GetOut());
685 pLow = pLow->GetNext();
686 } while ( pLow );
687 ::CalcContent( this );
688 ColUnlock();
689
690 if ( !isFrameAreaSizeValid() && !m_bWidthClipped )
691 {
692 setFrameAreaSizeValid(true);
693 m_bFormatHeightOnly = true;
694 }
695 }
696 else
697 {
698 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
699 aPrt.Height( getFrameArea().Height() - nPrtHeightDiff );
700 aPrt.Width ( getFrameArea().Width() - nPrtWidthDiff );
701 }
702 }
703 }
704
705 // #i26945#
706 OSL_ENSURE( getFrameArea().Height() >= 0,do { if (true && (!(getFrameArea().Height() >= 0))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "707" ": "), "%s", "<SwFlyFreeFrame::CheckClip(..)> - fly frame has negative height now."
); } } while (false)
707 "<SwFlyFreeFrame::CheckClip(..)> - fly frame has negative height now." )do { if (true && (!(getFrameArea().Height() >= 0))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "707" ": "), "%s", "<SwFlyFreeFrame::CheckClip(..)> - fly frame has negative height now."
); } } while (false)
;
708}
709
710/** method to determine, if a <MakeAll()> on the Writer fly frame is possible
711 #i43771#
712*/
713bool SwFlyFreeFrame::IsFormatPossible() const
714{
715 return SwFlyFrame::IsFormatPossible() &&
716 ( GetPageFrame() ||
717 ( GetAnchorFrame() && GetAnchorFrame()->IsInFly() ) );
718}
719
720SwFlyLayFrame::SwFlyLayFrame( SwFlyFrameFormat *pFormat, SwFrame* pSib, SwFrame *pAnch ) :
721 SwFlyFreeFrame( pFormat, pSib, pAnch )
722{
723 m_bLayout = true;
724}
725
726// #i28701#
727
728void SwFlyLayFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
729{
730 const SwFormatAnchor *pAnch = nullptr;
731
732 if (pNew)
733 {
734 const sal_uInt16 nWhich = pNew->Which();
735 if( RES_ATTRSET_CHG == nWhich && SfxItemState::SET ==
736 static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState( RES_ANCHOR, false,
737 reinterpret_cast<const SfxPoolItem**>(&pAnch) ))
738 ; // GetItemState sets the anchor pointer!
739
740 else if( RES_ANCHOR == nWhich )
741 {
742 // Change of anchor. I'm attaching myself to the new place.
743 // It's not allowed to change the anchor type. This is only
744 // possible via SwFEShell.
745 pAnch = static_cast<const SwFormatAnchor*>(pNew);
746 }
747 }
748
749 if( pAnch )
750 {
751 OSL_ENSURE( pAnch->GetAnchorId() ==do { if (true && (!(pAnch->GetAnchorId() == GetFormat
()->GetAnchor().GetAnchorId()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "753" ": "), "%s", "8-) Invalid change of anchor type.")
; } } while (false)
752 GetFormat()->GetAnchor().GetAnchorId(),do { if (true && (!(pAnch->GetAnchorId() == GetFormat
()->GetAnchor().GetAnchorId()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "753" ": "), "%s", "8-) Invalid change of anchor type.")
; } } while (false)
753 "8-) Invalid change of anchor type." )do { if (true && (!(pAnch->GetAnchorId() == GetFormat
()->GetAnchor().GetAnchorId()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "753" ": "), "%s", "8-) Invalid change of anchor type.")
; } } while (false)
;
754
755 // Unregister, get hold of the page, attach to the corresponding LayoutFrame.
756 SwRect aOld( GetObjRectWithSpaces() );
757 // #i28701# - use new method <GetPageFrame()>
758 SwPageFrame *pOldPage = GetPageFrame();
759 AnchorFrame()->RemoveFly( this );
760
761 if ( RndStdIds::FLY_AT_PAGE == pAnch->GetAnchorId() )
762 {
763 sal_uInt16 nPgNum = pAnch->GetPageNum();
764 SwRootFrame *pRoot = getRootFrame();
765 SwPageFrame *pTmpPage = static_cast<SwPageFrame*>(pRoot->Lower());
766 for ( sal_uInt16 i = 1; (i <= nPgNum) && pTmpPage; ++i,
767 pTmpPage = static_cast<SwPageFrame*>(pTmpPage->GetNext()) )
768 {
769 if ( i == nPgNum )
770 {
771 // #i50432# - adjust synopsis of <PlaceFly(..)>
772 pTmpPage->PlaceFly( this, nullptr );
773 }
774 }
775 if( !pTmpPage )
776 {
777 pRoot->SetAssertFlyPages();
778 pRoot->AssertFlyPages();
779 }
780 }
781 else
782 {
783 SwNodeIndex aIdx( pAnch->GetContentAnchor()->nNode );
784 SwContentFrame *pContent = GetFormat()->GetDoc()->GetNodes().GoNext( &aIdx )->
785 GetContentNode()->getLayoutFrame(getRootFrame(), nullptr, nullptr);
786 if( pContent )
787 {
788 SwFlyFrame *pTmp = pContent->FindFlyFrame();
789 if( pTmp )
790 pTmp->AppendFly( this );
791 }
792 }
793 // #i28701# - use new method <GetPageFrame()>
794 if ( pOldPage && pOldPage != GetPageFrame() )
795 NotifyBackground( pOldPage, aOld, PrepareHint::FlyFrameLeave );
796 SetCompletePaint();
797 InvalidateAll();
798 SetNotifyBack();
799 }
800 else
801 SwFlyFrame::Modify( pOld, pNew );
802}
803
804void SwPageFrame::AppendFlyToPage( SwFlyFrame *pNew )
805{
806 if ( !pNew->GetVirtDrawObj()->IsInserted() )
807 getRootFrame()->GetDrawPage()->InsertObject(
808 static_cast<SdrObject*>(pNew->GetVirtDrawObj()),
809 pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() );
810
811 InvalidateSpelling();
812 InvalidateSmartTags();
813 InvalidateAutoCompleteWords();
814 InvalidateWordCount();
815
816 if ( GetUpper() )
817 {
818 static_cast<SwRootFrame*>(GetUpper())->SetIdleFlags();
819 static_cast<SwRootFrame*>(GetUpper())->InvalidateBrowseWidth();
820 }
821
822 SdrObject* pObj = pNew->GetVirtDrawObj();
823 OSL_ENSURE( pNew->GetAnchorFrame(), "Fly without Anchor" )do { if (true && (!(pNew->GetAnchorFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "823" ": "), "%s", "Fly without Anchor"); } } while (false
)
;
824 SwFlyFrame* pFly = const_cast<SwFlyFrame*>(pNew->GetAnchorFrame()->FindFlyFrame());
825 if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
826 {
827 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
828 sal_uInt32 nNewNum = pObj->GetOrdNumDirect();
829 if ( pObj->getSdrPageFromSdrObject() )
830 pObj->getSdrPageFromSdrObject()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
831 else
832 pFly->GetVirtDrawObj()->SetOrdNum( nNewNum );
833 }
834
835 // Don't look further at Flys that sit inside the Content.
836 if ( pNew->IsFlyInContentFrame() )
837 InvalidateFlyInCnt();
838 else
839 {
840 InvalidateFlyContent();
841
842 if ( !m_pSortedObjs )
843 {
844 m_pSortedObjs.reset(new SwSortedObjs());
845 }
846
847 const bool bSuccessInserted = m_pSortedObjs->Insert( *pNew );
848 OSL_ENSURE( bSuccessInserted, "Fly not inserted in Sorted." )do { if (true && (!(bSuccessInserted))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "848" ": "), "%s", "Fly not inserted in Sorted."); } } while
(false)
;
849
850 // #i87493#
851 OSL_ENSURE( pNew->GetPageFrame() == nullptr || pNew->GetPageFrame() == this,do { if (true && (!(pNew->GetPageFrame() == nullptr
|| pNew->GetPageFrame() == this))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "852" ": "), "%s", "<SwPageFrame::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect."
); } } while (false)
852 "<SwPageFrame::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect." )do { if (true && (!(pNew->GetPageFrame() == nullptr
|| pNew->GetPageFrame() == this))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "852" ": "), "%s", "<SwPageFrame::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect."
); } } while (false)
;
853 // #i28701# - use new method <SetPageFrame(..)>
854 pNew->SetPageFrame( this );
855 pNew->InvalidatePage( this );
856 // #i28701#
857 pNew->UnlockPosition();
858 // needed to reposition at-page anchored flys moved from different page
859 pNew->InvalidateObjPos();
860
861 // Notify accessible layout. That's required at this place for
862 // frames only where the anchor is moved. Creation of new frames
863 // is additionally handled by the SwFrameNotify class.
864 if( GetUpper() &&
865 static_cast< SwRootFrame * >( GetUpper() )->IsAnyShellAccessible() &&
866 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell() )
867 {
868 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell()->Imp()
869 ->AddAccessibleFrame( pNew );
870 }
871 }
872
873 // #i28701# - correction: consider also drawing objects
874 if ( !pNew->GetDrawObjs() )
875 return;
876
877 SwSortedObjs &rObjs = *pNew->GetDrawObjs();
878 for (SwAnchoredObject* pTmpObj : rObjs)
879 {
880 if ( dynamic_cast<const SwFlyFrame*>( pTmpObj) != nullptr )
881 {
882 SwFlyFrame* pTmpFly = static_cast<SwFlyFrame*>(pTmpObj);
883 // #i28701# - use new method <GetPageFrame()>
884 if ( pTmpFly->IsFlyFreeFrame() && !pTmpFly->GetPageFrame() )
885 AppendFlyToPage( pTmpFly );
886 }
887 else if ( dynamic_cast<const SwAnchoredDrawObject*>( pTmpObj) != nullptr )
888 {
889 // #i87493#
890 if ( pTmpObj->GetPageFrame() != this )
891 {
892 if ( pTmpObj->GetPageFrame() != nullptr )
893 {
894 pTmpObj->GetPageFrame()->RemoveDrawObjFromPage( *pTmpObj );
895 }
896 AppendDrawObjToPage( *pTmpObj );
897 }
898 }
899 }
900}
901
902void SwPageFrame::RemoveFlyFromPage( SwFlyFrame *pToRemove )
903{
904 const sal_uInt32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum();
905 getRootFrame()->GetDrawPage()->RemoveObject( nOrdNum );
906 pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum );
907
908 if ( GetUpper() )
909 {
910 if ( !pToRemove->IsFlyInContentFrame() )
911 static_cast<SwRootFrame*>(GetUpper())->SetSuperfluous();
912 static_cast<SwRootFrame*>(GetUpper())->InvalidateBrowseWidth();
913 }
914
915 // Don't look further at Flys that sit inside the Content.
916 if ( pToRemove->IsFlyInContentFrame() )
917 return;
918
919 // Don't delete collections just yet. This will happen at the end of the
920 // action in the RemoveSuperfluous of the page, kicked off by a method of
921 // the same name in the root.
922 // The FlyColl might be gone already, because the page's dtor is being
923 // executed.
924 // Remove it _before_ disposing accessible frames to avoid accesses to
925 // the Frame from event handlers.
926 if (m_pSortedObjs)
927 {
928 m_pSortedObjs->Remove(*pToRemove);
929 if (!m_pSortedObjs->size())
930 {
931 m_pSortedObjs.reset();
932 }
933 }
934
935 // Notify accessible layout. That's required at this place for
936 // frames only where the anchor is moved. Creation of new frames
937 // is additionally handled by the SwFrameNotify class.
938 if( GetUpper() &&
939 static_cast< SwRootFrame * >( GetUpper() )->IsAnyShellAccessible() &&
940 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell() )
941 {
942 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell()->Imp()
943 ->DisposeAccessibleFrame( pToRemove, true );
944 }
945
946 // #i28701# - use new method <SetPageFrame(..)>
947 pToRemove->SetPageFrame( nullptr );
948}
949
950void SwPageFrame::MoveFly( SwFlyFrame *pToMove, SwPageFrame *pDest )
951{
952 // Invalidations
953 if ( GetUpper() )
954 {
955 static_cast<SwRootFrame*>(GetUpper())->SetIdleFlags();
956 if ( !pToMove->IsFlyInContentFrame() && pDest->GetPhyPageNum() < GetPhyPageNum() )
957 static_cast<SwRootFrame*>(GetUpper())->SetSuperfluous();
958 }
959
960 pDest->InvalidateSpelling();
961 pDest->InvalidateSmartTags();
962 pDest->InvalidateAutoCompleteWords();
963 pDest->InvalidateWordCount();
964
965 if ( pToMove->IsFlyInContentFrame() )
966 {
967 pDest->InvalidateFlyInCnt();
968 return;
969 }
970
971 // Notify accessible layout. That's required at this place for
972 // frames only where the anchor is moved. Creation of new frames
973 // is additionally handled by the SwFrameNotify class.
974 if( GetUpper() &&
975 static_cast< SwRootFrame * >( GetUpper() )->IsAnyShellAccessible() &&
976 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell() )
977 {
978 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell()->Imp()
979 ->DisposeAccessibleFrame( pToMove, true );
980 }
981
982 // The FlyColl might be gone already, because the page's dtor is being executed.
983 if ( m_pSortedObjs )
984 {
985 m_pSortedObjs->Remove( *pToMove );
986 if ( !m_pSortedObjs->size() )
987 {
988 m_pSortedObjs.reset();
989 }
990 }
991
992 // Register
993 if ( !pDest->GetSortedObjs() )
994 pDest->m_pSortedObjs.reset(new SwSortedObjs());
995
996 const bool bSuccessInserted = pDest->GetSortedObjs()->Insert( *pToMove );
997 OSL_ENSURE( bSuccessInserted, "Fly not inserted in Sorted." )do { if (true && (!(bSuccessInserted))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "997" ": "), "%s", "Fly not inserted in Sorted."); } } while
(false)
;
998
999 // #i28701# - use new method <SetPageFrame(..)>
1000 pToMove->SetPageFrame( pDest );
1001 pToMove->InvalidatePage( pDest );
1002 pToMove->SetNotifyBack();
1003 pDest->InvalidateFlyContent();
1004 // #i28701#
1005 pToMove->UnlockPosition();
1006
1007 // Notify accessible layout. That's required at this place for
1008 // frames only where the anchor is moved. Creation of new frames
1009 // is additionally handled by the SwFrameNotify class.
1010 if( GetUpper() &&
1011 static_cast< SwRootFrame * >( GetUpper() )->IsAnyShellAccessible() &&
1012 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell() )
1013 {
1014 static_cast< SwRootFrame * >( GetUpper() )->GetCurrShell()->Imp()
1015 ->AddAccessibleFrame( pToMove );
1016 }
1017
1018 // #i28701# - correction: move lowers of Writer fly frame
1019 if ( !pToMove->GetDrawObjs() )
1020 return;
1021
1022 SwSortedObjs &rObjs = *pToMove->GetDrawObjs();
1023 for (SwAnchoredObject* pObj : rObjs)
1024 {
1025 if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr )
1026 {
1027 SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pObj);
1028 if ( pFly->IsFlyFreeFrame() )
1029 {
1030 // #i28701# - use new method <GetPageFrame()>
1031 SwPageFrame* pPageFrame = pFly->GetPageFrame();
1032 if ( pPageFrame )
1033 pPageFrame->MoveFly( pFly, pDest );
1034 else
1035 pDest->AppendFlyToPage( pFly );
1036 }
1037 }
1038 else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr )
1039 {
1040 RemoveDrawObjFromPage( *pObj );
1041 pDest->AppendDrawObjToPage( *pObj );
1042 }
1043 }
1044}
1045
1046void SwPageFrame::AppendDrawObjToPage( SwAnchoredObject& _rNewObj )
1047{
1048 if ( dynamic_cast<const SwAnchoredDrawObject*>( &_rNewObj) == nullptr )
1049 {
1050 OSL_FAIL( "SwPageFrame::AppendDrawObjToPage(..) - anchored object of unexpected type -> object not appended" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1050" ": "), "%s", "SwPageFrame::AppendDrawObjToPage(..) - anchored object of unexpected type -> object not appended"
); } } while (false)
;
1051 return;
1052 }
1053
1054 if ( GetUpper() )
1055 {
1056 static_cast<SwRootFrame*>(GetUpper())->InvalidateBrowseWidth();
1057 }
1058
1059 assert(_rNewObj.GetAnchorFrame())(static_cast <bool> (_rNewObj.GetAnchorFrame()) ? void (
0) : __assert_fail ("_rNewObj.GetAnchorFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
, 1059, __extension__ __PRETTY_FUNCTION__))
;
1060 SwFlyFrame* pFlyFrame = const_cast<SwFlyFrame*>(_rNewObj.GetAnchorFrame()->FindFlyFrame());
1061 if ( pFlyFrame &&
1062 _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrame->GetVirtDrawObj()->GetOrdNum() )
1063 {
1064 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
1065 sal_uInt32 nNewNum = _rNewObj.GetDrawObj()->GetOrdNumDirect();
1066 if ( _rNewObj.GetDrawObj()->getSdrPageFromSdrObject() )
1067 _rNewObj.DrawObj()->getSdrPageFromSdrObject()->SetObjectOrdNum( pFlyFrame->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
1068 else
1069 pFlyFrame->GetVirtDrawObj()->SetOrdNum( nNewNum );
1070 }
1071
1072 if ( RndStdIds::FLY_AS_CHAR == _rNewObj.GetFrameFormat().GetAnchor().GetAnchorId() )
1073 {
1074 return;
1075 }
1076
1077 if ( !m_pSortedObjs )
1078 {
1079 m_pSortedObjs.reset(new SwSortedObjs());
1080 }
1081 if ( !m_pSortedObjs->Insert( _rNewObj ) )
1082 {
1083 OSL_ENSURE( m_pSortedObjs->Contains( _rNewObj ),do { if (true && (!(m_pSortedObjs->Contains( _rNewObj
)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1084" ": "), "%s", "Drawing object not appended into list <pSortedObjs>."
); } } while (false)
1084 "Drawing object not appended into list <pSortedObjs>." )do { if (true && (!(m_pSortedObjs->Contains( _rNewObj
)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1084" ": "), "%s", "Drawing object not appended into list <pSortedObjs>."
); } } while (false)
;
1085 }
1086 // #i87493#
1087 OSL_ENSURE( _rNewObj.GetPageFrame() == nullptr || _rNewObj.GetPageFrame() == this,do { if (true && (!(_rNewObj.GetPageFrame() == nullptr
|| _rNewObj.GetPageFrame() == this))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1088" ": "), "%s", "<SwPageFrame::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect."
); } } while (false)
1088 "<SwPageFrame::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect." )do { if (true && (!(_rNewObj.GetPageFrame() == nullptr
|| _rNewObj.GetPageFrame() == this))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1088" ": "), "%s", "<SwPageFrame::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect."
); } } while (false)
;
1089 _rNewObj.SetPageFrame( this );
1090
1091 // invalidate page in order to force a reformat of object layout of the page.
1092 InvalidateFlyLayout();
1093}
1094
1095void SwPageFrame::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj )
1096{
1097 if ( dynamic_cast<const SwAnchoredDrawObject*>( &_rToRemoveObj) == nullptr )
1098 {
1099 OSL_FAIL( "SwPageFrame::RemoveDrawObjFromPage(..) - anchored object of unexpected type -> object not removed" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1099" ": "), "%s", "SwPageFrame::RemoveDrawObjFromPage(..) - anchored object of unexpected type -> object not removed"
); } } while (false)
;
1100 return;
1101 }
1102
1103 if ( m_pSortedObjs )
1104 {
1105 m_pSortedObjs->Remove( _rToRemoveObj );
1106 if ( !m_pSortedObjs->size() )
1107 {
1108 m_pSortedObjs.reset();
1109 }
1110 if ( GetUpper() )
1111 {
1112 if (RndStdIds::FLY_AS_CHAR !=
1113 _rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId())
1114 {
1115 static_cast<SwRootFrame*>(GetUpper())->SetSuperfluous();
1116 InvalidatePage();
1117 }
1118 static_cast<SwRootFrame*>(GetUpper())->InvalidateBrowseWidth();
1119 }
1120 }
1121 _rToRemoveObj.SetPageFrame( nullptr );
1122}
1123
1124// #i50432# - adjust method description and synopsis.
1125void SwPageFrame::PlaceFly( SwFlyFrame* pFly, SwFlyFrameFormat* pFormat )
1126{
1127 // #i50432# - consider the case that page is an empty page:
1128 // In this case append the fly frame at the next page
1129 OSL_ENSURE( !IsEmptyPage() || GetNext(),do { if (true && (!(!IsEmptyPage() || GetNext()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1130" ": "), "%s", "<SwPageFrame::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page"
); } } while (false)
1130 "<SwPageFrame::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" )do { if (true && (!(!IsEmptyPage() || GetNext()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1130" ": "), "%s", "<SwPageFrame::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page"
); } } while (false)
;
1131 if ( IsEmptyPage() && GetNext() )
1132 {
1133 static_cast<SwPageFrame*>(GetNext())->PlaceFly( pFly, pFormat );
1134 }
1135 else
1136 {
1137 // If we received a Fly, we use that one. Otherwise, create a new
1138 // one using the Format.
1139 if ( pFly )
1140 AppendFly( pFly );
1141 else
1142 {
1143 OSL_ENSURE( pFormat, ":-( No Format given for Fly." )do { if (true && (!(pFormat))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1143" ": "), "%s", ":-( No Format given for Fly."); } }
while (false)
;
1144 pFly = new SwFlyLayFrame( pFormat, this, this );
1145 AppendFly( pFly );
1146 ::RegistFlys( this, pFly );
1147 }
1148 }
1149}
1150
1151// #i18732# - adjustments for following text flow or not
1152// AND alignment at 'page areas' for to paragraph/to character anchored objects
1153// #i22305# - adjustment for following text flow for to frame anchored objects
1154// #i29778# - Because calculating the floating screen object's position
1155// (Writer fly frame or drawing object) doesn't perform a calculation on its
1156// upper frames and its anchor frame, a calculation of the upper frames in this
1157// method is no longer sensible.
1158// #i28701# - if document compatibility option 'Consider wrapping style influence
1159// on object positioning' is ON, the clip area corresponds to the one as the
1160// object doesn't follow the text flow.
1161bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove )
1162{
1163 bool bRet = true;
1164 if ( auto pVirtFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(pSdrObj) )
1
Assuming 'pVirtFlyDrawObj' is null
2
Taking false branch
1165 {
1166 const SwFlyFrame* pFly = pVirtFlyDrawObj->GetFlyFrame();
1167 const bool bFollowTextFlow = pFly->GetFormat()->GetFollowTextFlow().GetValue();
1168 // #i28701#
1169 const bool bConsiderWrapOnObjPos =
1170 pFly->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION);
1171 const SwFormatVertOrient &rV = pFly->GetFormat()->GetVertOrient();
1172 if( pFly->IsFlyLayFrame() )
1173 {
1174 const SwFrame* pClip;
1175 // #i22305#
1176 // #i28701#
1177 if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
1178 {
1179 pClip = pFly->GetAnchorFrame()->FindPageFrame();
1180 }
1181 else
1182 {
1183 pClip = pFly->GetAnchorFrame();
1184 }
1185
1186 rRect = pClip->getFrameArea();
1187 SwRectFnSet aRectFnSet(pClip);
1188
1189 // vertical clipping: Top and Bottom, also to PrtArea if necessary
1190 if( rV.GetVertOrient() != text::VertOrientation::NONE &&
1191 rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
1192 {
1193 aRectFnSet.SetTop( rRect, aRectFnSet.GetPrtTop(*pClip) );
1194 aRectFnSet.SetBottom( rRect, aRectFnSet.GetPrtBottom(*pClip) );
1195 }
1196 // horizontal clipping: Top and Bottom, also to PrtArea if necessary
1197 const SwFormatHoriOrient &rH = pFly->GetFormat()->GetHoriOrient();
1198 if( rH.GetHoriOrient() != text::HoriOrientation::NONE &&
1199 rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
1200 {
1201 aRectFnSet.SetLeft( rRect, aRectFnSet.GetPrtLeft(*pClip) );
1202 aRectFnSet.SetRight(rRect, aRectFnSet.GetPrtRight(*pClip));
1203 }
1204 }
1205 else if( pFly->IsFlyAtContentFrame() )
1206 {
1207 // #i18732# - consider following text flow or not
1208 // AND alignment at 'page areas'
1209 const SwFrame* pVertPosOrientFrame = pFly->GetVertPosOrientFrame();
1210 if ( !pVertPosOrientFrame )
1211 {
1212 OSL_FAIL( "::CalcClipRect(..) - frame, vertical position is oriented at, is missing .")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1212" ": "), "%s", "::CalcClipRect(..) - frame, vertical position is oriented at, is missing ."
); } } while (false)
;
1213 pVertPosOrientFrame = pFly->GetAnchorFrame();
1214 }
1215
1216 if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
1217 {
1218 const SwLayoutFrame* pClipFrame = pVertPosOrientFrame->FindPageFrame();
1219 if (!pClipFrame)
1220 {
1221 OSL_FAIL("!pClipFrame: "do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1222" ": "), "%s", "!pClipFrame: " "if you can reproduce this please file a bug"
); } } while (false)
1222 "if you can reproduce this please file a bug")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1222" ": "), "%s", "!pClipFrame: " "if you can reproduce this please file a bug"
); } } while (false)
;
1223 return false;
1224 }
1225 rRect = bMove ? pClipFrame->GetUpper()->getFrameArea()
1226 : pClipFrame->getFrameArea();
1227 // #i26945# - consider that a table, during
1228 // its format, can exceed its upper printing area bottom.
1229 // Thus, enlarge the clip rectangle, if such a case occurred
1230 if ( pFly->GetAnchorFrame()->IsInTab() )
1231 {
1232 const SwTabFrame* pTabFrame = const_cast<SwFlyFrame*>(pFly)
1233 ->GetAnchorFrameContainingAnchPos()->FindTabFrame();
1234 SwRect aTmp( pTabFrame->getFramePrintArea() );
1235 aTmp += pTabFrame->getFrameArea().Pos();
1236 rRect.Union( aTmp );
1237 // #i43913# - consider also the cell frame
1238 const SwFrame* pCellFrame = const_cast<SwFlyFrame*>(pFly)
1239 ->GetAnchorFrameContainingAnchPos()->GetUpper();
1240 while ( pCellFrame && !pCellFrame->IsCellFrame() )
1241 {
1242 pCellFrame = pCellFrame->GetUpper();
1243 }
1244 if ( pCellFrame )
1245 {
1246 aTmp = pCellFrame->getFramePrintArea();
1247 aTmp += pCellFrame->getFrameArea().Pos();
1248 rRect.Union( aTmp );
1249 }
1250 }
1251 }
1252 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ||
1253 rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1254 {
1255 // new class <SwEnvironmentOfAnchoredObject>
1256 objectpositioning::SwEnvironmentOfAnchoredObject
1257 aEnvOfObj( bFollowTextFlow );
1258 const SwLayoutFrame& rVertClipFrame =
1259 aEnvOfObj.GetVertEnvironmentLayoutFrame( *pVertPosOrientFrame );
1260 if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME )
1261 {
1262 rRect = rVertClipFrame.getFrameArea();
1263 }
1264 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1265 {
1266 if ( rVertClipFrame.IsPageFrame() )
1267 {
1268 rRect = static_cast<const SwPageFrame&>(rVertClipFrame).PrtWithoutHeaderAndFooter();
1269 }
1270 else
1271 {
1272 rRect = rVertClipFrame.getFrameArea();
1273 }
1274 }
1275 const SwLayoutFrame* pHoriClipFrame =
1276 pFly->GetAnchorFrame()->FindPageFrame()->GetUpper();
1277 SwRectFnSet aRectFnSet(pFly->GetAnchorFrame());
1278 aRectFnSet.SetLeft( rRect, aRectFnSet.GetLeft(pHoriClipFrame->getFrameArea()) );
1279 aRectFnSet.SetRight(rRect, aRectFnSet.GetRight(pHoriClipFrame->getFrameArea()));
1280 }
1281 else
1282 {
1283 // #i26945#
1284 const SwFrame *pClip =
1285 const_cast<SwFlyFrame*>(pFly)->GetAnchorFrameContainingAnchPos();
1286 SwRectFnSet aRectFnSet(pClip);
1287 const SwLayoutFrame *pUp = pClip->GetUpper();
1288 const SwFrame *pCell = pUp->IsCellFrame() ? pUp : nullptr;
1289 const SwFrameType nType = bMove
1290 ? SwFrameType::Root | SwFrameType::Fly | SwFrameType::Header |
1291 SwFrameType::Footer | SwFrameType::Ftn
1292 : SwFrameType::Body | SwFrameType::Fly | SwFrameType::Header |
1293 SwFrameType::Footer | SwFrameType::Cell| SwFrameType::Ftn;
1294
1295 while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrame() )
1296 {
1297 pUp = pUp->GetUpper();
1298 if ( !pCell && pUp->IsCellFrame() )
1299 pCell = pUp;
1300 }
1301 if ( bMove && pUp->IsRootFrame() )
1302 {
1303 rRect = pUp->getFramePrintArea();
1304 rRect += pUp->getFrameArea().Pos();
1305 pUp = nullptr;
1306 }
1307 if ( pUp )
1308 {
1309 if ( pUp->GetType() & SwFrameType::Body )
1310 {
1311 const SwPageFrame *pPg;
1312 if ( pUp->GetUpper() != (pPg = pFly->FindPageFrame()) )
1313 pUp = pPg->FindBodyCont();
1314 if (pUp)
1315 {
1316 rRect = pUp->GetUpper()->getFrameArea();
1317 aRectFnSet.SetTop( rRect, aRectFnSet.GetPrtTop(*pUp) );
1318 aRectFnSet.SetBottom(rRect, aRectFnSet.GetPrtBottom(*pUp));
1319 }
1320 }
1321 else
1322 {
1323 if( ( pUp->GetType() & (SwFrameType::Fly | SwFrameType::Ftn ) ) &&
1324 !pUp->getFrameArea().IsInside( pFly->getFrameArea().Pos() ) )
1325 {
1326 if( pUp->IsFlyFrame() )
1327 {
1328 const SwFlyFrame *pTmpFly = static_cast<const SwFlyFrame*>(pUp);
1329 while( pTmpFly->GetNextLink() )
1330 {
1331 pTmpFly = pTmpFly->GetNextLink();
1332 if( pTmpFly->getFrameArea().IsInside( pFly->getFrameArea().Pos() ) )
1333 break;
1334 }
1335 pUp = pTmpFly;
1336 }
1337 else if( pUp->IsInFootnote() )
1338 {
1339 const SwFootnoteFrame *pTmp = pUp->FindFootnoteFrame();
1340 while( pTmp->GetFollow() )
1341 {
1342 pTmp = pTmp->GetFollow();
1343 if( pTmp->getFrameArea().IsInside( pFly->getFrameArea().Pos() ) )
1344 break;
1345 }
1346 pUp = pTmp;
1347 }
1348 }
1349 rRect = pUp->getFramePrintArea();
1350 rRect.Pos() += pUp->getFrameArea().Pos();
1351 if ( pUp->GetType() & (SwFrameType::Header | SwFrameType::Footer) )
1352 {
1353 rRect.Left ( pUp->GetUpper()->getFrameArea().Left() );
1354 rRect.Width( pUp->GetUpper()->getFrameArea().Width());
1355 }
1356 else if ( pUp->IsCellFrame() ) //MA_FLY_HEIGHT
1357 {
1358 const SwFrame *pTab = pUp->FindTabFrame();
1359 aRectFnSet.SetBottom( rRect, aRectFnSet.GetPrtBottom(*pTab->GetUpper()) );
1360 // expand to left and right cell border
1361 rRect.Left ( pUp->getFrameArea().Left() );
1362 rRect.Width( pUp->getFrameArea().Width() );
1363 }
1364 }
1365 }
1366 if ( pCell )
1367 {
1368 // CellFrames might also sit in unallowed areas. In this case,
1369 // the Fly is allowed to do so as well
1370 SwRect aTmp( pCell->getFramePrintArea() );
1371 aTmp += pCell->getFrameArea().Pos();
1372 rRect.Union( aTmp );
1373 }
1374 }
1375 }
1376 else
1377 {
1378 const SwFrame *pUp = pFly->GetAnchorFrame()->GetUpper();
1379 SwRectFnSet aRectFnSet(pFly->GetAnchorFrame());
1380 while( pUp->IsColumnFrame() || pUp->IsSctFrame() || pUp->IsColBodyFrame())
1381 pUp = pUp->GetUpper();
1382 rRect = pUp->getFrameArea();
1383 if( !pUp->IsBodyFrame() )
1384 {
1385 rRect += pUp->getFramePrintArea().Pos();
1386 rRect.SSize( pUp->getFramePrintArea().SSize() );
1387 if ( pUp->IsCellFrame() )
1388 {
1389 const SwFrame *pTab = pUp->FindTabFrame();
1390 aRectFnSet.SetBottom( rRect, aRectFnSet.GetPrtBottom(*pTab->GetUpper()) );
1391 }
1392 }
1393 else if ( pUp->GetUpper()->IsPageFrame() )
1394 {
1395 // Objects anchored as character may exceed right margin
1396 // of body frame:
1397 aRectFnSet.SetRight( rRect, aRectFnSet.GetRight(pUp->GetUpper()->getFrameArea()) );
1398 }
1399 long nHeight = (9*aRectFnSet.GetHeight(rRect))/10;
1400 long nTop;
1401 const SwFormat *pFormat = GetUserCall(pSdrObj)->GetFormat();
1402 const SvxULSpaceItem &rUL = pFormat->GetULSpace();
1403 if( bMove )
1404 {
1405 nTop = aRectFnSet.IsVert() ? static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X() :
1406 static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y();
1407 nTop = aRectFnSet.YInc( nTop, -nHeight );
1408 long nWidth = aRectFnSet.GetWidth(pFly->getFrameArea());
1409 aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
1410 static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y() :
1411 static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X(), nWidth );
1412 nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper();
1413 }
1414 else
1415 {
1416 nTop = aRectFnSet.YInc( aRectFnSet.GetBottom(pFly->getFrameArea()),
1417 rUL.GetLower() - nHeight );
1418 nHeight = 2*nHeight - aRectFnSet.GetHeight(pFly->getFrameArea())
1419 - rUL.GetLower() - rUL.GetUpper();
1420 }
1421 aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight );
1422 }
1423 }
1424 else
1425 {
1426 const SwDrawContact *pC = static_cast<const SwDrawContact*>(GetUserCall(pSdrObj));
1427 const SwFrameFormat *pFormat = pC->GetFormat();
1428 const SwFormatAnchor &rAnch = pFormat->GetAnchor();
1429 if ( RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId() )
3
Assuming the condition is true
4
Taking true branch
1430 {
1431 const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj );
1432 if( !pAnchorFrame )
5
Assuming 'pAnchorFrame' is non-null
6
Taking false branch
1433 {
1434 OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/flylay.cxx"
":" "1434" ": "), "%s", "<::CalcClipRect(..)> - missing anchor frame."
); } } while (false)
;
1435 const_cast<SwDrawContact*>(pC)->ConnectToLayout();
1436 pAnchorFrame = pC->GetAnchorFrame();
1437 }
1438 const SwFrame* pUp = pAnchorFrame->GetUpper();
1439 rRect = pUp->getFramePrintArea();
1440 rRect += pUp->getFrameArea().Pos();
1441 SwRectFnSet aRectFnSet(pAnchorFrame);
1442 long nHeight = (9*aRectFnSet.GetHeight(rRect))/10;
1443 long nTop;
1444 const SvxULSpaceItem &rUL = pFormat->GetULSpace();
1445 SwRect aSnapRect( pSdrObj->GetSnapRect() );
7
Called C++ object pointer is null
1446 long nTmpH = 0;
1447 if( bMove )
1448 {
1449 nTop = aRectFnSet.YInc( aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().X() :
1450 pSdrObj->GetAnchorPos().Y(), -nHeight );
1451 long nWidth = aRectFnSet.GetWidth(aSnapRect);
1452 aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
1453 pSdrObj->GetAnchorPos().Y() :
1454 pSdrObj->GetAnchorPos().X(), nWidth );
1455 }
1456 else
1457 {
1458 // #i26791# - value of <nTmpH> is needed to
1459 // calculate value of <nTop>.
1460 nTmpH = aRectFnSet.IsVert() ? pSdrObj->GetCurrentBoundRect().GetWidth() :
1461 pSdrObj->GetCurrentBoundRect().GetHeight();
1462 nTop = aRectFnSet.YInc( aRectFnSet.GetTop(aSnapRect),
1463 rUL.GetLower() + nTmpH - nHeight );
1464 }
1465 nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
1466 aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight );
1467 }
1468 else
1469 {
1470 // restrict clip rectangle for drawing
1471 // objects in header/footer to the page frame.
1472 // #i26791#
1473 const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj );
1474 if ( pAnchorFrame && pAnchorFrame->FindFooterOrHeader() )
1475 {
1476 // clip frame is the page frame the header/footer is on.
1477 const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame();
1478 rRect = pClipFrame->getFrameArea();
1479 }
1480 else
1481 {
1482 bRet = false;
1483 }
1484 }
1485 }
1486 return bRet;
1487}
1488
1489/* vim:set shiftwidth=4 softtabstop=4 expandtab: */