Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / inc / frmtool.hxx
blobffc218b5504ed184b80ed20e3a3f272e0412aded
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SW_SOURCE_CORE_INC_FRMTOOL_HXX
21 #define INCLUDED_SW_SOURCE_CORE_INC_FRMTOOL_HXX
23 #include <swtypes.hxx>
24 #include <frameformats.hxx>
25 #include <BorderCacheOwner.hxx>
26 #include "frame.hxx"
27 #include "txtfrm.hxx"
28 #include "swcache.hxx"
29 #include <swatrset.hxx>
31 class SwLayoutFrame;
32 class SwFont;
33 class SwTextFrame;
34 class SwFormatAnchor;
35 class SwViewShell;
36 class SwPageFrame;
37 class SwFlyFrame;
38 class SwContentFrame;
39 class SwRootFrame;
40 class SwDoc;
41 class SdrObject;
42 class SvxBrushItem;
43 class SdrMarkList;
44 class SwNodeIndex;
45 class GraphicObject;
46 class GraphicAttr;
47 class SwPageDesc;
48 class SwRegionRects;
49 class SwTextNode;
50 namespace sw { struct Extent; }
51 namespace basegfx::utils { class B2DClipState; }
53 #define FAR_AWAY (SAL_MAX_INT32 - 20000) // initial position of a Fly
54 constexpr tools::Long BROWSE_HEIGHT = 56700 * 10; // 10 Meters
55 #define GRFNUM_NO 0
56 #define GRFNUM_YES 1
57 #define GRFNUM_REPLACE 2
59 void AppendObjs(const sw::FrameFormats<sw::SpzFrameFormat*>* pSpz, SwNodeOffset nIndex, SwFrame* pFrame, SwPageFrame* pPage, SwDoc* doc);
61 void AppendObjsOfNode(sw::FrameFormats<sw::SpzFrameFormat*> const* pTable, SwNodeOffset nIndex,
62 SwFrame * pFrame, SwPageFrame * pPage, SwDoc * pDoc,
63 std::vector<sw::Extent>::const_iterator const* pIter,
64 std::vector<sw::Extent>::const_iterator const* pEnd,
65 SwTextNode const* pFirstNode, SwTextNode const* pLastNode);
67 void RemoveHiddenObjsOfNode(SwTextNode const& rNode,
68 std::vector<sw::Extent>::const_iterator const* pIter,
69 std::vector<sw::Extent>::const_iterator const* pEnd,
70 SwTextNode const* pFirstNode, SwTextNode const* pLastNode);
72 bool IsAnchoredObjShown(SwTextFrame const& rFrame, SwFormatAnchor const& rAnchor);
74 void AppendAllObjs(const sw::FrameFormats<sw::SpzFrameFormat*>* pSpzs, const SwFrame* pSib);
76 // draw background with brush or graphics
77 // The 6th parameter indicates that the method should consider background
78 // transparency, saved in the color of the brush item.
79 void DrawGraphic(
80 const SvxBrushItem *,
81 vcl::RenderContext &,
82 const SwRect &rOrg,
83 const SwRect &rOut,
84 const sal_uInt8 nGrfNum = GRFNUM_NO,
85 const bool bConsiderBackgroundTransparency = false );
86 bool DrawFillAttributes(
87 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
88 const SwRect& rOriginalLayoutRect,
89 const SwRegionRects& rPaintRegion,
90 const basegfx::utils::B2DClipState& rClipState,
91 vcl::RenderContext& rOut);
93 // RotGrfFlyFrame: Adapted to rotation
94 void paintGraphicUsingPrimitivesHelper(
95 vcl::RenderContext & rOutputDevice,
96 GraphicObject const& rGraphicObj,
97 GraphicAttr const& rGraphicAttr,
98 const basegfx::B2DHomMatrix& rGraphicTransform,
99 const OUString& rName,
100 const OUString& rTitle,
101 const OUString& rDescription);
103 // MM02 new VOC and primitive-based version
104 void paintGraphicUsingPrimitivesHelper(
105 vcl::RenderContext & rOutputDevice,
106 drawinglayer::primitive2d::Primitive2DContainer& rContent,
107 const basegfx::B2DHomMatrix& rGraphicTransform,
108 const OUString& rName,
109 const OUString& rTitle,
110 const OUString& rDescription);
112 // method to align rectangle.
113 // Created declaration here to avoid <extern> declarations
114 void SwAlignRect( SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext* pRenderContext );
116 // method to align graphic rectangle
117 // Created declaration here to avoid <extern> declarations
118 void SwAlignGrfRect( SwRect *pGrfRect, const vcl::RenderContext &rOut );
121 * Paint border around a run of characters using frame painting code.
123 * @param[in] rFont font object of actual text, which specify the border
124 * @param[in] rPaintArea rectangle area in which line portion takes place
125 * @param[in] bVerticalLayout corresponding text frame verticality
126 * @param[in] bVerticalLayoutLRBT corresponding text frame verticality (LRBT subset)
127 * @param[in] bJoinWithPrev leave border with which actual border joins to the previous portion
128 * @param[in] bJoinWithNext leave border with which actual border joins to the next portion
130 void PaintCharacterBorder(const SwFont& rFont, const SwRect& rPaintArea, const bool bVerticalLayout,
131 const bool bVerticalLayoutLRBT, const bool bJoinWithPrev,
132 const bool bJoinWithNext);
134 // get Fly, if no List is given use the current shell
135 // Implementation in feshview.cxx
136 SwFlyFrame *GetFlyFromMarked( const SdrMarkList *pLst, SwViewShell *pSh );
138 SwFrame *SaveContent( SwLayoutFrame *pLay, SwFrame *pStart = nullptr );
139 void RestoreContent( SwFrame *pSav, SwLayoutFrame *pParent, SwFrame *pSibling );
141 // Get ContentNodes, create ContentFrames, and add them to LayFrame.
142 void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, SwNodeOffset nIndex,
143 bool bPages = false, SwNodeOffset nEndIndex = SwNodeOffset(0),
144 SwFrame *pPrv = nullptr, sw::FrameMode eMode = sw::FrameMode::New);
146 // Creation of frames for a specific section (uses InsertCnt_)
147 void MakeFrames( SwDoc *pDoc, SwNode &rSttIdx,
148 SwNode &rEndIdx );
150 extern bool bObjsDirect;
152 // for FlyCnts, see SwFlyAtContentFrame::MakeAll()
153 extern bool bSetCompletePaintOnInvalidate;
155 // for table settings via keyboard
156 SwTwips CalcRowRstHeight( SwLayoutFrame *pRow );
157 tools::Long CalcHeightWithFlys( const SwFrame *pFrame );
159 namespace sw {
160 bool HasPageBreakBefore(SwPageFrame const& rPage);
161 bool IsRightPageByNumber(SwRootFrame const& rLayout, sal_uInt16 nPageNum);
162 class FlyCreationSuppressor
164 const bool m_wasAlreadySuppressed;
165 public:
166 FlyCreationSuppressor(bool isAlreadySuppressedAllowed = true);
167 ~FlyCreationSuppressor();
169 } // namespace sw
171 SwPageFrame *InsertNewPage( SwPageDesc &rDesc, SwFrame *pUpper,
172 bool isRightPage, bool bFirst, bool bInsertEmpty, bool bFootnote,
173 SwFrame *pSibling, bool bVeryFirstPage = false );
175 // connect Flys with page
176 void RegistFlys( SwPageFrame*, const SwLayoutFrame* );
178 // notification of Fly's background if needed
179 void Notify( SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld,
180 const SwRect* pOldRect = nullptr );
182 void Notify_Background( const SdrObject* pObj,
183 SwPageFrame* pPage,
184 const SwRect& rRect,
185 const PrepareHint eHint,
186 const bool bInva );
188 const SwFrame* GetVirtualUpper( const SwFrame* pFrame, const Point& rPos );
190 bool Is_Lower_Of( const SwFrame *pCurrFrame, const SdrObject* pObj );
192 // FIXME: EasyHack (refactoring): rename method and parameter name in all files
193 const SwFrame *FindContext( const SwFrame *pFrame, SwFrameType nAdditionalContextTyp );
195 bool IsFrameInSameContext( const SwFrame *pInnerFrame, const SwFrame *pFrame );
197 const SwFrame * FindPage( const SwRect &rRect, const SwFrame *pPage );
199 /** @see SwContentNode::getLayoutFrame()
200 @param pPos
201 Document model position; for a text frame, the returned frame will be
202 one containing this position.
203 @param pViewPosAndCalcFrame
204 First is a point in the document view; the returned frame will be the one
205 with the minimal distance to this point. To get the first frame in the
206 document, pass in a default-initialized Point with coordinates 0,0.
207 Second indicates whether the frames should be formatted before retrieving
208 their position for the test; this cannot be done by every caller so use
209 with care!
211 SwFrame* GetFrameOfModify( const SwRootFrame* pLayout,
212 sw::BroadcastingModify const&,
213 SwFrameType const nFrameType,
214 const SwPosition *pPos = nullptr,
215 std::pair<Point, bool> const* pViewPosAndCalcFrame = nullptr);
217 // Should extra data (redline stroke, line numbers) be painted?
218 bool IsExtraData( const SwDoc *pDoc );
220 // #i11760# - method declaration <CalcContent(..)>
221 void CalcContent( SwLayoutFrame *pLay, bool bNoColl = false );
223 // Notify classes memorize the current sizes in their constructor and do
224 // the necessary notifications in their destructor if needed
225 class SwFrameNotify
227 private:
228 void ImplDestroy();
230 protected:
231 SwFrame *mpFrame;
232 const SwRect maFrame;
233 const SwRect maPrt;
234 SwTwips mnFlyAnchorOfst;
235 SwTwips mnFlyAnchorOfstNoWrap;
236 bool mbHadFollow;
237 bool mbInvaKeep;
238 bool mbValidSize;
240 public:
241 SwFrameNotify( SwFrame *pFrame );
242 ~SwFrameNotify();
244 const SwRect &getFrameArea() const { return maFrame; }
245 void SetInvaKeep() { mbInvaKeep = true; }
248 class SwLayNotify : public SwFrameNotify
250 bool m_bLowersComplete;
252 void ImplDestroy();
254 public:
255 SwLayNotify( SwLayoutFrame *pLayFrame );
256 ~SwLayNotify();
258 void SetLowersComplete( bool b ) { m_bLowersComplete = b; }
259 bool IsLowersComplete() const { return m_bLowersComplete; }
262 class SwFlyNotify : public SwLayNotify
264 SwPageFrame *m_pOldPage;
265 const SwRect m_aFrameAndSpace;
267 void ImplDestroy();
269 public:
270 SwFlyNotify( SwFlyFrame *pFlyFrame );
271 ~SwFlyNotify();
274 class SwContentNotify : public SwFrameNotify
276 private:
277 // #i11859#
278 bool mbChkHeightOfLastLine;
279 SwTwips mnHeightOfLastLine;
281 // #i25029#
282 bool mbInvalidatePrevPrtArea;
283 bool mbBordersJoinedWithPrev;
285 void ImplDestroy();
287 public:
288 SwContentNotify( SwContentFrame *pContentFrame );
289 ~SwContentNotify();
291 // #i25029#
292 void SetInvalidatePrevPrtArea()
294 mbInvalidatePrevPrtArea = true;
297 void SetBordersJoinedWithPrev()
299 mbBordersJoinedWithPrev = true;
303 // SwBorderAttrs encapsulates the calculation for margin attributes including
304 // border. The whole class is cached.
306 // WARNING! If more attributes should be cached also adjust the method
307 // Modify::Modify!
308 class SwBorderAttrs final : public SwCacheObj
310 const SwAttrSet &m_rAttrSet;
311 const SvxULSpaceItem &m_rUL;
312 std::unique_ptr<SvxFirstLineIndentItem> m_pFirstLineIndent;
313 std::unique_ptr<SvxTextLeftMarginItem> m_pTextLeftMargin;
314 std::unique_ptr<SvxRightMarginItem> m_pRightMargin;
315 std::shared_ptr<SvxLRSpaceItem> m_xLR;
316 const SvxBoxItem &m_rBox;
317 const SvxShadowItem &m_rShadow;
318 const Size m_aFrameSize;
320 // the following bool values set the cached values to INVALID - until they
321 // are calculated for the first time
322 bool m_bTopLine : 1;
323 bool m_bBottomLine : 1;
324 bool m_bLeftLine : 1;
325 bool m_bRightLine : 1;
326 bool m_bTop : 1;
327 bool m_bBottom : 1;
328 bool m_bLine : 1;
329 bool m_bLineSpacing : 1;
331 bool m_bIsLine : 1; // border on at least one side?
333 bool m_bCacheGetLine : 1; // cache GetTopLine(), GetBottomLine()?
334 bool m_bCachedGetTopLine : 1; // is GetTopLine() cached?
335 bool m_bCachedGetBottomLine : 1; // is GetBottomLine() cached?
336 // Booleans indicate that <m_bJoinedWithPrev> and <m_bJoinedWithNext> are
337 // cached and valid.
338 // Caching depends on value of <m_bCacheGetLine>.
339 mutable bool m_bCachedJoinedWithPrev : 1;
340 mutable bool m_bCachedJoinedWithNext : 1;
341 // Booleans indicate that borders are joined with previous/next frame.
342 bool m_bJoinedWithPrev :1;
343 bool m_bJoinedWithNext :1;
345 // The cached values (un-defined until calculated for the first time)
346 sal_uInt16 m_nTopLine,
347 m_nBottomLine,
348 m_nLeftLine,
349 m_nRightLine,
350 m_nTop,
351 m_nBottom,
352 m_nGetTopLine,
353 m_nGetBottomLine,
354 m_nLineSpacing;
356 // only calculate lines and shadow
357 void CalcTopLine_();
358 void CalcBottomLine_();
359 void CalcLeftLine_();
360 void CalcRightLine_();
362 // lines + shadow + margin
363 void CalcTop_();
364 void CalcBottom_();
366 void IsLine_();
368 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
369 // borders/shadow have to be joined with previous frame.
370 void GetTopLine_ ( const SwFrame& _rFrame,
371 const SwFrame* _pPrevFrame );
372 void GetBottomLine_( const SwFrame& _rFrame );
374 // calculate cached values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
375 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
376 // borders/shadow have to be joined with previous frame.
377 void CalcJoinedWithPrev( const SwFrame& _rFrame,
378 const SwFrame* _pPrevFrame );
379 void CalcJoinedWithNext( const SwFrame& _rFrame );
381 // internal helper method for CalcJoinedWithPrev and CalcJoinedWithNext
382 bool JoinWithCmp( const SwFrame& _rCallerFrame,
383 const SwFrame& _rCmpFrame ) const;
385 // Are the left and right line and the LRSpace equal?
386 bool CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
387 const SwFrame *pCaller,
388 const SwFrame *pCmp ) const;
390 // tdf#125300 line spacing before cell border
391 void CalcLineSpacing_();
393 public:
394 SwBorderAttrs( const sw::BorderCacheOwner* pOwner, const SwFrame *pConstructor );
395 virtual ~SwBorderAttrs() override;
397 const SwAttrSet &GetAttrSet() const { return m_rAttrSet; }
398 const SvxULSpaceItem &GetULSpace() const { return m_rUL; }
399 const SvxBoxItem &GetBox() const { return m_rBox; }
400 const SvxShadowItem &GetShadow() const { return m_rShadow; }
402 inline sal_uInt16 CalcTopLine() const;
403 inline sal_uInt16 CalcBottomLine() const;
404 inline sal_uInt16 CalcLeftLine() const;
405 inline sal_uInt16 CalcRightLine() const;
406 inline sal_uInt16 CalcTop() const;
407 inline sal_uInt16 CalcBottom() const;
408 inline sal_uInt16 CalcLineSpacing() const;
409 tools::Long CalcLeft( const SwFrame *pCaller ) const;
410 tools::Long CalcRight( const SwFrame *pCaller ) const;
412 inline bool IsLine() const;
414 const Size &GetSize() const { return m_aFrameSize; }
416 // Should upper (or lower) border be evaluated for this frame?
417 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
418 // borders/shadow have to be joined with previous frame.
419 inline sal_uInt16 GetTopLine ( const SwFrame& _rFrame,
420 const SwFrame* _pPrevFrame = nullptr ) const;
421 inline sal_uInt16 GetBottomLine( const SwFrame& _rFrame ) const;
422 inline void SetGetCacheLine( bool bNew ) const;
424 // Accessors for cached values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
425 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
426 // borders/shadow have to be joined with previous frame.
427 bool JoinedWithPrev( const SwFrame& _rFrame,
428 const SwFrame* _pPrevFrame = nullptr ) const;
429 bool JoinedWithNext( const SwFrame& _rFrame ) const;
432 class SwBorderAttrAccess final : public SwCacheAccess
434 const SwFrame *m_pConstructor; //opt: for passing on to SwBorderAttrs
436 virtual SwCacheObj *NewObj() override;
438 public:
439 SwBorderAttrAccess( SwCache &rCache, const SwFrame *pOwner );
441 SwBorderAttrs *Get();
444 // Iterator for draw objects of a page. The objects will be iterated sorted by
445 // their Z-order. Iterating is not cheap since for each operation the _whole_
446 // SortArray needs to be traversed.
447 class SwOrderIter
449 const SwPageFrame *m_pPage;
450 const SdrObject *m_pCurrent;
452 public:
453 SwOrderIter( const SwPageFrame *pPage );
455 void Current( const SdrObject *pNew ) { m_pCurrent = pNew; }
456 const SdrObject *operator()() const { return m_pCurrent; }
457 void Top();
458 const SdrObject *Bottom();
459 const SdrObject *Next();
460 void Prev();
463 class StackHack
465 static sal_uInt8 s_nCnt;
466 static bool s_bLocked;
468 public:
469 StackHack()
471 if ( ++StackHack::s_nCnt > 50 )
472 StackHack::s_bLocked = true;
474 ~StackHack()
476 if ( --StackHack::s_nCnt < 5 )
477 StackHack::s_bLocked = false;
480 static bool IsLocked() { return StackHack::s_bLocked; }
481 static sal_uInt8 Count() { return StackHack::s_nCnt; }
484 // Should upper (or lower) border be evaluated for this frame?
485 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
486 // borders/shadow have to be joined with previous frame.
487 inline sal_uInt16 SwBorderAttrs::GetTopLine ( const SwFrame& _rFrame,
488 const SwFrame* _pPrevFrame ) const
490 if ( !m_bCachedGetTopLine || _pPrevFrame )
492 const_cast<SwBorderAttrs*>(this)->GetTopLine_( _rFrame, _pPrevFrame );
494 return m_nGetTopLine;
496 inline sal_uInt16 SwBorderAttrs::GetBottomLine( const SwFrame& _rFrame ) const
498 if ( !m_bCachedGetBottomLine )
499 const_cast<SwBorderAttrs*>(this)->GetBottomLine_( _rFrame );
500 return m_nGetBottomLine;
502 inline void SwBorderAttrs::SetGetCacheLine( bool bNew ) const
504 const_cast<SwBorderAttrs*>(this)->m_bCacheGetLine = bNew;
505 const_cast<SwBorderAttrs*>(this)->m_bCachedGetBottomLine =
506 const_cast<SwBorderAttrs*>(this)->m_bCachedGetTopLine = false;
507 // invalidate cache for values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
508 m_bCachedJoinedWithPrev = false;
509 m_bCachedJoinedWithNext = false;
512 inline sal_uInt16 SwBorderAttrs::CalcTopLine() const
514 if ( m_bTopLine )
515 const_cast<SwBorderAttrs*>(this)->CalcTopLine_();
516 return m_nTopLine;
518 inline sal_uInt16 SwBorderAttrs::CalcBottomLine() const
520 if ( m_bBottomLine )
521 const_cast<SwBorderAttrs*>(this)->CalcBottomLine_();
522 return m_nBottomLine;
524 inline sal_uInt16 SwBorderAttrs::CalcLeftLine() const
526 if ( m_bLeftLine )
527 const_cast<SwBorderAttrs*>(this)->CalcLeftLine_();
528 return m_nLeftLine;
530 inline sal_uInt16 SwBorderAttrs::CalcRightLine() const
532 if ( m_bRightLine )
533 const_cast<SwBorderAttrs*>(this)->CalcRightLine_();
534 return m_nRightLine;
536 inline sal_uInt16 SwBorderAttrs::CalcTop() const
538 if ( m_bTop )
539 const_cast<SwBorderAttrs*>(this)->CalcTop_();
540 return m_nTop;
542 inline sal_uInt16 SwBorderAttrs::CalcBottom() const
544 if ( m_bBottom )
545 const_cast<SwBorderAttrs*>(this)->CalcBottom_();
546 return m_nBottom;
548 inline sal_uInt16 SwBorderAttrs::CalcLineSpacing() const
550 if ( m_bLineSpacing )
551 const_cast<SwBorderAttrs*>(this)->CalcLineSpacing_();
552 return m_nLineSpacing;
554 inline bool SwBorderAttrs::IsLine() const
556 if ( m_bLine )
557 const_cast<SwBorderAttrs*>(this)->IsLine_();
558 return m_bIsLine;
561 /** method to determine the spacing values of a frame
563 #i28701#
564 Values only provided for flow frames (table, section or text frames)
565 Note: line spacing value is only determined for text frames
566 #i102458#
567 Add output parameter <obIsLineSpacingProportional>
569 @param rFrame
570 input parameter - frame, for which the spacing values are determined.
572 @param onPrevLowerSpacing
573 output parameter - lower spacing of the frame in SwTwips
575 @param onPrevLineSpacing
576 output parameter - line spacing of the frame in SwTwips
578 @param obIsLineSpacingProportional
580 @param bIdenticalStyles true if the styles of the actual and the next paragraphs (text-frames) are the same
582 void GetSpacingValuesOfFrame( const SwFrame& rFrame,
583 SwTwips& onLowerSpacing,
584 SwTwips& onLineSpacing,
585 bool& obIsLineSpacingProportional,
586 bool bIdenticalStyles );
588 /** method to get the content of the table cell
590 Content from any nested tables will be omitted.
591 Note: line spacing value is only determined for text frames
593 @param rCell_
594 input parameter - the cell which should be searched for content.
596 return
597 pointer to the found content frame or 0
600 const SwContentFrame* GetCellContent( const SwLayoutFrame& rCell_ );
602 /** helper class to check if a frame has been deleted during an operation
603 * WARNING! This should only be used as a last and desperate means to make the
604 * code robust.
607 class SwDeletionChecker
609 private:
610 const SwFrame* mpFrame;
611 const sw::BroadcastingModify* mpRegIn;
613 public:
614 SwDeletionChecker(const SwFrame* pFrame);
617 * return
618 * true if mpFrame != 0 and mpFrame is not client of pRegIn
619 * false otherwise
621 bool HasBeenDeleted() const;
624 #endif
626 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */