1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
26 #include "swcache.hxx"
27 #include <swatrset.hxx>
49 namespace sw
{ struct Extent
; }
50 namespace basegfx::utils
{ class B2DClipState
; }
52 #define FAR_AWAY (SAL_MAX_INT32 - 20000) // initial position of a Fly
53 constexpr tools::Long BROWSE_HEIGHT
= 56700 * 10; // 10 Meters
56 #define GRFNUM_REPLACE 2
58 void AppendObjs( const SwFrameFormats
*pTable
, sal_uLong nIndex
,
59 SwFrame
*pFrame
, SwPageFrame
*pPage
, SwDoc
* doc
);
61 void AppendObjsOfNode(SwFrameFormats
const* pTable
, sal_uLong 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 SwFrameFormats
* pTable
, 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.
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
, sal_uLong nIndex
,
143 bool bPages
= false, sal_uLong nEndIndex
= 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
, const SwNodeIndex
&rSttIdx
,
148 const SwNodeIndex
&rEndIdx
);
150 extern bool bObjsDirect
;
152 // prevent creation of Flys in InsertCnt_, e.g. for table headlines
153 extern bool bDontCreateObjects
;
155 // for FlyCnts, see SwFlyAtContentFrame::MakeAll()
156 extern bool bSetCompletePaintOnInvalidate
;
158 // for table settings via keyboard
159 SwTwips
CalcRowRstHeight( SwLayoutFrame
*pRow
);
160 tools::Long
CalcHeightWithFlys( const SwFrame
*pFrame
);
164 bool IsRightPageByNumber(SwRootFrame
const& rLayout
, sal_uInt16 nPageNum
);
168 SwPageFrame
*InsertNewPage( SwPageDesc
&rDesc
, SwFrame
*pUpper
,
169 bool isRightPage
, bool bFirst
, bool bInsertEmpty
, bool bFootnote
,
170 SwFrame
*pSibling
, bool bVeryFirstPage
= false );
172 // connect Flys with page
173 void RegistFlys( SwPageFrame
*, const SwLayoutFrame
* );
175 // notification of Fly's background if needed
176 void Notify( SwFlyFrame
*pFly
, SwPageFrame
*pOld
, const SwRect
&rOld
,
177 const SwRect
* pOldRect
= nullptr );
179 void Notify_Background( const SdrObject
* pObj
,
182 const PrepareHint eHint
,
185 const SwFrame
* GetVirtualUpper( const SwFrame
* pFrame
, const Point
& rPos
);
187 bool Is_Lower_Of( const SwFrame
*pCurrFrame
, const SdrObject
* pObj
);
189 // FIXME: EasyHack (refactoring): rename method and parameter name in all files
190 const SwFrame
*FindContext( const SwFrame
*pFrame
, SwFrameType nAdditionalContextTyp
);
192 bool IsFrameInSameContext( const SwFrame
*pInnerFrame
, const SwFrame
*pFrame
);
194 const SwFrame
* FindPage( const SwRect
&rRect
, const SwFrame
*pPage
);
196 /** @see SwContentNode::getLayoutFrame()
198 Document model position; for a text frame, the returned frame will be
199 one containing this position.
200 @param pViewPosAndCalcFrame
201 First is a point in the document view; the returned frame will be the one
202 with the minimal distance to this point. To get the first frame in the
203 document, pass in a default-initialized Point with coordinates 0,0.
204 Second indicates whether the frames should be formatted before retrieving
205 their position for the test; this cannot be done by every caller so use
208 SwFrame
* GetFrameOfModify( const SwRootFrame
* pLayout
,
209 sw::BroadcastingModify
const&,
210 SwFrameType
const nFrameType
,
211 const SwPosition
*pPos
= nullptr,
212 std::pair
<Point
, bool> const* pViewPosAndCalcFrame
= nullptr);
214 // Should extra data (redline stroke, line numbers) be painted?
215 bool IsExtraData( const SwDoc
*pDoc
);
217 // #i11760# - method declaration <CalcContent(..)>
218 void CalcContent( SwLayoutFrame
*pLay
, bool bNoColl
= false );
220 // Notify classes memorize the current sizes in their constructor and do
221 // the necessary notifications in their destructor if needed
226 const SwRect maFrame
;
228 SwTwips mnFlyAnchorOfst
;
229 SwTwips mnFlyAnchorOfstNoWrap
;
235 SwFrameNotify( SwFrame
*pFrame
);
236 ~SwFrameNotify() COVERITY_NOEXCEPT_FALSE
;
238 const SwRect
&getFrameArea() const { return maFrame
; }
239 void SetInvaKeep() { mbInvaKeep
= true; }
242 class SwLayNotify
: public SwFrameNotify
244 bool m_bLowersComplete
;
247 SwLayNotify( SwLayoutFrame
*pLayFrame
);
250 void SetLowersComplete( bool b
) { m_bLowersComplete
= b
; }
251 bool IsLowersComplete() const { return m_bLowersComplete
; }
254 class SwFlyNotify
: public SwLayNotify
256 SwPageFrame
*pOldPage
;
257 const SwRect aFrameAndSpace
;
260 SwFlyNotify( SwFlyFrame
*pFlyFrame
);
264 class SwContentNotify
: public SwFrameNotify
268 bool mbChkHeightOfLastLine
;
269 SwTwips mnHeightOfLastLine
;
272 bool mbInvalidatePrevPrtArea
;
273 bool mbBordersJoinedWithPrev
;
276 SwContentNotify( SwContentFrame
*pContentFrame
);
280 void SetInvalidatePrevPrtArea()
282 mbInvalidatePrevPrtArea
= true;
285 void SetBordersJoinedWithPrev()
287 mbBordersJoinedWithPrev
= true;
291 // SwBorderAttrs encapsulates the calculation for margin attributes including
292 // border. The whole class is cached.
294 // WARNING! If more attributes should be cached also adjust the method
296 class SwBorderAttrs
: public SwCacheObj
298 const SwAttrSet
&m_rAttrSet
;
299 const SvxULSpaceItem
&m_rUL
;
301 std::shared_ptr
<SvxLRSpaceItem
> m_rLR
;
302 const SvxBoxItem
&m_rBox
;
303 const SvxShadowItem
&m_rShadow
;
304 const Size m_aFrameSize
;
306 // the following bool values set the cached values to INVALID - until they
307 // are calculated for the first time
309 bool m_bBottomLine
: 1;
310 bool m_bLeftLine
: 1;
311 bool m_bRightLine
: 1;
315 bool m_bLineSpacing
: 1;
317 bool m_bIsLine
: 1; // border on at least one side?
319 bool m_bCacheGetLine
: 1; // cache GetTopLine(), GetBottomLine()?
320 bool m_bCachedGetTopLine
: 1; // is GetTopLine() cached?
321 bool m_bCachedGetBottomLine
: 1; // is GetBottomLine() cached?
322 // Booleans indicate that <m_bJoinedWithPrev> and <m_bJoinedWithNext> are
324 // Caching depends on value of <m_bCacheGetLine>.
325 mutable bool m_bCachedJoinedWithPrev
: 1;
326 mutable bool m_bCachedJoinedWithNext
: 1;
327 // Booleans indicate that borders are joined with previous/next frame.
328 bool m_bJoinedWithPrev
:1;
329 bool m_bJoinedWithNext
:1;
331 // The cached values (un-defined until calculated for the first time)
332 sal_uInt16 m_nTopLine
,
342 // only calculate lines and shadow
344 void CalcBottomLine_();
345 void CalcLeftLine_();
346 void CalcRightLine_();
348 // lines + shadow + margin
354 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
355 // borders/shadow have to be joined with previous frame.
356 void GetTopLine_ ( const SwFrame
& _rFrame
,
357 const SwFrame
* _pPrevFrame
);
358 void GetBottomLine_( const SwFrame
& _rFrame
);
360 // calculate cached values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
361 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
362 // borders/shadow have to be joined with previous frame.
363 void CalcJoinedWithPrev( const SwFrame
& _rFrame
,
364 const SwFrame
* _pPrevFrame
);
365 void CalcJoinedWithNext( const SwFrame
& _rFrame
);
367 // internal helper method for CalcJoinedWithPrev and CalcJoinedWithNext
368 bool JoinWithCmp( const SwFrame
& _rCallerFrame
,
369 const SwFrame
& _rCmpFrame
) const;
371 // Are the left and right line and the LRSpace equal?
372 bool CmpLeftRight( const SwBorderAttrs
&rCmpAttrs
,
373 const SwFrame
*pCaller
,
374 const SwFrame
*pCmp
) const;
376 // tdf#125300 line spacing before cell border
377 void CalcLineSpacing_();
380 SwBorderAttrs( const sw::BroadcastingModify
*pOwner
, const SwFrame
*pConstructor
);
381 virtual ~SwBorderAttrs() override
;
383 const SwAttrSet
&GetAttrSet() const { return m_rAttrSet
; }
384 const SvxULSpaceItem
&GetULSpace() const { return m_rUL
; }
385 const SvxBoxItem
&GetBox() const { return m_rBox
; }
386 const SvxShadowItem
&GetShadow() const { return m_rShadow
; }
388 inline sal_uInt16
CalcTopLine() const;
389 inline sal_uInt16
CalcBottomLine() const;
390 inline sal_uInt16
CalcLeftLine() const;
391 inline sal_uInt16
CalcRightLine() const;
392 inline sal_uInt16
CalcTop() const;
393 inline sal_uInt16
CalcBottom() const;
394 inline sal_uInt16
CalcLineSpacing() const;
395 tools::Long
CalcLeft( const SwFrame
*pCaller
) const;
396 tools::Long
CalcRight( const SwFrame
*pCaller
) const;
398 inline bool IsLine() const;
400 const Size
&GetSize() const { return m_aFrameSize
; }
402 // Should upper (or lower) border be evaluated for this frame?
403 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
404 // borders/shadow have to be joined with previous frame.
405 inline sal_uInt16
GetTopLine ( const SwFrame
& _rFrame
,
406 const SwFrame
* _pPrevFrame
= nullptr ) const;
407 inline sal_uInt16
GetBottomLine( const SwFrame
& _rFrame
) const;
408 inline void SetGetCacheLine( bool bNew
) const;
410 // Accessors for cached values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
411 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
412 // borders/shadow have to be joined with previous frame.
413 bool JoinedWithPrev( const SwFrame
& _rFrame
,
414 const SwFrame
* _pPrevFrame
= nullptr ) const;
415 bool JoinedWithNext( const SwFrame
& _rFrame
) const;
418 class SwBorderAttrAccess
: public SwCacheAccess
420 const SwFrame
*m_pConstructor
; //opt: for passing on to SwBorderAttrs
423 virtual SwCacheObj
*NewObj() override
;
426 SwBorderAttrAccess( SwCache
&rCache
, const SwFrame
*pOwner
);
428 SwBorderAttrs
*Get();
431 // Iterator for draw objects of a page. The objects will be iterated sorted by
432 // their Z-order. Iterating is not cheap since for each operation the _whole_
433 // SortArray needs to be traversed.
436 const SwPageFrame
*m_pPage
;
437 const SdrObject
*m_pCurrent
;
440 SwOrderIter( const SwPageFrame
*pPage
);
442 void Current( const SdrObject
*pNew
) { m_pCurrent
= pNew
; }
443 const SdrObject
*operator()() const { return m_pCurrent
; }
445 const SdrObject
*Bottom();
446 const SdrObject
*Next();
452 static sal_uInt8 s_nCnt
;
453 static bool s_bLocked
;
458 if ( ++StackHack::s_nCnt
> 50 )
459 StackHack::s_bLocked
= true;
463 if ( --StackHack::s_nCnt
< 5 )
464 StackHack::s_bLocked
= false;
467 static bool IsLocked() { return StackHack::s_bLocked
; }
468 static sal_uInt8
Count() { return StackHack::s_nCnt
; }
471 // Should upper (or lower) border be evaluated for this frame?
472 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
473 // borders/shadow have to be joined with previous frame.
474 inline sal_uInt16
SwBorderAttrs::GetTopLine ( const SwFrame
& _rFrame
,
475 const SwFrame
* _pPrevFrame
) const
477 if ( !m_bCachedGetTopLine
|| _pPrevFrame
)
479 const_cast<SwBorderAttrs
*>(this)->GetTopLine_( _rFrame
, _pPrevFrame
);
481 return m_nGetTopLine
;
483 inline sal_uInt16
SwBorderAttrs::GetBottomLine( const SwFrame
& _rFrame
) const
485 if ( !m_bCachedGetBottomLine
)
486 const_cast<SwBorderAttrs
*>(this)->GetBottomLine_( _rFrame
);
487 return m_nGetBottomLine
;
489 inline void SwBorderAttrs::SetGetCacheLine( bool bNew
) const
491 const_cast<SwBorderAttrs
*>(this)->m_bCacheGetLine
= bNew
;
492 const_cast<SwBorderAttrs
*>(this)->m_bCachedGetBottomLine
=
493 const_cast<SwBorderAttrs
*>(this)->m_bCachedGetTopLine
= false;
494 // invalidate cache for values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
495 m_bCachedJoinedWithPrev
= false;
496 m_bCachedJoinedWithNext
= false;
499 inline sal_uInt16
SwBorderAttrs::CalcTopLine() const
502 const_cast<SwBorderAttrs
*>(this)->CalcTopLine_();
505 inline sal_uInt16
SwBorderAttrs::CalcBottomLine() const
508 const_cast<SwBorderAttrs
*>(this)->CalcBottomLine_();
509 return m_nBottomLine
;
511 inline sal_uInt16
SwBorderAttrs::CalcLeftLine() const
514 const_cast<SwBorderAttrs
*>(this)->CalcLeftLine_();
517 inline sal_uInt16
SwBorderAttrs::CalcRightLine() const
520 const_cast<SwBorderAttrs
*>(this)->CalcRightLine_();
523 inline sal_uInt16
SwBorderAttrs::CalcTop() const
526 const_cast<SwBorderAttrs
*>(this)->CalcTop_();
529 inline sal_uInt16
SwBorderAttrs::CalcBottom() const
532 const_cast<SwBorderAttrs
*>(this)->CalcBottom_();
535 inline sal_uInt16
SwBorderAttrs::CalcLineSpacing() const
537 if ( m_bLineSpacing
)
538 const_cast<SwBorderAttrs
*>(this)->CalcLineSpacing_();
539 return m_nLineSpacing
;
541 inline bool SwBorderAttrs::IsLine() const
544 const_cast<SwBorderAttrs
*>(this)->IsLine_();
548 /** method to determine the spacing values of a frame
551 Values only provided for flow frames (table, section or text frames)
552 Note: line spacing value is only determined for text frames
554 Add output parameter <obIsLineSpacingProportional>
557 input parameter - frame, for which the spacing values are determined.
559 @param onPrevLowerSpacing
560 output parameter - lower spacing of the frame in SwTwips
562 @param onPrevLineSpacing
563 output parameter - line spacing of the frame in SwTwips
565 @param obIsLineSpacingProportional
567 @param bIdenticalStyles true if the styles of the actual and the next paragraphs (text-frames) are the same
569 void GetSpacingValuesOfFrame( const SwFrame
& rFrame
,
570 SwTwips
& onLowerSpacing
,
571 SwTwips
& onLineSpacing
,
572 bool& obIsLineSpacingProportional
,
573 bool bIdenticalStyles
);
575 /** method to get the content of the table cell
577 Content from any nested tables will be omitted.
578 Note: line spacing value is only determined for text frames
581 input parameter - the cell which should be searched for content.
584 pointer to the found content frame or 0
587 const SwContentFrame
* GetCellContent( const SwLayoutFrame
& rCell_
);
589 /** helper class to check if a frame has been deleted during an operation
590 * WARNING! This should only be used as a last and desperate means to make the
594 class SwDeletionChecker
597 const SwFrame
* mpFrame
;
598 const sw::BroadcastingModify
* mpRegIn
;
601 SwDeletionChecker(const SwFrame
* pFrame
);
605 * true if mpFrame != 0 and mpFrame is not client of pRegIn
608 bool HasBeenDeleted() const;
613 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */