summaryrefslogtreecommitdiffstats
path: root/sw/source/core/inc/txtfrm.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/inc/txtfrm.hxx')
-rw-r--r--sw/source/core/inc/txtfrm.hxx1032
1 files changed, 1032 insertions, 0 deletions
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
new file mode 100644
index 000000000..0ff2321bc
--- /dev/null
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -0,0 +1,1032 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_CORE_INC_TXTFRM_HXX
+#define INCLUDED_SW_SOURCE_CORE_INC_TXTFRM_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include "cntfrm.hxx"
+#include "TextFrameIndex.hxx"
+#include <nodeoffset.hxx>
+
+#include <set>
+
+namespace com::sun::star::linguistic2 { class XHyphenatedWord; }
+
+namespace sw::mark { class IMark; }
+class SwCharRange;
+class SwInsText;
+class SwTextNode;
+class SwTextAttrEnd;
+class SwTextFormatter;
+class SwTextFormatInfo;
+class SwParaPortion;
+class WidowsAndOrphans;
+class SwTextFootnote;
+class SwInterHyphInfo; // Hyphenate()
+class SwCache;
+class SwBorderAttrs;
+class SwFrameFormat;
+struct SwCursorMoveState;
+struct SwFillData;
+class SwPortionHandler;
+class SwScriptInfo;
+enum class ExpandMode;
+class SwTextAttr;
+class SwWrtShell;
+
+#define NON_PRINTING_CHARACTER_COLOR Color(0x26, 0x8b, 0xd2)
+
+/// a clone of SwInterHyphInfo, but with TextFrameIndex instead of node index
+class SwInterHyphInfoTextFrame
+{
+private:
+ /// output: hyphenated word
+ css::uno::Reference<css::linguistic2::XHyphenatedWord> m_xHyphWord;
+public:
+ /// input: requested range to hyphenate
+ TextFrameIndex m_nStart;
+ TextFrameIndex m_nEnd;
+ /// output: found word
+ TextFrameIndex m_nWordStart;
+ TextFrameIndex m_nWordLen;
+
+ SwInterHyphInfoTextFrame(SwTextFrame const& rFrame,
+ SwTextNode const& rNode, SwInterHyphInfo const& rHyphInfo);
+ void UpdateTextNodeHyphInfo(SwTextFrame const& rFrame,
+ SwTextNode const& rNode, SwInterHyphInfo & o_rHyphInfo);
+
+ void SetHyphWord(const css::uno::Reference<css::linguistic2::XHyphenatedWord> &xHW)
+ {
+ m_xHyphWord = xHW;
+ }
+};
+
+namespace sw {
+
+/**
+ * Describes a part of a single text node, which will be part of a text frame,
+ * even when redlines are hidden at a layout level.
+ */
+struct Extent
+{
+ SwTextNode * /*const logically, but need assignment for std::vector*/ pNode;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+ Extent(SwTextNode *const p, sal_Int32 const s, sal_Int32 const e)
+ : pNode(p), nStart(s), nEnd(e)
+ {
+ assert(pNode);
+ assert(nStart != nEnd);
+ }
+};
+
+struct MergedPara;
+
+std::pair<SwTextNode*, sal_Int32> MapViewToModel(MergedPara const&, TextFrameIndex nIndex);
+TextFrameIndex MapModelToView(MergedPara const&, SwTextNode const* pNode, sal_Int32 nIndex);
+
+// warning: Existing must be used only once; a second use would delete the frame created by the first one...
+enum class FrameMode { New, Existing };
+std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, FrameMode eMode);
+SwTextFrame * MakeTextFrame(SwTextNode & rNode, SwFrame *, sw::FrameMode eMode);
+
+bool FrameContainsNode(SwContentFrame const& rFrame, SwNodeOffset nNodeIndex);
+bool IsParaPropsNode(SwRootFrame const& rLayout, SwTextNode const& rNode);
+SwTextNode * GetParaPropsNode(SwRootFrame const& rLayout, SwNodeIndex const& rNode);
+SwPosition GetParaPropsPos(SwRootFrame const& rLayout, SwPosition const& rPos);
+std::pair<SwTextNode *, SwTextNode *>
+GetFirstAndLastNode(SwRootFrame const& rLayout, SwNodeIndex const& rPos);
+
+SwTextNode const& GetAttrMerged(SfxItemSet & rFormatSet,
+ SwTextNode const& rNode, SwRootFrame const* pLayout);
+
+void GotoPrevLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const* pLayout);
+void GotoNextLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const* pLayout);
+
+TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
+ bool isRealDelete,
+ SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen);
+
+void MoveMergedFlysAndFootnotes(std::vector<SwTextFrame*> const& rFrames,
+ SwTextNode const& rFirstNode, SwTextNode & rSecondNode, bool);
+
+void MoveDeletedPrevFrames(const SwTextNode & rDeletedPrev, SwTextNode & rNode);
+enum class Recreate { No, ThisNode, Predecessor };
+void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate eRecreateMerged);
+
+void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
+void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
+
+void AddRemoveFlysAnchoredToFrameStartingAtNode(
+ SwTextFrame & rFrame, SwTextNode & rTextNode,
+ std::set<SwNodeOffset> *pSkipped);
+
+OUString GetExpandTextMerged(SwRootFrame const* pLayout,
+ SwTextNode const& rNode, bool bWithNumber,
+ bool bWithSpacesForLevel, ExpandMode i_mode);
+
+bool IsMarkHidden(SwRootFrame const& rLayout, ::sw::mark::IMark const& rMark);
+bool IsMarkHintHidden(SwRootFrame const& rLayout,
+ SwTextNode const& rNode, SwTextAttrEnd const& rHint);
+
+void RecreateStartTextFrames(SwTextNode & rNode);
+
+auto MakeSwInsText(SwTextNode & rNode, sal_Int32 nPos, sal_Int32 nLen) -> SwInsText;
+
+/**
+ * Decides if rTextNode has a numbering which has layout-level values (e.g. Arabic, but not
+ * none or bullets).
+ */
+bool HasNumberingWhichNeedsLayoutUpdate(const SwTextNode& rTextNode);
+
+} // namespace sw
+
+/// Represents the visualization of a paragraph. Typical upper is an
+/// SwBodyFrame. The first text portion of the first line is az SwParaPortion.
+class SW_DLLPUBLIC SwTextFrame final : public SwContentFrame
+{
+ friend class SwTextIter;
+ friend class SwTestFormat;
+ friend class WidowsAndOrphans;
+ friend class TextFrameLockGuard; // May Lock()/Unlock()
+ friend bool sw_ChangeOffset(SwTextFrame* pFrame, TextFrameIndex nNew);
+
+ /// SwLineLayout cache: the lines are not actually owned by the SwTextFrame
+ /// but by this SwCache, so they will be deleted in large documents
+ /// if there are too many of them, but the "valid" flags of the frame
+ /// will still be set; GetFormatted() is the function that forces
+ /// recreation of the SwLineLayout by Format() if necessary.
+ static SwCache *s_pTextCache;
+ static constexpr tools::Long nMinPrtLine = 0; // This Line must not be underrun when printing
+ // Hack for table cells stretching multiple pages
+
+ sal_uInt32 mnAllLines :24; // Line count for the Paint (including nThisLines)
+ sal_uInt32 mnThisLines :8; // Count of Lines of the Frame
+
+ // The x position for flys anchored at this paragraph.
+ // These values are calculated in SwTextFrame::CalcBaseOfstForFly()
+ SwTwips mnFlyAnchorOfst;
+ // The x position for wrap-through flys anchored at this paragraph.
+ SwTwips mnFlyAnchorOfstNoWrap;
+ /// The y position for wrap-through flys anchored at this paragraph.
+ SwTwips mnFlyAnchorVertOfstNoWrap;
+ SwTwips mnFootnoteLine;
+ // OD 2004-03-17 #i11860# - re-factoring of #i11859#
+ // member for height of last line (value needed for proportional line spacing)
+ SwTwips mnHeightOfLastLine;
+ // member for the additional first line offset, which is caused by the list
+ // label alignment for list level position and space mode LABEL_ALIGNMENT.
+ // This additional first line offset is used for the text formatting.
+ // It is NOT used for the determination of printing area.
+ SwTwips mnAdditionalFirstLineOffset;
+
+ /// redline merge data
+ std::unique_ptr<sw::MergedPara> m_pMergedPara;
+
+ TextFrameIndex mnOffset; // Is the offset in the Content (character count)
+
+ sal_uInt16 mnCacheIndex; // Index into the cache, USHRT_MAX if there's definitely no fitting object in the cache
+
+ // Separates the Master and creates a Follow or adjusts the data in the Follow
+ void AdjustFollow_( SwTextFormatter &rLine, TextFrameIndex nOffset,
+ TextFrameIndex nStrEnd, const sal_uInt8 nMode );
+
+ // Iterates all Lines and sets the line spacing using the attribute
+ void CalcLineSpace();
+
+ // Only called in Format
+ void AdjustFrame( const SwTwips nChgHeight, bool bHasToFit = false );
+
+ // Evaluates the Preps in Format()
+ bool CalcPreps();
+ void PrepWidows( const sal_uInt16 nNeed, bool bNotify );
+ void InvalidateRange_( const SwCharRange &, const tools::Long = 0);
+ inline void InvalidateRange( const SwCharRange &, const tools::Long = 0);
+
+ // WidowsAndOrphans, AdjustFrame, AdjustFollow
+ void FormatAdjust( SwTextFormatter &rLine, WidowsAndOrphans &rFrameBreak,
+ TextFrameIndex nStrLen, const bool bDummy );
+ void ChangeOffset( SwTextFrame* pFrame, TextFrameIndex nNew );
+
+ bool mbLocked : 1; // In the Format?
+ bool mbWidow : 1; // Is our follow a Widow?
+ bool mbJustWidow : 1; // Did we just request Widow flag on master?
+ bool mbEmpty : 1; // Are we an empty paragraph?
+ bool mbInFootnoteConnect : 1; // Is in Connect at the moment
+ bool mbFootnote : 1; // Has at least one footnote
+ bool mbRepaint : 1; // TextFrame: Repaint is ready to be fetched
+ /// Contains rotated portions.
+ bool mbHasRotatedPortions : 1;
+ bool mbFieldFollow : 1; // Start with Field rest of the Master
+ bool mbHasAnimation : 1; // Contains animated SwGrfNumPortion
+ bool mbIsSwapped : 1; // during text formatting we swap the
+ // width and height for vertical formatting
+ // OD 14.03.2003 #i11760# - flag to control, if follow is formatted in
+ // method <CalcFollow(..)>.
+ // E.g., avoid formatting of follow, if method <SwLayoutFrame::FormatWidthCols(..)>
+ // is running.
+ bool mbFollowFormatAllowed : 1;
+
+ void ResetPreps();
+ void Lock() { mbLocked = true; }
+ void Unlock() { mbLocked = false; }
+ void SetWidow( const bool bNew ) { mbWidow = bNew; }
+ void SetJustWidow( const bool bNew ) { mbJustWidow = bNew; }
+ void SetEmpty( const bool bNew ) { mbEmpty = bNew; }
+ void SetFieldFollow( const bool bNew ) { mbFieldFollow = bNew; }
+
+ bool IsIdxInside(TextFrameIndex nPos, TextFrameIndex nLen) const;
+
+ // Changes the Frame or not (cf. FlyCnt)
+ bool GetModelPositionForViewPoint_(SwPosition *pPos, const Point &rPoint,
+ const bool bChgFrame, SwCursorMoveState* = nullptr ) const;
+ void FillCursorPos( SwFillData &rFill ) const;
+
+ // Format exactly one Line
+ bool FormatLine( SwTextFormatter &rLine, const bool bPrev );
+
+ // In order to safe stack space, we split this method:
+ // Format_ calls Format_ with parameters
+ void Format_( vcl::RenderContext* pRenderContext, SwParaPortion *pPara );
+ void Format_( SwTextFormatter &rLine, SwTextFormatInfo &rInf,
+ const bool bAdjust = false );
+ void FormatOnceMore( SwTextFormatter &rLine, SwTextFormatInfo &rInf );
+
+ // Formats the Follow and ensures disposing on orphans
+ bool CalcFollow(TextFrameIndex nTextOfst);
+
+ virtual void MakePos() override;
+
+ // Corrects the position from which we need to format
+ static TextFrameIndex FindBrk(const OUString &rText, TextFrameIndex nStart,
+ TextFrameIndex nEnd);
+
+ // inline branch
+ SwTwips GetFootnoteFrameHeight_() const;
+
+ // Outsourced to CalcPreps
+ bool CalcPrepFootnoteAdjust();
+
+ // For Footnote and WidOrp: Forced validation
+ void ValidateFrame();
+ void ValidateBodyFrame();
+
+ bool GetDropRect_( SwRect &rRect ) const;
+
+ void SetPara( SwParaPortion *pNew, bool bDelete = true );
+
+ bool IsFootnoteNumFrame_() const;
+
+ // Refresh formatting information
+ bool FormatQuick( bool bForceQuickFormat );
+
+ // Opt: Format empty paragraphs
+ bool FormatEmpty();
+ SwTwips EmptyHeight() const;
+
+ // Opt: Paint empty paragraphs
+ bool PaintEmpty( const SwRect &, bool bCheck ) const;
+
+ void ChgThisLines(); // Must always be called if the Line count could have changed
+
+ // required for 'new' relative anchor position
+ void CalcBaseOfstForFly();
+
+ /** method to determine height of last line, needed for proportional line spacing
+
+ OD 2004-03-17 #i11860#
+ OD 2005-05-20 #i47162# - introduce new optional parameter <_bUseFont>
+ in order to force the usage of the former algorithm to determine the
+ height of the last line, which uses the font.
+
+ @param _bUseFont
+ optional input parameter - boolean indicating, if the font has to be
+ used to determine the height of the last line. default value: false
+ */
+ void CalcHeightOfLastLine( const bool _bUseFont = false );
+
+ virtual void DestroyImpl() override;
+ virtual ~SwTextFrame() override;
+
+ void UpdateOutlineContentVisibilityButton(SwWrtShell* pWrtSh) const;
+ void PaintOutlineContentVisibilityButton() const;
+
+ virtual void SwClientNotify(SwModify const& rModify, SfxHint const& rHint) override;
+
+public:
+
+ virtual const SvxFormatBreakItem& GetBreakItem() const override;
+ virtual const SwFormatPageDesc& GetPageDescItem() const override;
+
+ css::uno::Sequence< css::style::TabStop > GetTabStopInfo( SwTwips CurrentPos ) override;
+
+ /**
+ * This is public, as it needs to be called by some methods in order to save the Prepare
+ * USE WITH CAUTION!
+ */
+ void Init();
+
+ /// Is called by DoIdleJob_(), ExecSpellPopup() and UpDown()
+ SwRect AutoSpell_(SwTextNode &, sal_Int32);
+
+ /// Is called by DoIdleJob_()
+ SwRect SmartTagScan(SwTextNode &);
+
+ /// Is called by DoIdleJob_()
+ void CollectAutoCmplWrds(SwTextNode &, sal_Int32);
+
+ /**
+ * Returns the view rectangle for the rPos model position. The values are relative to the upper
+ * left position of the page frame.
+ * Additional information can be obtained by passing an SwCursorMoveState object.
+ * Returns false if rPos > number of character is string
+ */
+ virtual bool GetCharRect( SwRect& rRect, const SwPosition& rPos,
+ SwCursorMoveState* pCMS = nullptr, bool bAllowFarAway = true ) const override;
+
+ /// A slimmer version of GetCharRect for autopositioning Frames
+ bool GetAutoPos( SwRect &, const SwPosition& ) const;
+
+ /**
+ * Determine top of line for given position in the text frame
+ *
+ * OD 11.11.2003 #i22341#
+ * Assumption: given position exists in the text frame or in a follow of it
+ * OD 2004-02-02 - adjustment
+ * Top of first paragraph line is the top of the paragraph.
+ * OD 2004-03-18 #i11860# - Consider upper space amount considered for
+ * previous frame and the page grid.
+ *
+ * @param _onTopOfLine
+ * output parameter - top of line, if the given position is found in the
+ * text frame.
+ *
+ * @param _rPos
+ * input parameter - reference to the position in the text frame
+ *
+ * @return boolean indicating, if the top of line for the given position
+ * has been determined or not.
+ */
+ bool GetTopOfLine( SwTwips& _onTopOfLine,
+ const SwPosition& _rPos ) const;
+
+ virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const override;
+
+ /**
+ * In nOffset returns the offset of the char within the set
+ * text buffer, which is closest to the position provided by
+ * aPoint within the layout's SSize.
+ *
+ * @returns false if the SPoint is outside of the SSize else
+ * returns true
+ */
+ virtual bool GetModelPositionForViewPoint( SwPosition *, Point&,
+ SwCursorMoveState* = nullptr, bool bTestBackground = false ) const override;
+
+ /**
+ * Makes sure that the Frame is not switched (e.g. switched for a
+ * character-bound Frame)
+ */
+ bool GetKeyCursorOfst(SwPosition *pPos, const Point &rPoint ) const
+ { return GetModelPositionForViewPoint_( pPos, rPoint, false ); }
+
+ void PaintExtraData( const SwRect & rRect ) const; /// Page number etc.
+ SwRect GetPaintSwRect();
+ virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&,
+ SwPrintData const*const pPrintData = nullptr ) const override;
+ virtual bool GetInfo( SfxPoolItem & ) const override;
+
+ /**
+ * Layout oriented cursor travelling:
+ * Left border, right border, previous Line, following Line,
+ * same horizontal position
+ */
+ virtual bool LeftMargin(SwPaM *) const override;
+ virtual bool RightMargin(SwPaM *, bool bAPI = false) const override;
+
+ virtual bool UnitUp(SwPaM *, const SwTwips nOffset,
+ bool bSetInReadOnly ) const override;
+ virtual bool UnitDown(SwPaM *, const SwTwips nOffset,
+ bool bSetInReadOnly ) const override;
+ bool UnitUp_(SwPaM *, const SwTwips nOffset,
+ bool bSetInReadOnly ) const;
+ bool UnitDown_(SwPaM *, const SwTwips nOffset,
+ bool bSetInReadOnly ) const;
+
+ /**
+ * Prepares the cursor position for a visual cursor move (BiDi).
+ * The behaviour is different for insert and overwrite cursors
+ */
+ void PrepareVisualMove( TextFrameIndex& nPos, sal_uInt8& nCursorLevel,
+ bool& bRight, bool bInsertCursor );
+
+ /// Methods to manage the FollowFrame
+ void SplitFrame(TextFrameIndex nTextPos);
+ SwContentFrame *JoinFrame();
+ TextFrameIndex GetOffset() const { return mnOffset; }
+ void SetOffset_(TextFrameIndex nNewOfst);
+ inline void SetOffset (TextFrameIndex nNewOfst);
+ void ManipOfst(TextFrameIndex const nNewOfst) { mnOffset = nNewOfst; }
+ SwTextFrame *GetFrameAtPos ( const SwPosition &rPos);
+ inline const SwTextFrame *GetFrameAtPos ( const SwPosition &rPos) const;
+ SwTextFrame& GetFrameAtOfst(TextFrameIndex nOfst);
+ /// If there's a Follow and we don't contain text ourselves
+ bool IsEmptyMaster() const
+ { return GetFollow() && !GetFollow()->GetOffset(); }
+
+ void SetMergedPara(std::unique_ptr<sw::MergedPara> p);
+ sw::MergedPara * GetMergedPara() { return m_pMergedPara.get(); }
+ sw::MergedPara const* GetMergedPara() const { return m_pMergedPara.get(); }
+
+ /// Returns the text portion we want to edit (for inline see underneath)
+ const OUString& GetText() const;
+ SwTextNode const* GetTextNodeForParaProps() const;
+ SwTextNode const* GetTextNodeForFirstText() const;
+ SwTextNode * GetTextNodeFirst()
+ { return const_cast<SwTextNode*>(const_cast<SwTextFrame const*>(this)->GetTextNodeFirst()); };
+ SwTextNode const* GetTextNodeFirst() const;
+ SwDoc & GetDoc()
+ { return const_cast<SwDoc &>(const_cast<SwTextFrame const*>(this)->GetDoc()); }
+ SwDoc const& GetDoc() const;
+
+ SwTextFrame(SwTextNode * const, SwFrame*, sw::FrameMode eMode);
+
+ /**
+ * SwContentFrame: the shortcut for the Frames
+ * If the void* casts wrongly, it's its own fault!
+ * The void* must be checked for 0 in any case!
+ *
+ * return true if the Portion associated with this SwTextFrame was
+ * potentially destroyed and replaced by Prepare
+ */
+ virtual bool Prepare( const PrepareHint ePrep = PrepareHint::Clear,
+ const void *pVoid = nullptr, bool bNotify = true ) override;
+
+ /**
+ * nMaxHeight is the required height
+ * bSplit indicates, that the paragraph has to be split
+ * bTst indicates, that we are currently doing a test formatting
+ */
+ virtual bool WouldFit(SwTwips &nMaxHeight, bool &bSplit, bool bTst, bool bMoveBwd) override;
+
+ /**
+ * The WouldFit equivalent for temporarily rewired TextFrames
+ * nMaxHeight returns the required size here too and bSplit
+ * determines whether the paragraph needs to be split.
+ * We pass the potential predecessor for the distance calculation
+ */
+ bool TestFormat( const SwFrame* pPrv, SwTwips &nMaxHeight, bool &bSplit );
+
+ /**
+ * We format a Line for interactive hyphenation
+ * @return found
+ */
+ bool Hyphenate(SwInterHyphInfoTextFrame & rInf);
+
+ /// Test grow
+ inline SwTwips GrowTst( const SwTwips nGrow );
+
+ SwParaPortion *GetPara();
+ inline const SwParaPortion *GetPara() const;
+ inline bool HasPara() const;
+ bool HasPara_() const;
+
+ /// map position in potentially merged text frame to SwPosition
+ std::pair<SwTextNode*, sal_Int32> MapViewToModel(TextFrameIndex nIndex) const;
+ SwPosition MapViewToModelPos(TextFrameIndex nIndex) const;
+ TextFrameIndex MapModelToView(SwTextNode const* pNode, sal_Int32 nIndex) const;
+ TextFrameIndex MapModelToViewPos(SwPosition const& rPos) const;
+
+ // If there are any hanging punctuation portions in the margin
+ // the offset will be returned.
+ SwTwips HangingMargin() const;
+
+ // Locking
+ bool IsLocked() const { return mbLocked; }
+
+ bool IsWidow() const { return mbWidow; }
+ bool IsJustWidow() const { return mbJustWidow; }
+ bool IsEmpty() const { return mbEmpty; }
+ bool HasFootnote() const { return mbFootnote; }
+ bool IsInFootnoteConnect()const { return mbInFootnoteConnect;}
+ bool IsFieldFollow() const { return mbFieldFollow;}
+
+ inline void SetRepaint() const;
+ inline void ResetRepaint() const;
+ bool HasRepaint() const { return mbRepaint; }
+ void SetHasRotatedPortions(bool bHasRotatedPortions);
+ bool GetHasRotatedPortions() const { return mbHasRotatedPortions; }
+ void SetAnimation() const
+ { const_cast<SwTextFrame*>(this)->mbHasAnimation = true; }
+ bool HasAnimation() const { return mbHasAnimation; }
+
+ bool IsSwapped() const { return mbIsSwapped; }
+
+ /// Does the Frame have a local footnote (in this Frame or Follow)?
+#ifdef DBG_UTIL
+ void CalcFootnoteFlag(TextFrameIndex nStop = TextFrameIndex(COMPLETE_STRING)); //For testing SplitFrame
+#else
+ void CalcFootnoteFlag();
+#endif
+
+ /// Hidden
+ bool IsHiddenNow() const; // bHidden && pOut == pPrt
+ void HideHidden(); // Remove appendage if Hidden
+ void HideFootnotes(TextFrameIndex nStart, TextFrameIndex nEnd);
+
+ /**
+ * Hides respectively shows objects, which are anchored at paragraph,
+ * at/as a character of the paragraph, corresponding to the paragraph and
+ * paragraph portion visibility.
+ */
+ void HideAndShowObjects();
+
+ /// Footnote
+ void RemoveFootnote(TextFrameIndex nStart,
+ TextFrameIndex nLen = TextFrameIndex(COMPLETE_STRING));
+ inline SwTwips GetFootnoteFrameHeight() const;
+ SwTextFrame *FindFootnoteRef( const SwTextFootnote *pFootnote );
+ const SwTextFrame *FindFootnoteRef( const SwTextFootnote *pFootnote ) const
+ { return const_cast<SwTextFrame *>(this)->FindFootnoteRef( pFootnote ); }
+ void ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDeadLine );
+
+ /**
+ * If we're a Footnote that grows towards its reference ...
+ * public, because it's needed by SwContentFrame::MakeAll
+ */
+ SwTwips GetFootnoteLine( const SwTextFootnote *pFootnote ) const;
+
+ TextFrameIndex GetDropLen(TextFrameIndex nWishLen) const;
+
+ LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript,
+ bool bNoChar = false) const;
+
+ virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
+ virtual void CheckDirection( bool bVert ) override;
+
+ /// Returns the sum of line height in pLine
+ SwTwips GetParHeight() const;
+
+ inline SwTextFrame *GetFollow();
+ inline const SwTextFrame *GetFollow() const;
+
+ /// Find the page number of ErgoSum and QuoVadis
+ SwTextFrame *FindQuoVadisFrame();
+
+ /**
+ * In case the SwLineLayout was cleared out of the s_pTextCache, recreate it
+ *
+ * #i29062# GetFormatted() can trigger a full formatting
+ * of the paragraph, causing other layout frames to become invalid. This
+ * has to be avoided during painting. Therefore we need to pass the
+ * information that we are currently in the paint process.
+ */
+ SwTextFrame* GetFormatted( bool bForceQuickFormat = false );
+
+ /// Will be moved soon
+ void SetFootnote( const bool bNew ) { mbFootnote = bNew; }
+
+ /// Respect the Follows
+ inline bool IsInside(TextFrameIndex nPos) const;
+
+ /// DropCaps and selections
+ bool GetDropRect( SwRect &rRect ) const
+ { return HasPara() && GetDropRect_( rRect ); }
+
+ static SwCache *GetTextCache() { return s_pTextCache; }
+ static void SetTextCache( SwCache *pNew ) { s_pTextCache = pNew; }
+
+ static tools::Long GetMinPrtLine() { return nMinPrtLine; }
+
+ sal_uInt16 GetCacheIdx() const { return mnCacheIndex; }
+ void SetCacheIdx( const sal_uInt16 nNew ) { mnCacheIndex = nNew; }
+
+ /// Removes the Line information from the Cache but retains the entry itself
+ void ClearPara();
+ /// Removes this frame completely from the Cache
+ void RemoveFromCache();
+
+ /// Am I a FootnoteFrame, with a number at the start of the paragraph?
+ bool IsFootnoteNumFrame() const
+ { return IsInFootnote() && !GetIndPrev() && IsFootnoteNumFrame_(); }
+
+ /**
+ * Simulates a formatting as if there were not right margin or Flys or other
+ * obstacles and returns the width
+ */
+ SwTwips CalcFitToContent();
+
+ /**
+ * Simulate format for a list item paragraph, whose list level attributes
+ * are in LABEL_ALIGNMENT mode, in order to determine additional first
+ * line offset for the real text formatting due to the value of label
+ * adjustment attribute of the list level.
+ */
+ void CalcAdditionalFirstLineOffset();
+
+ SwTwips GetAdditionalFirstLineOffset() const
+ {
+ return mnAdditionalFirstLineOffset;
+ }
+
+ /**
+ * Returns the additional line spacing for the next paragraph
+ * @param _bNoPropLineSpacing: control, whether the value of a
+ * proportional line spacing is returned or not
+ */
+ tools::Long GetLineSpace( const bool _bNoPropLineSpacing = false ) const;
+
+ /// Returns the first line height
+ sal_uInt16 FirstLineHeight() const;
+
+ /// Rewires FlyInContentFrame, if nEnd > Index >= nStart
+ void MoveFlyInCnt(SwTextFrame *pNew, TextFrameIndex nStart, TextFrameIndex nEnd);
+
+ /// Calculates the position of FlyInContentFrames
+ TextFrameIndex CalcFlyPos( SwFrameFormat const * pSearch );
+
+ /// Determines the start position and step size of the register
+ bool FillRegister( SwTwips& rRegStart, sal_uInt16& rRegDiff );
+
+ /// Determines the line count
+ sal_uInt16 GetLineCount(TextFrameIndex nPos);
+
+ /// For displaying the line numbers
+ sal_uLong GetAllLines() const { return mnAllLines; }
+ sal_uLong GetThisLines() const { return mnThisLines;}
+ void RecalcAllLines();
+
+ /// Stops the animations within numberings
+ void StopAnimation( const OutputDevice *pOut );
+
+ /// Visit all portions for Accessibility
+ void VisitPortions( SwPortionHandler& rPH ) const;
+
+ /// Returns the script info stored at the paraportion
+ const SwScriptInfo* GetScriptInfo() const;
+
+ /// Swaps width and height of the text frame
+ void SwapWidthAndHeight();
+
+ /**
+ * Calculates the coordinates of a rectangle when switching from
+ * horizontal to vertical layout
+ */
+ void SwitchHorizontalToVertical( SwRect& rRect ) const;
+
+ /**
+ * Calculates the coordinates of a point when switching from
+ * horizontal to vertical layout
+ */
+ void SwitchHorizontalToVertical( Point& rPoint ) const;
+
+ /**
+ * Calculates the limit value when switching from
+ * horizontal to vertical layout
+ */
+ tools::Long SwitchHorizontalToVertical( tools::Long nLimit ) const;
+
+ /**
+ * Calculates the coordinates of a rectangle when switching from
+ * vertical to horizontal layout
+ */
+ void SwitchVerticalToHorizontal( SwRect& rRect ) const;
+
+ /**
+ * Calculates the coordinates of a point when switching from
+ * vertical to horizontal layout
+ */
+ void SwitchVerticalToHorizontal( Point& rPoint ) const;
+
+ /**
+ * Calculates the a limit value when switching from
+ * vertical to horizontal layout
+ */
+ tools::Long SwitchVerticalToHorizontal( tools::Long nLimit ) const;
+
+ /**
+ * Calculates the coordinates of a rectangle when switching from
+ * LTR to RTL layout
+ */
+ void SwitchLTRtoRTL( SwRect& rRect ) const;
+
+ /**
+ * Calculates the coordinates of a point when switching from
+ * LTR to RTL layout
+ */
+ void SwitchLTRtoRTL( Point& rPoint ) const;
+
+ /**
+ * Calculates the coordinates of a rectangle when switching from
+ * RTL to LTR layout
+ */
+ void SwitchRTLtoLTR( SwRect& rRect ) const { SwitchLTRtoRTL( rRect ); }
+
+ /**
+ * Calculates the coordinates of a point when switching from
+ * RTL to LTR layout
+ */
+ void SwitchRTLtoLTR( Point& rPoint ) const { SwitchLTRtoRTL( rPoint ); };
+
+ bool FollowFormatAllowed() const
+ {
+ return mbFollowFormatAllowed;
+ }
+
+ void AllowFollowFormat()
+ {
+ mbFollowFormatAllowed = true;
+ }
+
+ void ForbidFollowFormat()
+ {
+ mbFollowFormatAllowed = false;
+ }
+
+ SwTwips GetBaseOffsetForFly( bool bIgnoreFlysAnchoredAtThisFrame ) const
+ {
+ return ( bIgnoreFlysAnchoredAtThisFrame ?
+ mnFlyAnchorOfst :
+ mnFlyAnchorOfstNoWrap );
+ }
+
+ SwTwips GetBaseVertOffsetForFly(bool bIgnoreFlysAnchoredAtThisFrame) const;
+
+ SwTwips GetHeightOfLastLine() const
+ {
+ return mnHeightOfLastLine;
+ }
+
+ static void repaintTextFrames( const SwTextNode& rNode );
+
+ void RegisterToNode(SwTextNode &, bool isForceNodeAsFirst = false);
+
+ bool IsSymbolAt(TextFrameIndex) const;
+ OUString GetCurWord(SwPosition const&) const;
+ sal_uInt16 GetScalingOfSelectedText(TextFrameIndex nStt, TextFrameIndex nEnd);
+
+ virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override;
+};
+
+//use this to protect a SwTextFrame for a given scope from getting merged with
+//its neighbour and thus deleted
+class TextFrameLockGuard
+{
+private:
+ SwTextFrame *m_pTextFrame;
+ bool m_bOldLocked;
+public:
+ //Lock pFrame for the lifetime of the Cut/Paste call, etc. to avoid
+ //SwTextFrame::AdjustFollow_ removing the pFrame we're trying to Make
+ TextFrameLockGuard(SwFrame* pFrame)
+ {
+ m_pTextFrame = pFrame->IsTextFrame() ? static_cast<SwTextFrame*>(pFrame) : nullptr;
+ if (m_pTextFrame)
+ {
+ m_bOldLocked = m_pTextFrame->IsLocked();
+ m_pTextFrame->Lock();
+ }
+ else
+ {
+ m_bOldLocked = false;
+ }
+ }
+
+ ~TextFrameLockGuard()
+ {
+ if (m_pTextFrame && !m_bOldLocked)
+ m_pTextFrame->Unlock();
+ }
+};
+
+inline const SwParaPortion *SwTextFrame::GetPara() const
+{
+ return const_cast<SwTextFrame*>(this)->GetPara();
+}
+
+inline bool SwTextFrame::HasPara() const
+{
+ return mnCacheIndex!=USHRT_MAX && HasPara_();
+}
+
+inline SwTwips SwTextFrame::GrowTst( const SwTwips nGrow )
+{
+ return Grow( nGrow, true );
+}
+
+inline bool SwTextFrame::IsInside(TextFrameIndex const nPos) const
+{
+ bool bRet = true;
+ if( nPos < GetOffset() )
+ bRet = false;
+ else
+ {
+ const SwTextFrame *pFoll = GetFollow();
+ if( pFoll && nPos >= pFoll->GetOffset() )
+ bRet = false;
+ }
+ return bRet;
+}
+
+inline SwTwips SwTextFrame::GetFootnoteFrameHeight() const
+{
+ if( !IsFollow() && IsInFootnote() && HasPara() )
+ return GetFootnoteFrameHeight_();
+ else
+ return 0;
+}
+
+inline const SwTextFrame *SwTextFrame::GetFollow() const
+{
+ return static_cast<const SwTextFrame*>(SwContentFrame::GetFollow());
+}
+inline SwTextFrame *SwTextFrame::GetFollow()
+{
+ return static_cast<SwTextFrame*>(SwContentFrame::GetFollow());
+}
+
+inline const SwTextFrame *SwTextFrame::GetFrameAtPos( const SwPosition &rPos) const
+{
+ return const_cast<SwTextFrame*>(this)->GetFrameAtPos( rPos );
+}
+
+inline void SwTextFrame::SetOffset(TextFrameIndex const nNewOfst)
+{
+ if ( mnOffset != nNewOfst )
+ SetOffset_( nNewOfst );
+}
+
+inline void SwTextFrame::SetRepaint() const
+{
+ const_cast<SwTextFrame*>(this)->mbRepaint = true;
+}
+inline void SwTextFrame::ResetRepaint() const
+{
+ const_cast<SwTextFrame*>(this)->mbRepaint = false;
+}
+
+class TemporarySwap {
+protected:
+ explicit TemporarySwap(SwTextFrame * frame, bool swap):
+ m_frame(frame), m_undo(false)
+ {
+ if (m_frame->IsVertical() && swap) {
+ m_undo = true;
+ m_frame->SwapWidthAndHeight();
+ }
+ }
+
+ ~TemporarySwap() {
+ if (m_undo) {
+ m_frame->SwapWidthAndHeight();
+ }
+ }
+
+private:
+ TemporarySwap(TemporarySwap const &) = delete;
+ void operator =(TemporarySwap const &) = delete;
+
+ SwTextFrame * m_frame;
+ bool m_undo;
+};
+
+class SwSwapIfSwapped: private TemporarySwap {
+public:
+ explicit SwSwapIfSwapped(SwTextFrame* frame):
+ TemporarySwap(frame, frame->IsSwapped()) {}
+};
+
+class SwSwapIfNotSwapped: private TemporarySwap {
+public:
+ explicit SwSwapIfNotSwapped(SwTextFrame* frame):
+ TemporarySwap(frame, !frame->IsSwapped()) {}
+};
+
+/**
+ * Helper class which can be used instead of the macros if a function
+ * has too many returns
+ */
+class SwFrameSwapper
+{
+ const SwTextFrame* pFrame;
+ bool bUndo;
+public:
+ SwFrameSwapper( const SwTextFrame* pFrame, bool bSwapIfNotSwapped );
+ ~SwFrameSwapper();
+};
+
+class SwLayoutModeModifier
+{
+ const OutputDevice& m_rOut;
+ vcl::text::ComplexTextLayoutFlags m_nOldLayoutMode;
+public:
+ SwLayoutModeModifier( const OutputDevice& rOutp );
+ ~SwLayoutModeModifier();
+ void Modify( bool bChgToRTL );
+ void SetAuto();
+};
+
+class SwDigitModeModifier
+{
+ const OutputDevice& rOut;
+ LanguageType nOldLanguageType;
+public:
+ SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang );
+ ~SwDigitModeModifier();
+};
+
+namespace sw {
+
+/**
+ * Describes parts of multiple text nodes, which will form a text frame, even
+ * when redlines are hidden at a layout level.
+ */
+struct MergedPara
+{
+ sw::WriterMultiListener listener;
+ std::vector<Extent> extents;
+ /// note: cannot be const currently to avoid UB because SwTextGuess::Guess
+ /// const_casts it and modifies it (also, Update will modify it)
+ OUString mergedText;
+ /// most paragraph properties are taken from the first non-empty node
+ SwTextNode * pParaPropsNode;
+ /// except break attributes, those are taken from the first node
+ SwTextNode *const pFirstNode;
+ /// mainly for sanity checks
+ SwTextNode const* pLastNode;
+ MergedPara(SwTextFrame & rFrame, std::vector<Extent>&& rExtents,
+ OUString const& rText,
+ SwTextNode *const pProps, SwTextNode *const pFirst,
+ SwTextNode const*const pLast)
+ : listener(rFrame), extents(std::move(rExtents)), mergedText(rText)
+ , pParaPropsNode(pProps), pFirstNode(pFirst), pLastNode(pLast)
+ {
+ assert(pParaPropsNode);
+ assert(pFirstNode);
+ assert(pLastNode);
+ }
+};
+
+/// iterate SwTextAttr in potentially merged text frame
+class MergedAttrIterBase
+{
+protected:
+ sw::MergedPara const*const m_pMerged;
+ SwTextNode const*const m_pNode;
+ size_t m_CurrentExtent;
+ size_t m_CurrentHint;
+ MergedAttrIterBase(SwTextFrame const& rFrame);
+};
+
+class MergedAttrIter
+ : public MergedAttrIterBase
+{
+public:
+ MergedAttrIter(SwTextFrame const& rFrame) : MergedAttrIterBase(rFrame) {}
+ SwTextAttr const* NextAttr(SwTextNode const** ppNode = nullptr);
+};
+
+class MergedAttrIterByEnd
+{
+private:
+ std::vector<std::pair<SwTextNode const*, SwTextAttr const*>> m_Hints;
+ SwTextNode const*const m_pNode;
+ size_t m_CurrentHint;
+public:
+ MergedAttrIterByEnd(SwTextFrame const& rFrame);
+ SwTextAttr const* NextAttr(SwTextNode const*& rpNode);
+ void PrevAttr();
+};
+
+class MergedAttrIterReverse
+ : public MergedAttrIterBase
+{
+public:
+ MergedAttrIterReverse(SwTextFrame const& rFrame);
+ SwTextAttr const* PrevAttr(SwTextNode const** ppNode = nullptr);
+};
+
+
+const SwTwips WIDOW_MAGIC = (SAL_MAX_INT32 - 1)/2;
+
+} // namespace sw
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */