Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/sw/inc/anchoredobject.hxx
Line
Count
Source (jump to first uncovered line)
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
#pragma once
20
21
#include "swtypes.hxx"
22
#include "swrect.hxx"
23
#include <svx/svdobj.hxx>
24
#include <libxml/xmlwriter.h>
25
26
class SwFrame;
27
class SwLayoutFrame;
28
class SwTextFrame;
29
class SwFlyFrame;
30
class SwPageFrame;
31
32
class SwFrameFormat;
33
class SwFormatAnchor;
34
enum class RndStdIds;
35
36
/** wrapper class for the positioning of Writer fly frames and drawing objects
37
38
    Purpose of this class is to provide a unified interface for the positioning
39
    of Writer fly frames (derived classes of <SwFlyFrame>) and of drawing objects
40
    (derived classes of <SwAnchoredDrawObject>).
41
*/
42
class SAL_DLLPUBLIC_RTTI SwAnchoredObject
43
{
44
    private:
45
        // drawing object representing the anchored object in the drawing layer
46
        rtl::Reference<SdrObject> mpDrawObj;
47
        /// Frame the object is anchored at.
48
        /// For at-char/at-para anchor, this is always the master SwTextFrame.
49
        SwFrame* mpAnchorFrame;
50
        // #i28701 - page frame the object is registered at
51
        // note: no page frame for as-character anchored objects
52
        SwPageFrame* mpPageFrame;
53
        // current relative position (relative to anchor position of anchor frame)
54
        Point maRelPos;
55
56
        // for to-character anchored objects:
57
        // Last known anchor character rectangle.
58
        // Used to decide, if invalidation has to been performed, if anchor position
59
        // has changed, and used to position object.
60
        SwRect maLastCharRect;
61
62
        // for to-character anchored objects:
63
        // Last known top of line, in which the anchor character is in.
64
        // Used to decide, if invalidation has to been performed, if anchor position
65
        // has changed, and used to position object.
66
        SwTwips mnLastTopOfLine;
67
68
        // for to-paragraph and to-character anchored objects:
69
        // Layout frame vertical position is orient at - typically it's the upper
70
        // of the anchor frame, but it could also by the upper of a follow or
71
        // a following layout frame in the text flow.
72
        const SwLayoutFrame* mpVertPosOrientFrame;
73
74
        // i#i28701 boolean, indicating that the object
75
        // positioning algorithm is in progress.
76
        bool mbPositioningInProgress;
77
78
        // Booleans needed for the layout process.
79
        // Values only of relevance for to-paragraph and to-character anchored
80
        // floating screen object, for whose the 'straight-forward positioning
81
        // process are applied
82
        // Otherwise value of <mbConsiderForTextWrap> is treated as <true>,
83
        // value of <mbPositionLocked> is treated as <false> and
84
        // value of <mbRestartLayoutProcess> is treated as <false>.
85
        // i#35911 - add boolean <mbClearEnvironment>
86
        // Indicates that due to its position and wrapping style its layout
87
        // environment is cleared - all content is moved forward.
88
        // Treated as <false>, if not the 'straight-forward positioning process"
89
        // is applied.
90
        bool mbConsiderForTextWrap;
91
        bool mbPositionLocked;
92
        // boolean needed to keep position of
93
        // anchored object locked due to special object positioning for sections.
94
        bool mbKeepPositionLockedForSection;
95
96
        bool mbRestartLayoutProcess;
97
        bool mbClearedEnvironment;
98
99
        // i#i3317 - boolean, indicating that temporarily
100
        // the wrapping style influence of the anchored object has to be
101
        // considered during its positioning.
102
        // This boolean is used, if compatibility option 'Consider wrapping style
103
        // influence on object positioning' is OFF and a positioning loop is
104
        // detected in method <SwFlyAtContentFrame::MakeAll()> or method
105
        // <SwAnchoredDrawObject::MakeObjPosAnchoredAtPara()>.
106
        // The boolean is reset to <false>, when the layout process for a
107
        // page frame starts.
108
        bool mbTmpConsiderWrapInfluence;
109
110
        bool mbForceNotifyNewBackground = false;
111
112
        mutable SwRect maObjRectWithSpaces;
113
        mutable bool mbObjRectWithSpacesValid;
114
        mutable SwRect maLastObjRect;
115
116
        /** method to indicate, that positioning of anchored object is in progress
117
118
            note: method is implemented empty
119
        */
120
        friend class SwObjPositioningInProgress;
121
        void SetPositioningInProgress( const bool _bPosInProgress )
122
342k
        {
123
342k
            mbPositioningInProgress = _bPosInProgress;
124
342k
        }
125
126
        /** check anchor character rectangle
127
128
            helper method for method <CheckCharRectAndTopOfLine()>
129
            For to-character anchored Writer fly frames the member <maLastCharRect>
130
            is updated. This is checked for change and depending on the applied
131
            positioning, it's decided, if the Writer fly frame has to be invalidated.
132
            improvement - add second parameter <_rAnchorCharFrame>
133
134
            @param _rAnch
135
            input parameter - reference to anchor position
136
137
            @param _rAnchorCharFrame
138
            input parameter - reference to the text frame containing the anchor
139
            character.
140
        */
141
        void CheckCharRect( const SwFormatAnchor& _rAnch,
142
                             const SwTextFrame& _rAnchorCharFrame );
143
144
        /** check top of line
145
146
            helper method for method <CheckCharRectAndTopOfLine()>
147
            For to-character anchored Writer fly frames the member <mnLastTopOfLine>
148
            is updated. This is checked for change and depending on the applied
149
            positioning, it's decided, if the Writer fly frame has to be invalidated.
150
151
            @param _rAnch
152
            input parameter - reference to anchor position
153
154
            @param _rAnchorCharFrame
155
            input parameter - reference to the text frame containing the anchor
156
            character.
157
        */
158
        void CheckTopOfLine( const SwFormatAnchor& _rAnch,
159
                              const SwTextFrame& _rAnchorCharFrame );
160
161
        // method <sw_HideObj(..)> sets needed data structure values for the
162
        // object positioning
163
        friend bool sw_HideObj( const SwTextFrame& _rFrame,
164
                                 const RndStdIds _eAnchorType,
165
                                 SwFormatAnchor const& rFormatAnchor,
166
                                 SwAnchoredObject* _pAnchoredObj );
167
    protected:
168
        SwAnchoredObject();
169
170
        void SetVertPosOrientFrame( const SwLayoutFrame& _rVertPosOrientFrame );
171
172
        /** method to assure that anchored object is registered at the correct
173
            page frame
174
        */
175
        virtual void RegisterAtCorrectPage() = 0;
176
177
        /** method to indicate, that anchored object is attached to an anchor frame */
178
        virtual void ObjectAttachedToAnchorFrame();
179
180
        /** method to determine, if other anchored objects, also attached at
181
            to the anchor frame, have to consider its wrap influence.
182
        */
183
        bool ConsiderObjWrapInfluenceOfOtherObjs() const;
184
185
        /** method to apply temporary consideration of wrapping style influence
186
            to the anchored objects, which are anchored at the same anchor frame
187
        */
188
        void SetTmpConsiderWrapInfluenceOfOtherObjs();
189
190
        virtual bool SetObjTop_( const SwTwips _nTop) = 0;
191
        virtual bool SetObjLeft_( const SwTwips _nLeft) = 0;
192
193
        virtual SwRect GetObjBoundRect() const = 0;
194
    public:
195
196
        virtual ~SwAnchoredObject();
197
198
        // accessors to member <mpDrawObj>
199
        void SetDrawObj( SdrObject& _rDrawObj );
200
2.49M
        const SdrObject* GetDrawObj() const { return mpDrawObj.get(); }
201
2.93M
        SdrObject* DrawObj() { return mpDrawObj.get(); }
202
205k
        void ClearDrawObj() { mpDrawObj.clear(); }
203
204
        // accessors to member <mpAnchorFrame>
205
3.56M
        const SwFrame* GetAnchorFrame() const { return mpAnchorFrame; }
206
1.24M
        SwFrame* AnchorFrame() { return mpAnchorFrame; }
207
        void ChgAnchorFrame( SwFrame* _pNewAnchorFrame );
208
        /** determine anchor frame containing the anchor position
209
210
            the anchor frame, which is determined, is <mpAnchorFrame>
211
            for an at-page, at-frame or at-paragraph anchored object
212
            and the anchor character frame for an at-character and as-character
213
            anchored object.
214
        */
215
        SW_DLLPUBLIC SwFrame* GetAnchorFrameContainingAnchPos();
216
217
892k
        SwPageFrame* GetPageFrame() { return mpPageFrame; }
218
422k
        const SwPageFrame* GetPageFrame() const { return mpPageFrame; }
219
        void SetPageFrame( SwPageFrame* _pNewPageFrame );
220
221
        /** method to determine the page frame, on which the 'anchor' of
222
            the given anchored object is.
223
224
            Adjust meaning of method and thus its name: If the anchored object
225
            or its anchor isn't correctly inserted in the layout, no page frame
226
            can be found. Thus, the return type changed to be a pointer and can
227
            be NULL.
228
229
            @param _rAnchoredObj
230
            input parameter - anchored object, for which the page frame of its
231
            'anchor' has to be determined.
232
233
            @return SwPageFrame&
234
            page frame, the 'anchor' of the given anchored object is on
235
        */
236
        SwPageFrame* FindPageFrameOfAnchor();
237
238
        /** get frame, which contains the anchor character, if the object
239
            is anchored at-character or as-character.
240
241
            @return SwTextFrame*
242
            text frame containing the anchor character. It's NULL, if the object
243
            isn't anchored at-character resp. as-character.
244
        */
245
        SwTextFrame* FindAnchorCharFrame();
246
247
        // accessors to data of position calculation:
248
        // frame vertical position is orient at
249
        const SwLayoutFrame* GetVertPosOrientFrame() const
250
129k
        {
251
129k
            return mpVertPosOrientFrame;
252
129k
        }
253
        // method to clear member <mpVertPosOrientFrame>
254
        void ClearVertPosOrientFrame();
255
256
        /** check anchor character rectangle and top of line
257
258
            For to-character anchored Writer fly frames the members <maLastCharRect>
259
            and <maLastTopOfLine> are updated. These are checked for change and
260
            depending on the applied positioning, it's decided, if the Writer fly
261
            frame has to be invalidated.
262
263
            @param _bCheckForParaPorInf
264
            input parameter - boolean indicating, if check on paragraph portion
265
            information has to be done.
266
        */
267
        void CheckCharRectAndTopOfLine( const bool _bCheckForParaPorInf );
268
269
        // accessors to member <maLastCharRect>
270
594
        const SwRect& GetLastCharRect() const { return maLastCharRect;}
271
        SwTwips GetRelCharX( const SwFrame* pFrame ) const;
272
        SwTwips GetRelCharY( const SwFrame* pFrame ) const;
273
        void AddLastCharY( tools::Long nDiff );
274
        void ResetLastCharRectHeight();
275
276
        // accessor to member <nmLastTopOfLine>
277
594
        SwTwips GetLastTopOfLine() const { return mnLastTopOfLine;}
278
        void AddLastTopOfLineY( SwTwips _nDiff );
279
280
        /** reset members <maLastCharRect> and <mnLastTopOfLine> */
281
        void ClearCharRectAndTopOfLine();
282
283
        /** method to determine position for the object and set the position
284
            at the object
285
        */
286
        virtual void MakeObjPos() = 0;
287
288
        /** is positioning of anchored object in progress */
289
        bool IsPositioningInProgress() const
290
597k
        {
291
597k
            return mbPositioningInProgress;
292
597k
        }
293
294
        /** method to determine, if invalidation of position is allowed */
295
        bool InvalidationOfPosAllowed() const;
296
297
        /** method to invalidate position of the anchored object */
298
        virtual void InvalidateObjPos() = 0;
299
300
        virtual void RegisterAtPage(SwPageFrame &) = 0;
301
302
        /** method to perform necessary invalidations for the positioning of
303
            objects, for whose the wrapping style influence has to be considered
304
            on the object positioning.
305
        */
306
        void InvalidateObjPosForConsiderWrapInfluence();
307
308
        /** method to trigger notification of 'background' */
309
        virtual void NotifyBackground( SwPageFrame* _pPageFrame,
310
                                       const SwRect& _rRect,
311
                                       PrepareHint _eHint ) = 0;
312
313
        // accessors to the current relative position (relative to anchor
314
        // position of anchor frame)
315
63.1k
        const Point& GetCurrRelPos() const { return maRelPos;}
316
        void SetCurrRelPos( Point _aRelPos );
317
318
        // accessors to the format
319
        virtual SwFrameFormat* GetFrameFormat() = 0;
320
        virtual const SwFrameFormat* GetFrameFormat() const = 0;
321
322
        // accessors to the object area and its position
323
        virtual SwRect GetObjRect() const = 0;
324
325
        void SetObjTop( const SwTwips _nTop);
326
        void SetObjLeft( const SwTwips _nLeft);
327
328
        /** method update layout direction the layout direction, the anchored
329
            object is assigned to
330
331
            method has typically to be called, if the anchored object gets its
332
            anchor frame assigned and if the anchor frame changes its layout direction
333
        */
334
        virtual void UpdateLayoutDir();
335
336
        /** method to determine object area inclusive its spacing */
337
        SW_DLLPUBLIC const SwRect& GetObjRectWithSpaces() const;
338
339
        void InvalidateObjRectWithSpaces() const
340
105k
        {
341
105k
            mbObjRectWithSpacesValid = false;
342
105k
        }
343
344
        /** method to determine, if wrapping style influence of the anchored
345
            object has to be considered on the object positioning
346
347
            Note: result of this method also decides, if the boolean for the
348
            layout process are of relevance.
349
        */
350
        bool ConsiderObjWrapInfluenceOnObjPos() const;
351
352
        // accessors to booleans for layout process
353
        bool ConsiderForTextWrap() const;
354
        void SetConsiderForTextWrap( const bool _bConsiderForTextWrap );
355
        bool PositionLocked() const;
356
        void LockPosition()
357
6
        {
358
6
            mbPositionLocked = true;
359
6
        }
360
        void UnlockPosition()
361
59.9k
        {
362
59.9k
            if ( !mbKeepPositionLockedForSection )
363
59.9k
            {
364
59.9k
                mbPositionLocked = false;
365
59.9k
            }
366
59.9k
        }
367
368
        void SetKeepPosLocked( const bool _bKeepPosLocked )
369
0
        {
370
0
            mbKeepPositionLockedForSection = _bKeepPosLocked;
371
0
        }
372
373
        bool RestartLayoutProcess() const;
374
        void SetRestartLayoutProcess( const bool _bRestartLayoutProcess );
375
        // accessors for <mbClearedEnvironment>
376
        bool ClearedEnvironment() const;
377
        void SetClearedEnvironment( const bool _bClearedEnvironment );
378
379
        // reset booleans for layout process
380
        void ResetLayoutProcessBools()
381
37.9k
        {
382
37.9k
            mbPositioningInProgress = false;
383
37.9k
            mbConsiderForTextWrap = false;
384
37.9k
            mbPositionLocked = false;
385
37.9k
            mbKeepPositionLockedForSection = false;
386
37.9k
            mbRestartLayoutProcess = false;
387
37.9k
            mbClearedEnvironment = false;
388
37.9k
            mbTmpConsiderWrapInfluence = false;
389
37.9k
        }
390
391
        /** method to determine, if due to anchored object size and wrapping
392
            style, its layout environment is cleared.
393
        */
394
        bool HasClearedEnvironment() const;
395
396
        /** method to update anchored object in the <SwSortedObjs> lists
397
398
            Method is not proposed to be called during a layout process is
399
            running. It has been used on the change of the anchored object
400
            attributes, which belongs the sort criteria of <SwSortedObjs>.
401
            If document compatibility option 'Consider wrapping style influence
402
            on object positioning' is ON, additionally all anchored objects
403
            at the anchor frame and all following anchored objects on the page
404
            frame are invalidated.
405
        */
406
        void UpdateObjInSortedList();
407
408
        /** method to determine, if a format on the anchored object is possible
409
410
            A format isn't possible, if anchored object is in an invisible layer.
411
            Note: method is virtual to refine the conditions for the sub-classes.
412
        */
413
        virtual bool IsFormatPossible() const;
414
415
        /** method to determine if dragging objects off page is allowed
416
417
            Returns true if editor objects can be dragged off page, false otherwise
418
        */
419
        static bool IsDraggingOffPageAllowed(const SwFrameFormat*);
420
421
        // accessors to member <mbTmpConsiderWrapInfluence>
422
        void SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrapInfluence );
423
313k
        bool IsTmpConsiderWrapInfluence() const { return mbTmpConsiderWrapInfluence;}
424
        void ClearTmpConsiderWrapInfluence();
425
426
35.0k
        bool IsForceNotifyNewBackground() { return mbForceNotifyNewBackground; }
427
0
        void SetForceNotifyNewBackground(bool const b) { mbForceNotifyNewBackground = b; }
428
429
        /** method to determine, if the anchored object is overlapping with a
430
            previous column
431
432
            overlapping with a previous column means, that the object overlaps
433
            with a column, which is a previous one of the column its anchor
434
            frame is in.
435
            Only applied for at-paragraph and at-character anchored objects.
436
        */
437
        bool OverlapsPrevColumn() const;
438
439
        /** method to determine position of anchored object relative to
440
            anchor frame
441
442
            Usage: Needed layout information for WW8 export
443
444
            @return Point - determined relative position
445
        */
446
        Point GetRelPosToAnchorFrame() const;
447
448
        /** method to determine position of anchored object relative to
449
            page frame
450
451
            Usage: Needed layout information for WW8 export
452
453
            If <_bFollowTextFlow> is set and object is anchored inside table,
454
            the position relative to the table cell is determined. Output
455
            parameter <_obRelToTableCell> reflects this situation
456
457
            @param _bFollowTextFlow
458
            input parameter - boolean indicating, if the anchored object has to
459
            follow the text flow.
460
461
            @param _obRelToTableCell
462
            output parameter - boolean indicating, the determine position is
463
            relative to the table cell
464
465
            @return Point - determined relative position
466
        */
467
        Point GetRelPosToPageFrame( const bool _bFollowTextFlow,
468
                                  bool& _obRelToTableCell ) const;
469
470
        /** method to determine position of anchored object relative to
471
            anchor character
472
473
            Usage: Needed layout information for WW8 export
474
475
            @return Point - determined relative position
476
        */
477
        Point GetRelPosToChar() const;
478
479
        /** method to determine position of anchored object relative to
480
            top of line
481
482
            Usage: Needed layout information for WW8 export
483
484
            @return Point - determined relative position
485
        */
486
        Point GetRelPosToLine() const;
487
488
        /** Dump a bunch of useful data to an XML representation to ease
489
            layout understanding, debugging and testing.
490
          */
491
        virtual void dumpAsXml( xmlTextWriterPtr pWriter = nullptr ) const;
492
493
        /** The element name to show in the XML dump. */
494
0
        virtual const char* getElementName( ) const { return "SwAnchoredObject"; }
495
496
        virtual const SwFlyFrame* DynCastFlyFrame() const;
497
        virtual SwFlyFrame* DynCastFlyFrame();
498
};
499
500
/// Helper class for notify that positioning of an anchored object is in progress.
501
class SwObjPositioningInProgress
502
{
503
    private:
504
        SwAnchoredObject* mpAnchoredObj;
505
        // boolean indicating old state
506
        // of anchored object regarding positioning in progress in order to
507
        // consider nested usage of class <SwObjPositioningInProgress>
508
        bool mbOldObjPositioningInProgress;
509
510
    public:
511
        SwObjPositioningInProgress( SdrObject& _rSdrObj );
512
        SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj );
513
        ~SwObjPositioningInProgress();
514
};
515
516
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */