nss: upgrade to release 3.73
[LibreOffice.git] / sw / source / core / inc / txtfrm.hxx
blob389adb8c92ad5364039a2909e670d86abeeaad77
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"
26 #include <set>
28 namespace com::sun::star::linguistic2 { class XHyphenatedWord; }
30 namespace sw::mark { class IMark; }
31 class SwCharRange;
32 class SwTextNode;
33 class SwTextAttrEnd;
34 class SwTextFormatter;
35 class SwTextFormatInfo;
36 class SwParaPortion;
37 class WidowsAndOrphans;
38 class SwTextFootnote;
39 class SwInterHyphInfo; // Hyphenate()
40 class SwCache;
41 class SwBorderAttrs;
42 class SwFrameFormat;
43 struct SwCursorMoveState;
44 struct SwFillData;
45 class SwPortionHandler;
46 class SwScriptInfo;
47 enum class ExpandMode;
48 class SwTextAttr;
50 #define NON_PRINTING_CHARACTER_COLOR Color(0x26, 0x8b, 0xd2)
52 /// a clone of SwInterHyphInfo, but with TextFrameIndex instead of node index
53 class SwInterHyphInfoTextFrame
55 private:
56 /// output: hyphenated word
57 css::uno::Reference<css::linguistic2::XHyphenatedWord> m_xHyphWord;
58 public:
59 /// input: requested range to hyphenate
60 TextFrameIndex m_nStart;
61 TextFrameIndex m_nEnd;
62 /// output: found word
63 TextFrameIndex m_nWordStart;
64 TextFrameIndex m_nWordLen;
66 SwInterHyphInfoTextFrame(SwTextFrame const& rFrame,
67 SwTextNode const& rNode, SwInterHyphInfo const& rHyphInfo);
68 void UpdateTextNodeHyphInfo(SwTextFrame const& rFrame,
69 SwTextNode const& rNode, SwInterHyphInfo & o_rHyphInfo);
71 void SetHyphWord(const css::uno::Reference<css::linguistic2::XHyphenatedWord> &xHW)
73 m_xHyphWord = xHW;
77 namespace sw {
79 /**
80 * Describes a part of a single text node, which will be part of a text frame,
81 * even when redlines are hidden at a layout level.
83 struct Extent
85 SwTextNode * /*const logically, but need assignment for std::vector*/ pNode;
86 sal_Int32 nStart;
87 sal_Int32 nEnd;
88 Extent(SwTextNode *const p, sal_Int32 const s, sal_Int32 const e)
89 : pNode(p), nStart(s), nEnd(e)
91 assert(pNode);
92 assert(nStart != nEnd);
96 struct MergedPara;
98 std::pair<SwTextNode*, sal_Int32> MapViewToModel(MergedPara const&, TextFrameIndex nIndex);
99 TextFrameIndex MapModelToView(MergedPara const&, SwTextNode const* pNode, sal_Int32 nIndex);
101 // warning: Existing must be used only once; a second use would delete the frame created by the first one...
102 enum class FrameMode { New, Existing };
103 std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, FrameMode eMode);
104 SwTextFrame * MakeTextFrame(SwTextNode & rNode, SwFrame *, sw::FrameMode eMode);
106 bool FrameContainsNode(SwContentFrame const& rFrame, sal_uLong nNodeIndex);
107 bool IsParaPropsNode(SwRootFrame const& rLayout, SwTextNode const& rNode);
108 SwTextNode * GetParaPropsNode(SwRootFrame const& rLayout, SwNodeIndex const& rNode);
109 SwPosition GetParaPropsPos(SwRootFrame const& rLayout, SwPosition const& rPos);
110 std::pair<SwTextNode *, SwTextNode *>
111 GetFirstAndLastNode(SwRootFrame const& rLayout, SwNodeIndex const& rPos);
113 SwTextNode const& GetAttrMerged(SfxItemSet & rFormatSet,
114 SwTextNode const& rNode, SwRootFrame const* pLayout);
116 void GotoPrevLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const* pLayout);
117 void GotoNextLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const* pLayout);
119 TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
120 bool isRealDelete,
121 SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen);
123 void MoveMergedFlysAndFootnotes(std::vector<SwTextFrame*> const& rFrames,
124 SwTextNode const& rFirstNode, SwTextNode & rSecondNode, bool);
126 void MoveDeletedPrevFrames(const SwTextNode & rDeletedPrev, SwTextNode & rNode);
127 enum class Recreate { No, ThisNode, Predecessor };
128 void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate eRecreateMerged);
130 void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
131 void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
133 void AddRemoveFlysAnchoredToFrameStartingAtNode(
134 SwTextFrame & rFrame, SwTextNode & rTextNode,
135 std::set<sal_uLong> *pSkipped);
137 OUString GetExpandTextMerged(SwRootFrame const* pLayout,
138 SwTextNode const& rNode, bool bWithNumber,
139 bool bWithSpacesForLevel, ExpandMode i_mode);
141 bool IsMarkHidden(SwRootFrame const& rLayout, ::sw::mark::IMark const& rMark);
142 bool IsMarkHintHidden(SwRootFrame const& rLayout,
143 SwTextNode const& rNode, SwTextAttrEnd const& rHint);
145 void RecreateStartTextFrames(SwTextNode & rNode);
147 } // namespace sw
149 /// Represents the visualization of a paragraph. Typical upper is an
150 /// SwBodyFrame. The first text portion of the first line is az SwParaPortion.
151 class SW_DLLPUBLIC SwTextFrame: public SwContentFrame
153 friend class SwTextIter;
154 friend class SwTestFormat;
155 friend class WidowsAndOrphans;
156 friend class TextFrameLockGuard; // May Lock()/Unlock()
157 friend bool sw_ChangeOffset(SwTextFrame* pFrame, TextFrameIndex nNew);
159 /// SwLineLayout cache: the lines are not actually owned by the SwTextFrame
160 /// but by this SwCache, so they will be deleted in large documents
161 /// if there are too many of them, but the "valid" flags of the frame
162 /// will still be set; GetFormatted() is the function that forces
163 /// recreation of the SwLineLayout by Format() if necessary.
164 static SwCache *s_pTextCache;
165 static constexpr tools::Long nMinPrtLine = 0; // This Line must not be underrun when printing
166 // Hack for table cells stretching multiple pages
168 sal_uLong mnAllLines :24; // Line count for the Paint (including nThisLines)
169 sal_uLong mnThisLines :8; // Count of Lines of the Frame
171 // The x position for flys anchored at this paragraph.
172 // These values are calculated in SwTextFrame::CalcBaseOfstForFly()
173 SwTwips mnFlyAnchorOfst;
174 // The x position for wrap-through flys anchored at this paragraph.
175 SwTwips mnFlyAnchorOfstNoWrap;
176 /// The y position for wrap-through flys anchored at this paragraph.
177 SwTwips mnFlyAnchorVertOfstNoWrap;
178 SwTwips mnFootnoteLine;
179 // OD 2004-03-17 #i11860# - re-factoring of #i11859#
180 // member for height of last line (value needed for proportional line spacing)
181 SwTwips mnHeightOfLastLine;
182 // member for the additional first line offset, which is caused by the list
183 // label alignment for list level position and space mode LABEL_ALIGNMENT.
184 // This additional first line offset is used for the text formatting.
185 // It is NOT used for the determination of printing area.
186 SwTwips mnAdditionalFirstLineOffset;
188 /// redline merge data
189 std::unique_ptr<sw::MergedPara> m_pMergedPara;
191 TextFrameIndex mnOffset; // Is the offset in the Content (character count)
193 sal_uInt16 mnCacheIndex; // Index into the cache, USHRT_MAX if there's definitely no fitting object in the cache
195 // Separates the Master and creates a Follow or adjusts the data in the Follow
196 void AdjustFollow_( SwTextFormatter &rLine, TextFrameIndex nOffset,
197 TextFrameIndex nStrEnd, const sal_uInt8 nMode );
199 // Iterates all Lines and sets the line spacing using the attribute
200 void CalcLineSpace();
202 // Only called in Format
203 void AdjustFrame( const SwTwips nChgHeight, bool bHasToFit = false );
205 // Evaluates the Preps in Format()
206 bool CalcPreps();
207 void PrepWidows( const sal_uInt16 nNeed, bool bNotify );
208 void InvalidateRange_( const SwCharRange &, const tools::Long = 0);
209 inline void InvalidateRange( const SwCharRange &, const tools::Long = 0);
211 // WidowsAndOrphans, AdjustFrame, AdjustFollow
212 void FormatAdjust( SwTextFormatter &rLine, WidowsAndOrphans &rFrameBreak,
213 TextFrameIndex nStrLen, const bool bDummy );
214 void ChangeOffset( SwTextFrame* pFrame, TextFrameIndex nNew );
216 bool mbLocked : 1; // In the Format?
217 bool mbWidow : 1; // Is our follow a Widow?
218 bool mbJustWidow : 1; // Did we just request Widow flag on master?
219 bool mbEmpty : 1; // Are we an empty paragraph?
220 bool mbInFootnoteConnect : 1; // Is in Connect at the moment
221 bool mbFootnote : 1; // Has at least one footnote
222 bool mbRepaint : 1; // TextFrame: Repaint is ready to be fetched
223 /// Contains rotated portions.
224 bool mbHasRotatedPortions : 1;
225 bool mbFieldFollow : 1; // Start with Field rest of the Master
226 bool mbHasAnimation : 1; // Contains animated SwGrfNumPortion
227 bool mbIsSwapped : 1; // during text formatting we swap the
228 // width and height for vertical formatting
229 // OD 14.03.2003 #i11760# - flag to control, if follow is formatted in
230 // method <CalcFollow(..)>.
231 // E.g., avoid formatting of follow, if method <SwLayoutFrame::FormatWidthCols(..)>
232 // is running.
233 bool mbFollowFormatAllowed : 1;
235 void ResetPreps();
236 void Lock() { mbLocked = true; }
237 void Unlock() { mbLocked = false; }
238 void SetWidow( const bool bNew ) { mbWidow = bNew; }
239 void SetJustWidow( const bool bNew ) { mbJustWidow = bNew; }
240 void SetEmpty( const bool bNew ) { mbEmpty = bNew; }
241 void SetFieldFollow( const bool bNew ) { mbFieldFollow = bNew; }
243 bool IsIdxInside(TextFrameIndex nPos, TextFrameIndex nLen) const;
245 // Changes the Frame or not (cf. FlyCnt)
246 bool GetModelPositionForViewPoint_(SwPosition *pPos, const Point &rPoint,
247 const bool bChgFrame, SwCursorMoveState* = nullptr ) const;
248 void FillCursorPos( SwFillData &rFill ) const;
250 // Format exactly one Line
251 bool FormatLine( SwTextFormatter &rLine, const bool bPrev );
253 // In order to safe stack space, we split this method:
254 // Format_ calls Format_ with parameters
255 void Format_( vcl::RenderContext* pRenderContext, SwParaPortion *pPara );
256 void Format_( SwTextFormatter &rLine, SwTextFormatInfo &rInf,
257 const bool bAdjust = false );
258 void FormatOnceMore( SwTextFormatter &rLine, SwTextFormatInfo &rInf );
260 // Formats the Follow and ensures disposing on orphans
261 bool CalcFollow(TextFrameIndex nTextOfst);
263 virtual void MakePos() override;
265 // Corrects the position from which we need to format
266 static TextFrameIndex FindBrk(const OUString &rText, TextFrameIndex nStart,
267 TextFrameIndex nEnd);
269 // inline branch
270 SwTwips GetFootnoteFrameHeight_() const;
272 // Outsourced to CalcPreps
273 bool CalcPrepFootnoteAdjust();
275 // For Footnote and WidOrp: Forced validation
276 void ValidateFrame();
277 void ValidateBodyFrame();
279 bool GetDropRect_( SwRect &rRect ) const;
281 void SetPara( SwParaPortion *pNew, bool bDelete = true );
283 bool IsFootnoteNumFrame_() const;
285 // Refresh formatting information
286 bool FormatQuick( bool bForceQuickFormat );
288 // Opt: Format empty paragraphs
289 bool FormatEmpty();
290 SwTwips EmptyHeight() const;
292 // Opt: Paint empty paragraphs
293 bool PaintEmpty( const SwRect &, bool bCheck ) const;
295 void ChgThisLines(); // Must always be called if the Line count could have changed
297 // required for 'new' relative anchor position
298 void CalcBaseOfstForFly();
300 /** method to determine height of last line, needed for proportional line spacing
302 OD 2004-03-17 #i11860#
303 OD 2005-05-20 #i47162# - introduce new optional parameter <_bUseFont>
304 in order to force the usage of the former algorithm to determine the
305 height of the last line, which uses the font.
307 @param _bUseFont
308 optional input parameter - boolean indicating, if the font has to be
309 used to determine the height of the last line. default value: false
311 void CalcHeightOfLastLine( const bool _bUseFont = false );
313 virtual void DestroyImpl() override;
314 virtual ~SwTextFrame() override;
316 protected:
317 virtual void SwClientNotify(SwModify const& rModify, SfxHint const& rHint) override;
319 public:
321 virtual const SvxFormatBreakItem& GetBreakItem() const override;
322 virtual const SwFormatPageDesc& GetPageDescItem() const override;
324 css::uno::Sequence< css::style::TabStop > GetTabStopInfo( SwTwips CurrentPos ) override;
327 * This is public, as it needs to be called by some methods in order to save the Prepare
328 * USE WITH CAUTION!
330 void Init();
332 /// Is called by DoIdleJob_() and ExecSpellPopup()
333 SwRect AutoSpell_(SwTextNode &, sal_Int32);
335 /// Is called by DoIdleJob_()
336 SwRect SmartTagScan(SwTextNode &);
338 /// Is called by DoIdleJob_()
339 void CollectAutoCmplWrds(SwTextNode &, sal_Int32);
342 * Returns the screen position of rPos. The values are relative to the upper
343 * left position of the page frame.
344 * Additional information can be obtained by passing an SwCursorMoveState object.
345 * Returns false if rPos > number of character is string
347 virtual bool GetCharRect( SwRect& rRect, const SwPosition& rPos,
348 SwCursorMoveState* pCMS = nullptr, bool bAllowFarAway = true ) const override;
350 /// A slimmer version of GetCharRect for autopositioning Frames
351 bool GetAutoPos( SwRect &, const SwPosition& ) const;
354 * Determine top of line for given position in the text frame
356 * OD 11.11.2003 #i22341#
357 * Assumption: given position exists in the text frame or in a follow of it
358 * OD 2004-02-02 - adjustment
359 * Top of first paragraph line is the top of the paragraph.
360 * OD 2004-03-18 #i11860# - Consider upper space amount considered for
361 * previous frame and the page grid.
363 * @param _onTopOfLine
364 * output parameter - top of line, if the given position is found in the
365 * text frame.
367 * @param _rPos
368 * input parameter - reference to the position in the text frame
370 * @return boolean indicating, if the top of line for the given position
371 * has been determined or not.
373 bool GetTopOfLine( SwTwips& _onTopOfLine,
374 const SwPosition& _rPos ) const;
376 virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const override;
379 * In nOffset returns the offset of the char within the set
380 * text buffer, which is closest to the position provided by
381 * aPoint within the layout's SSize.
383 * @returns false if the SPoint is outside of the SSize else
384 * returns true
386 virtual bool GetModelPositionForViewPoint( SwPosition *, Point&,
387 SwCursorMoveState* = nullptr, bool bTestBackground = false ) const override;
390 * Makes sure that the Frame is not switched (e.g. switched for a
391 * character-bound Frame)
393 bool GetKeyCursorOfst(SwPosition *pPos, const Point &rPoint ) const
394 { return GetModelPositionForViewPoint_( pPos, rPoint, false ); }
396 void PaintExtraData( const SwRect & rRect ) const; /// Page number etc.
397 SwRect GetPaintSwRect();
398 virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&,
399 SwPrintData const*const pPrintData = nullptr ) const override;
400 virtual bool GetInfo( SfxPoolItem & ) const override;
403 * Layout oriented cursor travelling:
404 * Left border, right border, previous Line, following Line,
405 * same horizontal position
407 virtual bool LeftMargin(SwPaM *) const override;
408 virtual bool RightMargin(SwPaM *, bool bAPI = false) const override;
410 virtual bool UnitUp(SwPaM *, const SwTwips nOffset,
411 bool bSetInReadOnly ) const override;
412 virtual bool UnitDown(SwPaM *, const SwTwips nOffset,
413 bool bSetInReadOnly ) const override;
414 bool UnitUp_(SwPaM *, const SwTwips nOffset,
415 bool bSetInReadOnly ) const;
416 bool UnitDown_(SwPaM *, const SwTwips nOffset,
417 bool bSetInReadOnly ) const;
420 * Prepares the cursor position for a visual cursor move (BiDi).
421 * The behaviour is different for insert and overwrite cursors
423 void PrepareVisualMove( TextFrameIndex& nPos, sal_uInt8& nCursorLevel,
424 bool& bRight, bool bInsertCursor );
426 /// Methods to manage the FollowFrame
427 void SplitFrame(TextFrameIndex nTextPos);
428 SwContentFrame *JoinFrame();
429 TextFrameIndex GetOffset() const { return mnOffset; }
430 void SetOffset_(TextFrameIndex nNewOfst);
431 inline void SetOffset (TextFrameIndex nNewOfst);
432 void ManipOfst(TextFrameIndex const nNewOfst) { mnOffset = nNewOfst; }
433 SwTextFrame *GetFrameAtPos ( const SwPosition &rPos);
434 inline const SwTextFrame *GetFrameAtPos ( const SwPosition &rPos) const;
435 SwTextFrame& GetFrameAtOfst(TextFrameIndex nOfst);
436 /// If there's a Follow and we don't contain text ourselves
437 bool IsEmptyMaster() const
438 { return GetFollow() && !GetFollow()->GetOffset(); }
440 void SetMergedPara(std::unique_ptr<sw::MergedPara> p);
441 sw::MergedPara * GetMergedPara() { return m_pMergedPara.get(); }
442 sw::MergedPara const* GetMergedPara() const { return m_pMergedPara.get(); }
444 /// Returns the text portion we want to edit (for inline see underneath)
445 const OUString& GetText() const;
446 SwTextNode const* GetTextNodeForParaProps() const;
447 SwTextNode const* GetTextNodeForFirstText() const;
448 SwTextNode * GetTextNodeFirst()
449 { return const_cast<SwTextNode*>(const_cast<SwTextFrame const*>(this)->GetTextNodeFirst()); };
450 SwTextNode const* GetTextNodeFirst() const;
451 SwDoc & GetDoc()
452 { return const_cast<SwDoc &>(const_cast<SwTextFrame const*>(this)->GetDoc()); }
453 SwDoc const& GetDoc() const;
455 SwTextFrame(SwTextNode * const, SwFrame*, sw::FrameMode eMode);
458 * SwContentFrame: the shortcut for the Frames
459 * If the void* casts wrongly, it's its own fault!
460 * The void* must be checked for 0 in any case!
462 * return true if the Portion associated with this SwTextFrame was
463 * potentially destroyed and replaced by Prepare
465 virtual bool Prepare( const PrepareHint ePrep = PrepareHint::Clear,
466 const void *pVoid = nullptr, bool bNotify = true ) override;
469 * nMaxHeight is the required height
470 * bSplit indicates, that the paragraph has to be split
471 * bTst indicates, that we are currently doing a test formatting
473 virtual bool WouldFit( SwTwips &nMaxHeight, bool &bSplit, bool bTst ) override;
476 * The WouldFit equivalent for temporarily rewired TextFrames
477 * nMaxHeight returns the required size here too and bSplit
478 * determines whether the paragraph needs to be split.
479 * We pass the potential predecessor for the distance calculation
481 bool TestFormat( const SwFrame* pPrv, SwTwips &nMaxHeight, bool &bSplit );
484 * We format a Line for interactive hyphenation
485 * @return found
487 bool Hyphenate(SwInterHyphInfoTextFrame & rInf);
489 /// Test grow
490 inline SwTwips GrowTst( const SwTwips nGrow );
492 SwParaPortion *GetPara();
493 inline const SwParaPortion *GetPara() const;
494 inline bool HasPara() const;
495 bool HasPara_() const;
497 /// map position in potentially merged text frame to SwPosition
498 std::pair<SwTextNode*, sal_Int32> MapViewToModel(TextFrameIndex nIndex) const;
499 SwPosition MapViewToModelPos(TextFrameIndex nIndex) const;
500 TextFrameIndex MapModelToView(SwTextNode const* pNode, sal_Int32 nIndex) const;
501 TextFrameIndex MapModelToViewPos(SwPosition const& rPos) const;
503 // If there are any hanging punctuation portions in the margin
504 // the offset will be returned.
505 SwTwips HangingMargin() const;
507 // Locking
508 bool IsLocked() const { return mbLocked; }
510 bool IsWidow() const { return mbWidow; }
511 bool IsJustWidow() const { return mbJustWidow; }
512 bool IsEmpty() const { return mbEmpty; }
513 bool HasFootnote() const { return mbFootnote; }
514 bool IsInFootnoteConnect()const { return mbInFootnoteConnect;}
515 bool IsFieldFollow() const { return mbFieldFollow;}
517 inline void SetRepaint() const;
518 inline void ResetRepaint() const;
519 bool HasRepaint() const { return mbRepaint; }
520 void SetHasRotatedPortions(bool bHasRotatedPortions);
521 bool GetHasRotatedPortions() const { return mbHasRotatedPortions; }
522 void SetAnimation() const
523 { const_cast<SwTextFrame*>(this)->mbHasAnimation = true; }
524 bool HasAnimation() const { return mbHasAnimation; }
526 bool IsSwapped() const { return mbIsSwapped; }
528 /// Does the Frame have a local footnote (in this Frame or Follow)?
529 #ifdef DBG_UTIL
530 void CalcFootnoteFlag(TextFrameIndex nStop = TextFrameIndex(COMPLETE_STRING)); //For testing SplitFrame
531 #else
532 void CalcFootnoteFlag();
533 #endif
535 /// Hidden
536 bool IsHiddenNow() const; // bHidden && pOut == pPrt
537 void HideHidden(); // Remove appendage if Hidden
538 void HideFootnotes(TextFrameIndex nStart, TextFrameIndex nEnd);
541 * Hides respectively shows objects, which are anchored at paragraph,
542 * at/as a character of the paragraph, corresponding to the paragraph and
543 * paragraph portion visibility.
545 void HideAndShowObjects();
547 /// Footnote
548 void RemoveFootnote(TextFrameIndex nStart,
549 TextFrameIndex nLen = TextFrameIndex(COMPLETE_STRING));
550 inline SwTwips GetFootnoteFrameHeight() const;
551 SwTextFrame *FindFootnoteRef( const SwTextFootnote *pFootnote );
552 const SwTextFrame *FindFootnoteRef( const SwTextFootnote *pFootnote ) const
553 { return const_cast<SwTextFrame *>(this)->FindFootnoteRef( pFootnote ); }
554 void ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDeadLine );
557 * If we're a Footnote that grows towards its reference ...
558 * public, because it's needed by SwContentFrame::MakeAll
560 SwTwips GetFootnoteLine( const SwTextFootnote *pFootnote ) const;
562 TextFrameIndex GetDropLen(TextFrameIndex nWishLen) const;
564 LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript,
565 bool bNoChar = false) const;
567 virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
568 virtual void CheckDirection( bool bVert ) override;
570 /// Returns the sum of line height in pLine
571 sal_uInt16 GetParHeight() const;
573 inline SwTextFrame *GetFollow();
574 inline const SwTextFrame *GetFollow() const;
576 /// Find the page number of ErgoSum and QuoVadis
577 SwTextFrame *FindQuoVadisFrame();
580 * In case the SwLineLayout was cleared out of the s_pTextCache, recreate it
582 * #i29062# GetFormatted() can trigger a full formatting
583 * of the paragraph, causing other layout frames to become invalid. This
584 * has to be avoided during painting. Therefore we need to pass the
585 * information that we are currently in the paint process.
587 SwTextFrame* GetFormatted( bool bForceQuickFormat = false );
589 /// Will be moved soon
590 void SetFootnote( const bool bNew ) { mbFootnote = bNew; }
592 /// Respect the Follows
593 inline bool IsInside(TextFrameIndex nPos) const;
595 /// DropCaps and selections
596 bool GetDropRect( SwRect &rRect ) const
597 { return HasPara() && GetDropRect_( rRect ); }
599 static SwCache *GetTextCache() { return s_pTextCache; }
600 static void SetTextCache( SwCache *pNew ) { s_pTextCache = pNew; }
602 static tools::Long GetMinPrtLine() { return nMinPrtLine; }
604 sal_uInt16 GetCacheIdx() const { return mnCacheIndex; }
605 void SetCacheIdx( const sal_uInt16 nNew ) { mnCacheIndex = nNew; }
607 /// Removes the Line information from the Cache but retains the entry itself
608 void ClearPara();
609 /// Removes this frame completely from the Cache
610 void RemoveFromCache();
612 /// Am I a FootnoteFrame, with a number at the start of the paragraph?
613 bool IsFootnoteNumFrame() const
614 { return IsInFootnote() && !GetIndPrev() && IsFootnoteNumFrame_(); }
617 * Simulates a formatting as if there were not right margin or Flys or other
618 * obstacles and returns the width
620 SwTwips CalcFitToContent();
623 * Simulate format for a list item paragraph, whose list level attributes
624 * are in LABEL_ALIGNMENT mode, in order to determine additional first
625 * line offset for the real text formatting due to the value of label
626 * adjustment attribute of the list level.
628 void CalcAdditionalFirstLineOffset();
630 SwTwips GetAdditionalFirstLineOffset() const
632 return mnAdditionalFirstLineOffset;
636 * Returns the additional line spacing for the next paragraph
637 * @param _bNoPropLineSpacing: control, whether the value of a
638 * proportional line spacing is returned or not
640 tools::Long GetLineSpace( const bool _bNoPropLineSpacing = false ) const;
642 /// Returns the first line height
643 sal_uInt16 FirstLineHeight() const;
645 /// Rewires FlyInContentFrame, if nEnd > Index >= nStart
646 void MoveFlyInCnt(SwTextFrame *pNew, TextFrameIndex nStart, TextFrameIndex nEnd);
648 /// Calculates the position of FlyInContentFrames
649 TextFrameIndex CalcFlyPos( SwFrameFormat const * pSearch );
651 /// Determines the start position and step size of the register
652 bool FillRegister( SwTwips& rRegStart, sal_uInt16& rRegDiff );
654 /// Determines the line count
655 sal_uInt16 GetLineCount(TextFrameIndex nPos);
657 /// For displaying the line numbers
658 sal_uLong GetAllLines() const { return mnAllLines; }
659 sal_uLong GetThisLines() const { return mnThisLines;}
660 void RecalcAllLines();
662 /// Stops the animations within numberings
663 void StopAnimation( const OutputDevice *pOut );
665 /// Visit all portions for Accessibility
666 void VisitPortions( SwPortionHandler& rPH ) const;
668 /// Returns the script info stored at the paraportion
669 const SwScriptInfo* GetScriptInfo() const;
671 /// Swaps width and height of the text frame
672 void SwapWidthAndHeight();
675 * Calculates the coordinates of a rectangle when switching from
676 * horizontal to vertical layout
678 void SwitchHorizontalToVertical( SwRect& rRect ) const;
681 * Calculates the coordinates of a point when switching from
682 * horizontal to vertical layout
684 void SwitchHorizontalToVertical( Point& rPoint ) const;
687 * Calculates the limit value when switching from
688 * horizontal to vertical layout
690 tools::Long SwitchHorizontalToVertical( tools::Long nLimit ) const;
693 * Calculates the coordinates of a rectangle when switching from
694 * vertical to horizontal layout
696 void SwitchVerticalToHorizontal( SwRect& rRect ) const;
699 * Calculates the coordinates of a point when switching from
700 * vertical to horizontal layout
702 void SwitchVerticalToHorizontal( Point& rPoint ) const;
705 * Calculates the a limit value when switching from
706 * vertical to horizontal layout
708 tools::Long SwitchVerticalToHorizontal( tools::Long nLimit ) const;
711 * Calculates the coordinates of a rectangle when switching from
712 * LTR to RTL layout
714 void SwitchLTRtoRTL( SwRect& rRect ) const;
717 * Calculates the coordinates of a point when switching from
718 * LTR to RTL layout
720 void SwitchLTRtoRTL( Point& rPoint ) const;
723 * Calculates the coordinates of a rectangle when switching from
724 * RTL to LTR layout
726 void SwitchRTLtoLTR( SwRect& rRect ) const { SwitchLTRtoRTL( rRect ); }
729 * Calculates the coordinates of a point when switching from
730 * RTL to LTR layout
732 void SwitchRTLtoLTR( Point& rPoint ) const { SwitchLTRtoRTL( rPoint ); };
734 bool FollowFormatAllowed() const
736 return mbFollowFormatAllowed;
739 void AllowFollowFormat()
741 mbFollowFormatAllowed = true;
744 void ForbidFollowFormat()
746 mbFollowFormatAllowed = false;
749 SwTwips GetBaseOffsetForFly( bool bIgnoreFlysAnchoredAtThisFrame ) const
751 return ( bIgnoreFlysAnchoredAtThisFrame ?
752 mnFlyAnchorOfst :
753 mnFlyAnchorOfstNoWrap );
756 SwTwips GetBaseVertOffsetForFly(bool bIgnoreFlysAnchoredAtThisFrame) const;
758 SwTwips GetHeightOfLastLine() const
760 return mnHeightOfLastLine;
763 static void repaintTextFrames( const SwTextNode& rNode );
765 void RegisterToNode(SwTextNode &, bool isForceNodeAsFirst = false);
767 bool IsSymbolAt(TextFrameIndex) const;
768 OUString GetCurWord(SwPosition const&) const;
769 sal_uInt16 GetScalingOfSelectedText(TextFrameIndex nStt, TextFrameIndex nEnd);
771 virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override;
774 //use this to protect a SwTextFrame for a given scope from getting merged with
775 //its neighbour and thus deleted
776 class TextFrameLockGuard
778 private:
779 SwTextFrame *m_pTextFrame;
780 bool m_bOldLocked;
781 public:
782 //Lock pFrame for the lifetime of the Cut/Paste call, etc. to avoid
783 //SwTextFrame::AdjustFollow_ removing the pFrame we're trying to Make
784 TextFrameLockGuard(SwFrame* pFrame)
786 m_pTextFrame = pFrame->IsTextFrame() ? static_cast<SwTextFrame*>(pFrame) : nullptr;
787 if (m_pTextFrame)
789 m_bOldLocked = m_pTextFrame->IsLocked();
790 m_pTextFrame->Lock();
792 else
794 m_bOldLocked = false;
798 ~TextFrameLockGuard()
800 if (m_pTextFrame && !m_bOldLocked)
801 m_pTextFrame->Unlock();
805 inline const SwParaPortion *SwTextFrame::GetPara() const
807 return const_cast<SwTextFrame*>(this)->GetPara();
810 inline bool SwTextFrame::HasPara() const
812 return mnCacheIndex!=USHRT_MAX && HasPara_();
815 inline SwTwips SwTextFrame::GrowTst( const SwTwips nGrow )
817 return Grow( nGrow, true );
820 inline bool SwTextFrame::IsInside(TextFrameIndex const nPos) const
822 bool bRet = true;
823 if( nPos < GetOffset() )
824 bRet = false;
825 else
827 const SwTextFrame *pFoll = GetFollow();
828 if( pFoll && nPos >= pFoll->GetOffset() )
829 bRet = false;
831 return bRet;
834 inline SwTwips SwTextFrame::GetFootnoteFrameHeight() const
836 if( !IsFollow() && IsInFootnote() && HasPara() )
837 return GetFootnoteFrameHeight_();
838 else
839 return 0;
842 inline const SwTextFrame *SwTextFrame::GetFollow() const
844 return static_cast<const SwTextFrame*>(SwContentFrame::GetFollow());
846 inline SwTextFrame *SwTextFrame::GetFollow()
848 return static_cast<SwTextFrame*>(SwContentFrame::GetFollow());
851 inline const SwTextFrame *SwTextFrame::GetFrameAtPos( const SwPosition &rPos) const
853 return const_cast<SwTextFrame*>(this)->GetFrameAtPos( rPos );
856 inline void SwTextFrame::SetOffset(TextFrameIndex const nNewOfst)
858 if ( mnOffset != nNewOfst )
859 SetOffset_( nNewOfst );
862 inline void SwTextFrame::SetRepaint() const
864 const_cast<SwTextFrame*>(this)->mbRepaint = true;
866 inline void SwTextFrame::ResetRepaint() const
868 const_cast<SwTextFrame*>(this)->mbRepaint = false;
871 class TemporarySwap {
872 protected:
873 explicit TemporarySwap(SwTextFrame * frame, bool swap):
874 m_frame(frame), m_undo(false)
876 if (m_frame->IsVertical() && swap) {
877 m_undo = true;
878 m_frame->SwapWidthAndHeight();
882 ~TemporarySwap() {
883 if (m_undo) {
884 m_frame->SwapWidthAndHeight();
888 private:
889 TemporarySwap(TemporarySwap const &) = delete;
890 void operator =(TemporarySwap const &) = delete;
892 SwTextFrame * m_frame;
893 bool m_undo;
896 class SwSwapIfSwapped: private TemporarySwap {
897 public:
898 explicit SwSwapIfSwapped(SwTextFrame* frame):
899 TemporarySwap(frame, frame->IsSwapped()) {}
902 class SwSwapIfNotSwapped: private TemporarySwap {
903 public:
904 explicit SwSwapIfNotSwapped(SwTextFrame* frame):
905 TemporarySwap(frame, !frame->IsSwapped()) {}
909 * Helper class which can be used instead of the macros if a function
910 * has too many returns
912 class SwFrameSwapper
914 const SwTextFrame* pFrame;
915 bool bUndo;
916 public:
917 SwFrameSwapper( const SwTextFrame* pFrame, bool bSwapIfNotSwapped );
918 ~SwFrameSwapper();
921 class SwLayoutModeModifier
923 const OutputDevice& m_rOut;
924 ComplexTextLayoutFlags m_nOldLayoutMode;
925 public:
926 SwLayoutModeModifier( const OutputDevice& rOutp );
927 ~SwLayoutModeModifier();
928 void Modify( bool bChgToRTL );
929 void SetAuto();
932 class SwDigitModeModifier
934 const OutputDevice& rOut;
935 LanguageType nOldLanguageType;
936 public:
937 SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang );
938 ~SwDigitModeModifier();
941 namespace sw {
944 * Describes parts of multiple text nodes, which will form a text frame, even
945 * when redlines are hidden at a layout level.
947 struct MergedPara
949 sw::WriterMultiListener listener;
950 std::vector<Extent> extents;
951 /// note: cannot be const currently to avoid UB because SwTextGuess::Guess
952 /// const_casts it and modifies it (also, Update will modify it)
953 OUString mergedText;
954 /// most paragraph properties are taken from the first non-empty node
955 SwTextNode * pParaPropsNode;
956 /// except break attributes, those are taken from the first node
957 SwTextNode *const pFirstNode;
958 /// mainly for sanity checks
959 SwTextNode const* pLastNode;
960 MergedPara(SwTextFrame & rFrame, std::vector<Extent>&& rExtents,
961 OUString const& rText,
962 SwTextNode *const pProps, SwTextNode *const pFirst,
963 SwTextNode const*const pLast)
964 : listener(rFrame), extents(std::move(rExtents)), mergedText(rText)
965 , pParaPropsNode(pProps), pFirstNode(pFirst), pLastNode(pLast)
967 assert(pParaPropsNode);
968 assert(pFirstNode);
969 assert(pLastNode);
973 /// iterate SwTextAttr in potentially merged text frame
974 class MergedAttrIterBase
976 protected:
977 #if BOOST_VERSION < 105600
978 sw::MergedPara const* m_pMerged;
979 SwTextNode const* m_pNode;
980 #else
981 sw::MergedPara const*const m_pMerged;
982 SwTextNode const*const m_pNode;
983 #endif
984 size_t m_CurrentExtent;
985 size_t m_CurrentHint;
986 MergedAttrIterBase(SwTextFrame const& rFrame);
989 class MergedAttrIter
990 : public MergedAttrIterBase
992 public:
993 MergedAttrIter(SwTextFrame const& rFrame) : MergedAttrIterBase(rFrame) {}
994 SwTextAttr const* NextAttr(SwTextNode const** ppNode = nullptr);
997 class MergedAttrIterByEnd
999 private:
1000 std::vector<std::pair<SwTextNode const*, SwTextAttr const*>> m_Hints;
1001 SwTextNode const*const m_pNode;
1002 size_t m_CurrentHint;
1003 public:
1004 MergedAttrIterByEnd(SwTextFrame const& rFrame);
1005 SwTextAttr const* NextAttr(SwTextNode const*& rpNode);
1006 void PrevAttr();
1009 class MergedAttrIterReverse
1010 : public MergedAttrIterBase
1012 public:
1013 MergedAttrIterReverse(SwTextFrame const& rFrame);
1014 SwTextAttr const* PrevAttr(SwTextNode const** ppNode = nullptr);
1018 const SwTwips WIDOW_MAGIC = (SAL_MAX_INT32 - 1)/2;
1020 } // namespace sw
1022 #endif
1024 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */