Revert "reduce symbol visibility in sw"
[LibreOffice.git] / sw / source / core / inc / txtfrm.hxx
blobe4b568996b663aaf1177ea3791c62919d099e6c6
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 .
19 #ifndef INCLUDED_SW_SOURCE_CORE_INC_TXTFRM_HXX
20 #define INCLUDED_SW_SOURCE_CORE_INC_TXTFRM_HXX
22 #include <com/sun/star/uno/Sequence.hxx>
23 #include "cntfrm.hxx"
24 #include "TextFrameIndex.hxx"
25 #include <nodeoffset.hxx>
27 #include <set>
28 #include <utility>
30 #include <view.hxx>
32 namespace com::sun::star::linguistic2 { class XHyphenatedWord; }
34 namespace sw::mark { class IMark; }
35 class SwCharRange;
36 class SwTextNode;
37 class SwTextAttrEnd;
38 class SwTextFormatter;
39 class SwTextFormatInfo;
40 class SwParaPortion;
41 class WidowsAndOrphans;
42 class SwTextFootnote;
43 class SwInterHyphInfo; // Hyphenate()
44 class SwCache;
45 class SwBorderAttrs;
46 class SwFrameFormat;
47 struct SwCursorMoveState;
48 struct SwFillData;
49 class SwPortionHandler;
50 class SwScriptInfo;
51 enum class ExpandMode;
52 class SwTextAttr;
53 class SwWrtShell;
54 class SwNode;
55 class SwFlyAtContentFrame;
57 #define NON_PRINTING_CHARACTER_COLOR Color(0x26, 0x8b, 0xd2)
59 /// a clone of SwInterHyphInfo, but with TextFrameIndex instead of node index
60 class SwInterHyphInfoTextFrame
62 private:
63 /// output: hyphenated word
64 css::uno::Reference<css::linguistic2::XHyphenatedWord> m_xHyphWord;
65 public:
66 /// input: requested range to hyphenate
67 TextFrameIndex m_nStart;
68 TextFrameIndex m_nEnd;
69 /// output: found word
70 TextFrameIndex m_nWordStart;
71 TextFrameIndex m_nWordLen;
73 SwInterHyphInfoTextFrame(SwTextFrame const& rFrame,
74 SwTextNode const& rNode, SwInterHyphInfo const& rHyphInfo);
75 void UpdateTextNodeHyphInfo(SwTextFrame const& rFrame,
76 SwTextNode const& rNode, SwInterHyphInfo & o_rHyphInfo);
78 void SetHyphWord(const css::uno::Reference<css::linguistic2::XHyphenatedWord> &xHW)
80 m_xHyphWord = xHW;
84 namespace sw {
86 /**
87 * Describes a part of a single text node, which will be part of a text frame,
88 * even when redlines are hidden at a layout level.
90 struct Extent
92 SwTextNode * /*const logically, but need assignment for std::vector*/ pNode;
93 sal_Int32 nStart;
94 sal_Int32 nEnd;
95 Extent(SwTextNode *const p, sal_Int32 const s, sal_Int32 const e)
96 : pNode(p), nStart(s), nEnd(e)
98 assert(pNode);
99 assert(nStart != nEnd);
103 struct MergedPara;
104 class InsertText;
106 std::pair<SwTextNode*, sal_Int32> MapViewToModel(MergedPara const&, TextFrameIndex nIndex);
107 TextFrameIndex MapModelToView(MergedPara const&, SwTextNode const* pNode, sal_Int32 nIndex);
109 // warning: Existing must be used only once; a second use would delete the frame created by the first one...
110 enum class FrameMode { New, Existing };
111 std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, FrameMode eMode);
112 SwTextFrame * MakeTextFrame(SwTextNode & rNode, SwFrame *, sw::FrameMode eMode);
114 bool FrameContainsNode(SwContentFrame const& rFrame, SwNodeOffset nNodeIndex);
115 bool IsParaPropsNode(SwRootFrame const& rLayout, SwTextNode const& rNode);
116 SwTextNode * GetParaPropsNode(SwRootFrame const& rLayout, SwNode const& rNode);
117 SwPosition GetParaPropsPos(SwRootFrame const& rLayout, SwPosition const& rPos);
118 std::pair<SwTextNode *, SwTextNode *>
119 GetFirstAndLastNode(SwRootFrame const& rLayout, SwNode const& rPos);
121 SwTextNode const& GetAttrMerged(SfxItemSet & rFormatSet,
122 SwTextNode const& rNode, SwRootFrame const* pLayout);
124 void GotoPrevLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const* pLayout);
125 void GotoNextLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const* pLayout);
127 TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
128 bool isRealDelete,
129 SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen);
131 void MoveMergedFlysAndFootnotes(std::vector<SwTextFrame*> const& rFrames,
132 SwTextNode const& rFirstNode, SwTextNode & rSecondNode, bool);
134 void MoveDeletedPrevFrames(const SwTextNode & rDeletedPrev, SwTextNode & rNode);
135 enum class Recreate { No, ThisNode, Predecessor };
136 void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate eRecreateMerged);
138 void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
139 void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
141 void AddRemoveFlysAnchoredToFrameStartingAtNode(
142 SwTextFrame & rFrame, SwTextNode & rTextNode,
143 std::set<SwNodeOffset> *pSkipped);
145 OUString GetExpandTextMerged(SwRootFrame const* pLayout,
146 SwTextNode const& rNode, bool bWithNumber,
147 bool bWithSpacesForLevel, ExpandMode i_mode);
149 bool IsMarkHidden(SwRootFrame const& rLayout, ::sw::mark::IMark const& rMark);
150 bool IsMarkHintHidden(SwRootFrame const& rLayout,
151 SwTextNode const& rNode, SwTextAttrEnd const& rHint);
153 void RecreateStartTextFrames(SwTextNode & rNode);
155 sw::InsertText MakeInsertText(SwTextNode& rNode, const sal_Int32 nPos, const sal_Int32 nLen);
158 * Decides if rTextNode has a numbering which has layout-level values (e.g. Arabic, but not
159 * none or bullets).
161 bool HasNumberingWhichNeedsLayoutUpdate(const SwTextNode& rTextNode);
163 } // namespace sw
165 /// Represents the visualization of a paragraph. Typical upper is an
166 /// SwBodyFrame. The first text portion of the first line is az SwParaPortion.
167 class SW_DLLPUBLIC SwTextFrame final : public SwContentFrame
169 friend class SwTextIter;
170 friend class SwTestFormat;
171 friend class WidowsAndOrphans;
172 friend class TextFrameLockGuard; // May Lock()/Unlock()
173 friend bool sw_ChangeOffset(SwTextFrame* pFrame, TextFrameIndex nNew);
175 /// SwLineLayout cache: the lines are not actually owned by the SwTextFrame
176 /// but by this SwCache, so they will be deleted in large documents
177 /// if there are too many of them, but the "valid" flags of the frame
178 /// will still be set; GetFormatted() is the function that forces
179 /// recreation of the SwLineLayout by Format() if necessary.
180 static SwCache *s_pTextCache;
181 static constexpr tools::Long nMinPrtLine = 0; // This Line must not be underrun when printing
182 // Hack for table cells stretching multiple pages
184 sal_Int32 mnAllLines :24; // Line count for the Paint (including nThisLines)
185 sal_Int32 mnThisLines :8; // Count of Lines of the Frame
187 // The x position for flys anchored at this paragraph.
188 // These values are calculated in SwTextFrame::CalcBaseOfstForFly()
189 SwTwips mnFlyAnchorOfst;
190 // The x position for wrap-through flys anchored at this paragraph.
191 SwTwips mnFlyAnchorOfstNoWrap;
192 /// The y position for wrap-through flys anchored at this paragraph.
193 SwTwips mnFlyAnchorVertOfstNoWrap;
194 SwTwips mnFootnoteLine;
195 // OD 2004-03-17 #i11860# - re-factoring of #i11859#
196 // member for height of last line (value needed for proportional line spacing)
197 SwTwips mnHeightOfLastLine;
198 // member for the additional first line offset, which is caused by the list
199 // label alignment for list level position and space mode LABEL_ALIGNMENT.
200 // This additional first line offset is used for the text formatting.
201 // It is NOT used for the determination of printing area.
202 SwTwips mnAdditionalFirstLineOffset;
204 /// redline merge data
205 std::unique_ptr<sw::MergedPara> m_pMergedPara;
207 TextFrameIndex mnOffset; // Is the offset in the Content (character count)
209 sal_uInt16 mnCacheIndex; // Index into the cache, USHRT_MAX if there's definitely no fitting object in the cache
211 // Separates the Master and creates a Follow or adjusts the data in the Follow
212 void AdjustFollow_( SwTextFormatter &rLine, TextFrameIndex nOffset,
213 TextFrameIndex nStrEnd, const sal_uInt8 nMode );
215 // Iterates all Lines and sets the line spacing using the attribute
216 void CalcLineSpace();
218 // Only called in Format
219 void AdjustFrame( const SwTwips nChgHeight, bool bHasToFit = false );
221 // Evaluates the Preps in Format()
222 bool CalcPreps();
223 void PrepWidows( const sal_uInt16 nNeed, bool bNotify );
224 void InvalidateRange_( const SwCharRange &, const tools::Long = 0);
225 inline void InvalidateRange( const SwCharRange &, const tools::Long = 0);
227 // WidowsAndOrphans, AdjustFrame, AdjustFollow
228 void FormatAdjust( SwTextFormatter &rLine, WidowsAndOrphans &rFrameBreak,
229 TextFrameIndex nStrLen, const bool bDummy );
230 void ChangeOffset( SwTextFrame* pFrame, TextFrameIndex nNew );
232 bool mbLocked : 1; // In the Format?
233 bool mbWidow : 1; // Is our follow a Widow?
234 bool mbJustWidow : 1; // Did we just request Widow flag on master?
235 bool mbEmpty : 1; // Are we an empty paragraph?
236 bool mbInFootnoteConnect : 1; // Is in Connect at the moment
237 bool mbFootnote : 1; // Has at least one footnote
238 bool mbRepaint : 1; // TextFrame: Repaint is ready to be fetched
239 /// Contains rotated portions.
240 bool mbHasRotatedPortions : 1;
241 bool mbFieldFollow : 1; // Start with Field rest of the Master
242 bool mbHasAnimation : 1; // Contains animated SwGrfNumPortion
243 bool mbIsSwapped : 1; // during text formatting we swap the
244 // width and height for vertical formatting
245 // OD 14.03.2003 #i11760# - flag to control, if follow is formatted in
246 // method <CalcFollow(..)>.
247 // E.g., avoid formatting of follow, if method <SwLayoutFrame::FormatWidthCols(..)>
248 // is running.
249 bool mbFollowFormatAllowed : 1;
251 void ResetPreps();
252 void Lock() { mbLocked = true; }
253 void Unlock() { mbLocked = false; }
254 void SetWidow( const bool bNew ) { mbWidow = bNew; }
255 void SetJustWidow( const bool bNew ) { mbJustWidow = bNew; }
256 void SetEmpty( const bool bNew ) { mbEmpty = bNew; }
257 void SetFieldFollow( const bool bNew ) { mbFieldFollow = bNew; }
259 bool IsIdxInside(TextFrameIndex nPos, TextFrameIndex nLen) const;
261 // Changes the Frame or not (cf. FlyCnt)
262 bool GetModelPositionForViewPoint_(SwPosition *pPos, const Point &rPoint,
263 const bool bChgFrame, SwCursorMoveState* = nullptr ) const;
264 void FillCursorPos( SwFillData &rFill ) const;
266 // Format exactly one Line
267 bool FormatLine( SwTextFormatter &rLine, const bool bPrev );
269 // In order to safe stack space, we split this method:
270 // Format_ calls Format_ with parameters
271 void FormatImpl( vcl::RenderContext* pRenderContext, SwParaPortion *pPara,
272 ::std::vector<SwAnchoredObject *> & rIntersectingObjs);
273 void Format_( SwTextFormatter &rLine, SwTextFormatInfo &rInf,
274 const bool bAdjust = false );
275 void FormatOnceMore( SwTextFormatter &rLine, SwTextFormatInfo &rInf );
277 // Formats the Follow and ensures disposing on orphans
278 bool CalcFollow(TextFrameIndex nTextOfst);
280 virtual void MakePos() override;
282 // Corrects the position from which we need to format
283 static TextFrameIndex FindBrk(std::u16string_view aText, TextFrameIndex nStart,
284 TextFrameIndex nEnd);
286 // inline branch
287 SwTwips GetFootnoteFrameHeight_() const;
289 // Outsourced to CalcPreps
290 bool CalcPrepFootnoteAdjust();
292 // For Footnote and WidOrp: Forced validation
293 void ValidateFrame();
294 void ValidateBodyFrame();
296 bool GetDropRect_( SwRect &rRect ) const;
298 void SetPara( SwParaPortion *pNew, bool bDelete = true );
300 bool IsFootnoteNumFrame_() const;
302 // Refresh formatting information
303 bool FormatQuick( bool bForceQuickFormat );
305 // Opt: Format empty paragraphs
306 bool FormatEmpty();
307 SwTwips EmptyHeight() const;
309 // Opt: Paint empty paragraphs
310 bool PaintEmpty( const SwRect &, bool bCheck ) const;
312 void ChgThisLines(); // Must always be called if the Line count could have changed
314 // required for 'new' relative anchor position
315 void CalcBaseOfstForFly();
317 /** method to determine height of last line, needed for proportional line spacing
319 OD 2004-03-17 #i11860#
320 OD 2005-05-20 #i47162# - introduce new optional parameter <_bUseFont>
321 in order to force the usage of the former algorithm to determine the
322 height of the last line, which uses the font.
324 @param _bUseFont
325 optional input parameter - boolean indicating, if the font has to be
326 used to determine the height of the last line. default value: false
328 void CalcHeightOfLastLine( const bool _bUseFont = false );
330 virtual void DestroyImpl() override;
331 virtual ~SwTextFrame() override;
333 void UpdateOutlineContentVisibilityButton(SwWrtShell* pWrtSh) const;
334 void PaintOutlineContentVisibilityButton() const;
336 void PaintParagraphStylesHighlighting() const;
338 virtual void SwClientNotify(SwModify const& rModify, SfxHint const& rHint) override;
340 /// Like GetDrawObjs(), but limit to fly frames which are allowed to split.
341 std::vector<SwFlyAtContentFrame*> GetSplitFlyDrawObjs() const;
343 public:
345 virtual const SvxFormatBreakItem& GetBreakItem() const override;
346 virtual const SwFormatPageDesc& GetPageDescItem() const override;
348 css::uno::Sequence< css::style::TabStop > GetTabStopInfo( SwTwips CurrentPos ) override;
351 * This is public, as it needs to be called by some methods in order to save the Prepare
352 * USE WITH CAUTION!
354 void Init();
356 /// Is called by DoIdleJob_(), ExecSpellPopup() and UpDown()
357 SwRect AutoSpell_(SwTextNode &, sal_Int32);
359 /// Is called by DoIdleJob_()
360 SwRect SmartTagScan(SwTextNode &);
362 /// Is called by DoIdleJob_()
363 void CollectAutoCmplWrds(SwTextNode &, sal_Int32);
366 * Returns the view rectangle for the rPos model position. The values are relative to the upper
367 * left position of the page frame.
368 * Additional information can be obtained by passing an SwCursorMoveState object.
369 * Returns false if rPos > number of character is string
371 virtual bool GetCharRect( SwRect& rRect, const SwPosition& rPos,
372 SwCursorMoveState* pCMS = nullptr, bool bAllowFarAway = true ) const override;
374 /// A slimmer version of GetCharRect for autopositioning Frames
375 bool GetAutoPos( SwRect &, const SwPosition& ) const;
378 * Determine top of line for given position in the text frame
380 * OD 11.11.2003 #i22341#
381 * Assumption: given position exists in the text frame or in a follow of it
382 * OD 2004-02-02 - adjustment
383 * Top of first paragraph line is the top of the paragraph.
384 * OD 2004-03-18 #i11860# - Consider upper space amount considered for
385 * previous frame and the page grid.
387 * @param _onTopOfLine
388 * output parameter - top of line, if the given position is found in the
389 * text frame.
391 * @param _rPos
392 * input parameter - reference to the position in the text frame
394 * @return boolean indicating, if the top of line for the given position
395 * has been determined or not.
397 bool GetTopOfLine( SwTwips& _onTopOfLine,
398 const SwPosition& _rPos ) const;
400 virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const override;
403 * In nOffset returns the offset of the char within the set
404 * text buffer, which is closest to the position provided by
405 * aPoint within the layout's SSize.
407 * @returns false if the SPoint is outside of the SSize else
408 * returns true
410 virtual bool GetModelPositionForViewPoint( SwPosition *, Point&,
411 SwCursorMoveState* = nullptr, bool bTestBackground = false ) const override;
414 * Makes sure that the Frame is not switched (e.g. switched for a
415 * character-bound Frame)
417 bool GetKeyCursorOfst(SwPosition *pPos, const Point &rPoint ) const
418 { return GetModelPositionForViewPoint_( pPos, rPoint, false ); }
420 void PaintExtraData( const SwRect & rRect ) const; /// Page number etc.
421 SwRect GetPaintSwRect();
422 virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const& ) const override;
425 * Layout oriented cursor travelling:
426 * Left border, right border, previous Line, following Line,
427 * same horizontal position
429 virtual bool LeftMargin(SwPaM *) const override;
430 virtual bool RightMargin(SwPaM *, bool bAPI = false) const override;
432 virtual bool UnitUp(SwPaM *, const SwTwips nOffset,
433 bool bSetInReadOnly ) const override;
434 virtual bool UnitDown(SwPaM *, const SwTwips nOffset,
435 bool bSetInReadOnly ) const override;
436 bool UnitUp_(SwPaM *, const SwTwips nOffset,
437 bool bSetInReadOnly ) const;
438 bool UnitDown_(SwPaM *, const SwTwips nOffset,
439 bool bSetInReadOnly ) const;
442 * Prepares the cursor position for a visual cursor move (BiDi).
443 * The behaviour is different for insert and overwrite cursors
445 void PrepareVisualMove( TextFrameIndex& nPos, sal_uInt8& nCursorLevel,
446 bool& bRight, bool bInsertCursor );
448 /// Methods to manage the FollowFrame
449 void SplitFrame(TextFrameIndex nTextPos);
450 SwContentFrame *JoinFrame();
451 TextFrameIndex GetOffset() const { return mnOffset; }
452 void SetOffset_(TextFrameIndex nNewOfst);
453 inline void SetOffset (TextFrameIndex nNewOfst);
454 void ManipOfst(TextFrameIndex const nNewOfst) { mnOffset = nNewOfst; }
455 SwTextFrame *GetFrameAtPos ( const SwPosition &rPos);
456 inline const SwTextFrame *GetFrameAtPos ( const SwPosition &rPos) const;
457 SwTextFrame& GetFrameAtOfst(TextFrameIndex nOfst);
458 /// If there's a Follow and we don't contain text ourselves
459 bool IsEmptyMaster() const
460 { return GetFollow() && !GetFollow()->GetOffset(); }
462 void SetMergedPara(std::unique_ptr<sw::MergedPara> p);
463 sw::MergedPara * GetMergedPara() { return m_pMergedPara.get(); }
464 sw::MergedPara const* GetMergedPara() const { return m_pMergedPara.get(); }
466 /// Returns the text portion we want to edit (for inline see underneath)
467 const OUString& GetText() const;
468 SwTextNode const* GetTextNodeForParaProps() const;
469 SwTextNode const* GetTextNodeForFirstText() const;
470 SwTextNode * GetTextNodeFirst()
471 { return const_cast<SwTextNode*>(const_cast<SwTextFrame const*>(this)->GetTextNodeFirst()); };
472 SwTextNode const* GetTextNodeFirst() const;
473 SwDoc & GetDoc()
474 { return const_cast<SwDoc &>(const_cast<SwTextFrame const*>(this)->GetDoc()); }
475 SwDoc const& GetDoc() const;
477 SwTextFrame(SwTextNode * const, SwFrame*, sw::FrameMode eMode);
480 * SwContentFrame: the shortcut for the Frames
481 * If the void* casts wrongly, it's its own fault!
482 * The void* must be checked for 0 in any case!
484 * return true if the Portion associated with this SwTextFrame was
485 * potentially destroyed and replaced by Prepare
487 virtual bool Prepare( const PrepareHint ePrep = PrepareHint::Clear,
488 const void *pVoid = nullptr, bool bNotify = true ) override;
491 * nMaxHeight is the required height
492 * bSplit indicates, that the paragraph has to be split
493 * bTst indicates, that we are currently doing a test formatting
495 virtual bool WouldFit(SwTwips &nMaxHeight, bool &bSplit, bool bTst, bool bMoveBwd) override;
498 * The WouldFit equivalent for temporarily rewired TextFrames
499 * nMaxHeight returns the required size here too and bSplit
500 * determines whether the paragraph needs to be split.
501 * We pass the potential predecessor for the distance calculation
503 bool TestFormat( const SwFrame* pPrv, SwTwips &nMaxHeight, bool &bSplit );
506 * We format a Line for interactive hyphenation
507 * @return found
509 bool Hyphenate(SwInterHyphInfoTextFrame & rInf);
511 /// Test grow
512 inline SwTwips GrowTst( const SwTwips nGrow );
514 SwParaPortion *GetPara();
515 inline const SwParaPortion *GetPara() const;
516 inline bool HasPara() const;
517 bool HasPara_() const;
519 /// map position in potentially merged text frame to SwPosition
520 std::pair<SwTextNode*, sal_Int32> MapViewToModel(TextFrameIndex nIndex) const;
521 SwPosition MapViewToModelPos(TextFrameIndex nIndex) const;
522 TextFrameIndex MapModelToView(SwTextNode const* pNode, sal_Int32 nIndex) const;
523 TextFrameIndex MapModelToViewPos(SwPosition const& rPos) const;
525 // If there are any hanging punctuation portions in the margin
526 // the offset will be returned.
527 SwTwips HangingMargin() const;
529 /// Get the amount of lower margin of this frame we need to consider for fly portion purposes.
530 SwTwips GetLowerMarginForFlyIntersect() const;
532 // Locking
533 bool IsLocked() const { return mbLocked; }
535 bool IsWidow() const { return mbWidow; }
536 bool IsJustWidow() const { return mbJustWidow; }
537 bool IsEmpty() const { return mbEmpty; }
538 bool HasFootnote() const { return mbFootnote; }
539 bool IsInFootnoteConnect()const { return mbInFootnoteConnect;}
540 bool IsFieldFollow() const { return mbFieldFollow;}
542 inline void SetRepaint() const;
543 inline void ResetRepaint() const;
544 bool HasRepaint() const { return mbRepaint; }
545 void SetHasRotatedPortions(bool bHasRotatedPortions);
546 bool GetHasRotatedPortions() const { return mbHasRotatedPortions; }
547 void SetAnimation() const
548 { const_cast<SwTextFrame*>(this)->mbHasAnimation = true; }
549 bool HasAnimation() const { return mbHasAnimation; }
551 bool IsSwapped() const { return mbIsSwapped; }
553 /// Does the Frame have a local footnote (in this Frame or Follow)?
554 #ifdef DBG_UTIL
555 void CalcFootnoteFlag(TextFrameIndex nStop = TextFrameIndex(COMPLETE_STRING)); //For testing SplitFrame
556 #else
557 void CalcFootnoteFlag();
558 #endif
560 /// Hidden
561 virtual bool IsHiddenNow() const override; // bHidden && pOut == pPrt
562 void HideHidden(); // Remove appendage if Hidden
563 void HideFootnotes(TextFrameIndex nStart, TextFrameIndex nEnd);
566 * Hides respectively shows objects, which are anchored at paragraph,
567 * at/as a character of the paragraph, corresponding to the paragraph and
568 * paragraph portion visibility.
570 void HideAndShowObjects();
572 /// Footnote
573 void RemoveFootnote(TextFrameIndex nStart,
574 TextFrameIndex nLen = TextFrameIndex(COMPLETE_STRING));
575 inline SwTwips GetFootnoteFrameHeight() const;
576 SwTextFrame *FindFootnoteRef( const SwTextFootnote *pFootnote );
577 const SwTextFrame *FindFootnoteRef( const SwTextFootnote *pFootnote ) const
578 { return const_cast<SwTextFrame *>(this)->FindFootnoteRef( pFootnote ); }
579 void ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDeadLine );
582 * If we're a Footnote that grows towards its reference ...
583 * public, because it's needed by SwContentFrame::MakeAll
585 SwTwips GetFootnoteLine( const SwTextFootnote *pFootnote ) const;
587 TextFrameIndex GetDropLen(TextFrameIndex nWishLen) const;
589 LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript,
590 bool bNoChar = false, bool bNoneIfNoHyphenation = false ) const;
592 virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
593 virtual void CheckDirection( bool bVert ) override;
595 /// Returns the sum of line height in pLine
596 SwTwips GetParHeight() const;
598 inline SwTextFrame *GetFollow();
599 inline const SwTextFrame *GetFollow() const;
601 /// Find the page number of ErgoSum and QuoVadis
602 SwTextFrame *FindQuoVadisFrame();
605 * In case the SwLineLayout was cleared out of the s_pTextCache, recreate it
607 * #i29062# GetFormatted() can trigger a full formatting
608 * of the paragraph, causing other layout frames to become invalid. This
609 * has to be avoided during painting. Therefore we need to pass the
610 * information that we are currently in the paint process.
612 SwTextFrame* GetFormatted( bool bForceQuickFormat = false );
614 /// Will be moved soon
615 void SetFootnote( const bool bNew ) { mbFootnote = bNew; }
617 /// Respect the Follows
618 inline bool IsInside(TextFrameIndex nPos) const;
620 /// DropCaps and selections
621 bool GetDropRect( SwRect &rRect ) const
622 { return HasPara() && GetDropRect_( rRect ); }
624 static SwCache *GetTextCache() { return s_pTextCache; }
625 static void SetTextCache( SwCache *pNew ) { s_pTextCache = pNew; }
627 static tools::Long GetMinPrtLine() { return nMinPrtLine; }
629 sal_uInt16 GetCacheIdx() const { return mnCacheIndex; }
630 void SetCacheIdx( const sal_uInt16 nNew ) { mnCacheIndex = nNew; }
632 /// Removes the Line information from the Cache but retains the entry itself
633 void ClearPara();
634 /// Removes this frame completely from the Cache
635 void RemoveFromCache();
637 /// Am I a FootnoteFrame, with a number at the start of the paragraph?
638 bool IsFootnoteNumFrame() const
639 { return IsInFootnote() && !GetIndPrev() && IsFootnoteNumFrame_(); }
642 * Simulates a formatting as if there were not right margin or Flys or other
643 * obstacles and returns the width
645 SwTwips CalcFitToContent();
648 * Simulate format for a list item paragraph, whose list level attributes
649 * are in LABEL_ALIGNMENT mode, in order to determine additional first
650 * line offset for the real text formatting due to the value of label
651 * adjustment attribute of the list level.
653 void CalcAdditionalFirstLineOffset();
655 SwTwips GetAdditionalFirstLineOffset() const
657 return mnAdditionalFirstLineOffset;
661 * Returns the additional line spacing for the next paragraph
662 * @param _bNoPropLineSpacing: control, whether the value of a
663 * proportional line spacing is returned or not
665 tools::Long GetLineSpace( const bool _bNoPropLineSpacing = false ) const;
667 /// Returns the first line height
668 sal_uInt16 FirstLineHeight() const;
670 /// Rewires FlyInContentFrame, if nEnd > Index >= nStart
671 void MoveFlyInCnt(SwTextFrame *pNew, TextFrameIndex nStart, TextFrameIndex nEnd);
673 /// Calculates the position of FlyInContentFrames
674 TextFrameIndex CalcFlyPos( SwFrameFormat const * pSearch );
676 /// Determines the start position and step size of the register
677 bool FillRegister( SwTwips& rRegStart, sal_uInt16& rRegDiff );
679 /// Determines the line count
680 sal_Int32 GetLineCount(TextFrameIndex nPos);
682 /// For displaying the line numbers
683 sal_Int32 GetAllLines() const { return mnAllLines; }
684 sal_Int32 GetThisLines() const { return mnThisLines;}
685 void RecalcAllLines();
687 /// Stops the animations within numberings
688 void StopAnimation( const OutputDevice *pOut );
690 /// Visit all portions for Accessibility
691 void VisitPortions( SwPortionHandler& rPH ) const;
693 /// Returns the script info stored at the paraportion
694 const SwScriptInfo* GetScriptInfo() const;
696 /// Swaps width and height of the text frame
697 void SwapWidthAndHeight();
700 * Calculates the coordinates of a rectangle when switching from
701 * horizontal to vertical layout
703 void SwitchHorizontalToVertical( SwRect& rRect ) const;
706 * Calculates the coordinates of a point when switching from
707 * horizontal to vertical layout
709 void SwitchHorizontalToVertical( Point& rPoint ) const;
712 * Calculates the limit value when switching from
713 * horizontal to vertical layout
715 tools::Long SwitchHorizontalToVertical( tools::Long nLimit ) const;
718 * Calculates the coordinates of a rectangle when switching from
719 * vertical to horizontal layout
721 void SwitchVerticalToHorizontal( SwRect& rRect ) const;
724 * Calculates the coordinates of a point when switching from
725 * vertical to horizontal layout
727 void SwitchVerticalToHorizontal( Point& rPoint ) const;
730 * Calculates the a limit value when switching from
731 * vertical to horizontal layout
733 tools::Long SwitchVerticalToHorizontal( tools::Long nLimit ) const;
736 * Calculates the coordinates of a rectangle when switching from
737 * LTR to RTL layout
739 void SwitchLTRtoRTL( SwRect& rRect ) const;
742 * Calculates the coordinates of a point when switching from
743 * LTR to RTL layout
745 void SwitchLTRtoRTL( Point& rPoint ) const;
748 * Calculates the coordinates of a rectangle when switching from
749 * RTL to LTR layout
751 void SwitchRTLtoLTR( SwRect& rRect ) const { SwitchLTRtoRTL( rRect ); }
754 * Calculates the coordinates of a point when switching from
755 * RTL to LTR layout
757 void SwitchRTLtoLTR( Point& rPoint ) const { SwitchLTRtoRTL( rPoint ); };
759 bool FollowFormatAllowed() const
761 return mbFollowFormatAllowed;
764 void AllowFollowFormat()
766 mbFollowFormatAllowed = true;
769 void ForbidFollowFormat()
771 mbFollowFormatAllowed = false;
774 SwTwips GetBaseOffsetForFly( bool bIgnoreFlysAnchoredAtThisFrame ) const
776 return ( bIgnoreFlysAnchoredAtThisFrame ?
777 mnFlyAnchorOfst :
778 mnFlyAnchorOfstNoWrap );
781 SwTwips GetBaseVertOffsetForFly(bool bIgnoreFlysAnchoredAtThisFrame) const;
783 SwTwips GetHeightOfLastLine() const
785 return mnHeightOfLastLine;
788 static void repaintTextFrames( const SwTextNode& rNode );
790 void RegisterToNode(SwTextNode &, bool isForceNodeAsFirst = false);
792 bool IsSymbolAt(TextFrameIndex) const;
793 OUString GetCurWord(SwPosition const&) const;
794 sal_uInt16 GetScalingOfSelectedText(TextFrameIndex nStt, TextFrameIndex nEnd);
796 /// This text frame may have a split fly frames anchored to it. Is any of them a frame that has
797 /// a follow, i.e. not the last in a master -> follow 1 -> ... -> last follow chain?
798 SwFlyAtContentFrame* HasNonLastSplitFlyDrawObj() const;
800 /// This text frame has a follow and the text frame don't contain text. Additionally one split
801 /// fly is anchored to the text frame.
802 bool IsEmptyMasterWithSplitFly() const;
804 /// This text frame is not split, doesn't fit the upper, has a single split fly anchored to it
805 /// with a negative vertical offset. Such frames may need explicit splitting.
806 bool IsEmptyWithSplitFly() const;
808 static SwView* GetView();
810 void dumpAsXml(xmlTextWriterPtr writer = nullptr) const override;
811 void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override;
814 //use this to protect a SwTextFrame for a given scope from getting merged with
815 //its neighbour and thus deleted
816 class TextFrameLockGuard
818 private:
819 SwTextFrame *m_pTextFrame;
820 bool m_bOldLocked;
821 public:
822 //Lock pFrame for the lifetime of the Cut/Paste call, etc. to avoid
823 //SwTextFrame::AdjustFollow_ removing the pFrame we're trying to Make
824 TextFrameLockGuard(SwFrame* pFrame)
826 m_pTextFrame = pFrame->IsTextFrame() ? static_cast<SwTextFrame*>(pFrame) : nullptr;
827 if (m_pTextFrame)
829 m_bOldLocked = m_pTextFrame->IsLocked();
830 m_pTextFrame->Lock();
832 else
834 m_bOldLocked = false;
838 ~TextFrameLockGuard()
840 if (m_pTextFrame && !m_bOldLocked)
841 m_pTextFrame->Unlock();
845 inline const SwParaPortion *SwTextFrame::GetPara() const
847 return const_cast<SwTextFrame*>(this)->GetPara();
850 inline bool SwTextFrame::HasPara() const
852 return mnCacheIndex!=USHRT_MAX && HasPara_();
855 inline SwTwips SwTextFrame::GrowTst( const SwTwips nGrow )
857 return Grow( nGrow, true );
860 inline bool SwTextFrame::IsInside(TextFrameIndex const nPos) const
862 bool bRet = true;
863 if( nPos < GetOffset() )
864 bRet = false;
865 else
867 const SwTextFrame *pFoll = GetFollow();
868 if( pFoll && nPos >= pFoll->GetOffset() )
869 bRet = false;
871 return bRet;
874 inline SwTwips SwTextFrame::GetFootnoteFrameHeight() const
876 if( !IsFollow() && IsInFootnote() && HasPara() )
877 return GetFootnoteFrameHeight_();
878 else
879 return 0;
882 inline const SwTextFrame *SwTextFrame::GetFollow() const
884 return static_cast<const SwTextFrame*>(SwContentFrame::GetFollow());
886 inline SwTextFrame *SwTextFrame::GetFollow()
888 return static_cast<SwTextFrame*>(SwContentFrame::GetFollow());
891 inline const SwTextFrame *SwTextFrame::GetFrameAtPos( const SwPosition &rPos) const
893 return const_cast<SwTextFrame*>(this)->GetFrameAtPos( rPos );
896 inline void SwTextFrame::SetOffset(TextFrameIndex const nNewOfst)
898 if ( mnOffset != nNewOfst )
899 SetOffset_( nNewOfst );
902 inline void SwTextFrame::SetRepaint() const
904 const_cast<SwTextFrame*>(this)->mbRepaint = true;
906 inline void SwTextFrame::ResetRepaint() const
908 const_cast<SwTextFrame*>(this)->mbRepaint = false;
911 class TemporarySwap {
912 protected:
913 explicit TemporarySwap(SwTextFrame * frame, bool swap):
914 m_frame(frame), m_undo(false)
916 if (m_frame->IsVertical() && swap) {
917 m_undo = true;
918 m_frame->SwapWidthAndHeight();
922 ~TemporarySwap() {
923 if (m_undo) {
924 m_frame->SwapWidthAndHeight();
928 private:
929 TemporarySwap(TemporarySwap const &) = delete;
930 void operator =(TemporarySwap const &) = delete;
932 SwTextFrame * m_frame;
933 bool m_undo;
936 class SwSwapIfSwapped: private TemporarySwap {
937 public:
938 explicit SwSwapIfSwapped(SwTextFrame* frame):
939 TemporarySwap(frame, frame->IsSwapped()) {}
942 class SwSwapIfNotSwapped: private TemporarySwap {
943 public:
944 explicit SwSwapIfNotSwapped(SwTextFrame* frame):
945 TemporarySwap(frame, !frame->IsSwapped()) {}
949 * Helper class which can be used instead of the macros if a function
950 * has too many returns
952 class SwFrameSwapper
954 const SwTextFrame* pFrame;
955 bool bUndo;
956 public:
957 SwFrameSwapper( const SwTextFrame* pFrame, bool bSwapIfNotSwapped );
958 ~SwFrameSwapper();
961 class SwLayoutModeModifier
963 const OutputDevice& m_rOut;
964 vcl::text::ComplexTextLayoutFlags m_nOldLayoutMode;
965 public:
966 SwLayoutModeModifier( const OutputDevice& rOutp );
967 ~SwLayoutModeModifier();
968 void Modify( bool bChgToRTL );
969 void SetAuto();
972 class SwDigitModeModifier
974 const OutputDevice& rOut;
975 LanguageType nOldLanguageType;
976 public:
977 SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang );
978 ~SwDigitModeModifier();
981 namespace sw {
984 * Describes parts of multiple text nodes, which will form a text frame, even
985 * when redlines are hidden at a layout level.
987 struct MergedPara
989 sw::WriterMultiListener listener;
990 std::vector<Extent> extents;
991 /// note: cannot be const currently to avoid UB because SwTextGuess::Guess
992 /// const_casts it and modifies it (also, Update will modify it)
993 OUString mergedText;
994 /// most paragraph properties are taken from the first non-empty node
995 SwTextNode * pParaPropsNode;
996 /// except break attributes, those are taken from the first node
997 SwTextNode *const pFirstNode;
998 /// mainly for sanity checks
999 SwTextNode const* pLastNode;
1000 MergedPara(SwTextFrame & rFrame, std::vector<Extent>&& rExtents,
1001 OUString aText,
1002 SwTextNode *const pProps, SwTextNode *const pFirst,
1003 SwTextNode const*const pLast)
1004 : listener(rFrame), extents(std::move(rExtents)), mergedText(std::move(aText))
1005 , pParaPropsNode(pProps), pFirstNode(pFirst), pLastNode(pLast)
1007 assert(pParaPropsNode);
1008 assert(pFirstNode);
1009 assert(pLastNode);
1013 /// iterate SwTextAttr in potentially merged text frame
1014 class MergedAttrIterBase
1016 protected:
1017 sw::MergedPara const*const m_pMerged;
1018 SwTextNode const*const m_pNode;
1019 size_t m_CurrentExtent;
1020 size_t m_CurrentHint;
1021 MergedAttrIterBase(SwTextFrame const& rFrame);
1024 class MergedAttrIter
1025 : public MergedAttrIterBase
1027 public:
1028 MergedAttrIter(SwTextFrame const& rFrame) : MergedAttrIterBase(rFrame) {}
1029 SwTextAttr const* NextAttr(SwTextNode const** ppNode = nullptr);
1032 class MergedAttrIterByEnd
1034 private:
1035 std::vector<std::pair<SwTextNode const*, SwTextAttr const*>> m_Hints;
1036 SwTextNode const*const m_pNode;
1037 size_t m_CurrentHint;
1038 public:
1039 MergedAttrIterByEnd(SwTextFrame const& rFrame);
1040 SwTextAttr const* NextAttr(SwTextNode const*& rpNode);
1041 void PrevAttr();
1044 class MergedAttrIterReverse
1045 : public MergedAttrIterBase
1047 public:
1048 MergedAttrIterReverse(SwTextFrame const& rFrame);
1049 SwTextAttr const* PrevAttr(SwTextNode const** ppNode = nullptr);
1053 const SwTwips WIDOW_MAGIC = (SAL_MAX_INT32 - 1)/2;
1055 } // namespace sw
1057 #endif
1059 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */