summaryrefslogtreecommitdiffstats
path: root/sw/source/core/text/inftxt.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/text/inftxt.hxx')
-rw-r--r--sw/source/core/text/inftxt.hxx788
1 files changed, 788 insertions, 0 deletions
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
new file mode 100644
index 000000000..83c173e2d
--- /dev/null
+++ b/sw/source/core/text/inftxt.hxx
@@ -0,0 +1,788 @@
+/* -*- 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_TEXT_INFTXT_HXX
+#define INCLUDED_SW_SOURCE_CORE_TEXT_INFTXT_HXX
+#include <memory>
+#include <com/sun/star/beans/PropertyValues.hpp>
+
+#include <map>
+
+#include <swtypes.hxx>
+#include <swrect.hxx>
+#include <txtfly.hxx>
+#include <swfont.hxx>
+#include "porlay.hxx"
+#include <txtfrm.hxx>
+#include <ndtxt.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <sal/log.hxx>
+
+namespace com::sun::star::linguistic2 { class XHyphenatedWord; }
+
+class SvxBrushItem;
+class SvxLineSpacingItem;
+class SvxTabStop;
+class SvxTabStopItem;
+class SwFlyPortion;
+class SwFormatDrop;
+class SwLinePortion;
+class SwTabPortion;
+class SwViewOption;
+class SwViewShell;
+class SwAttrIter;
+struct SwMultiCreator;
+class SwMultiPortion;
+namespace sw { class WrongListIterator; }
+
+#define ARROW_WIDTH 200
+#define DIR_LEFT2RIGHT 0
+#define DIR_BOTTOM2TOP 1
+#define DIR_RIGHT2LEFT 2
+#define DIR_TOP2BOTTOM 3
+
+#ifdef DBG_UTIL
+#define OPTDBG( rInf ) (rInf).IsOptDbg()
+#else
+#define OPTDBG( rInf ) false
+#endif
+
+// Respects the attribute LineSpace when calculating the Height/Ascent
+class SwLineInfo
+{
+ friend class SwTextIter;
+
+ std::unique_ptr<SvxTabStopItem> pRuler;
+ const SvxLineSpacingItem *pSpace;
+ SvxParaVertAlignItem::Align nVertAlign;
+ sal_uInt16 nDefTabStop;
+ bool bListTabStopIncluded;
+ long nListTabStopPosition;
+
+ void CtorInitLineInfo( const SwAttrSet& rAttrSet,
+ const SwTextNode& rTextNode );
+
+ SwLineInfo();
+ ~SwLineInfo();
+public:
+ // #i24363# tab stops relative to indent - returns the tab stop following nSearchPos or NULL
+ const SvxTabStop *GetTabStop( const SwTwips nSearchPos,
+ const SwTwips nRight ) const;
+ const SvxLineSpacingItem *GetLineSpacing() const { return pSpace; }
+ sal_uInt16 GetDefTabStop() const { return nDefTabStop; }
+ void SetDefTabStop( sal_uInt16 nNew ) const
+ { const_cast<SwLineInfo*>(this)->nDefTabStop = nNew; }
+
+ // vertical alignment
+ SvxParaVertAlignItem::Align GetVertAlign() const { return nVertAlign; }
+ bool HasSpecialAlign( bool bVert ) const
+ { return bVert ?
+ ( SvxParaVertAlignItem::Align::Baseline != nVertAlign ) :
+ ( SvxParaVertAlignItem::Align::Baseline != nVertAlign &&
+ SvxParaVertAlignItem::Align::Automatic != nVertAlign ); }
+
+ sal_uInt16 NumberOfTabStops() const;
+
+ bool IsListTabStopIncluded() const
+ {
+ return bListTabStopIncluded;
+ }
+ long GetListTabStopPosition() const
+ {
+ return nListTabStopPosition;
+ }
+};
+
+class SwTextInfo
+{
+ // Implementation in txthyph.cxx
+ friend void SetParaPortion( SwTextInfo *pInf, SwParaPortion *pRoot );
+ SwParaPortion *m_pPara;
+ TextFrameIndex m_nTextStart; // TextOfst for Follows
+
+protected:
+ SwTextInfo()
+ : m_pPara(nullptr)
+ , m_nTextStart(0)
+ {}
+
+public:
+ void CtorInitTextInfo( SwTextFrame *pFrame );
+ SwTextInfo( const SwTextInfo &rInf );
+ explicit SwTextInfo( SwTextFrame *pFrame ) { CtorInitTextInfo( pFrame ); }
+ SwParaPortion *GetParaPortion() { return m_pPara; }
+ const SwParaPortion *GetParaPortion() const { return m_pPara; }
+ TextFrameIndex GetTextStart() const { return m_nTextStart; }
+};
+
+class SwTextSizeInfo : public SwTextInfo
+{
+private:
+ typedef std::map< SwLinePortion const *, sal_uInt16 > SwTextPortionMap;
+
+protected:
+ // during formatting, a small database is built, mapping portion pointers
+ // to their maximum size (used for kana compression)
+ SwTextPortionMap m_aMaxWidth;
+ // for each line, an array of compression values is calculated
+ // this array is passed over to the info structure
+ std::deque<sal_uInt16>* m_pKanaComp;
+
+ SwViewShell *m_pVsh;
+
+ // m_pOut is the output device, m_pRef is the device used for formatting
+ VclPtr<OutputDevice> m_pOut;
+ VclPtr<OutputDevice> m_pRef;
+
+ // performance hack - this is only used by SwTextFormatInfo but
+ // because it's not even possible to dynamic_cast these things
+ // currently it has to be stored here
+ std::shared_ptr<vcl::TextLayoutCache> m_pCachedVclData;
+
+ SwFont *m_pFnt;
+ SwUnderlineFont *m_pUnderFnt; // Font for underlining
+ SwTextFrame *m_pFrame;
+ const SwViewOption *m_pOpt;
+ const OUString *m_pText;
+ TextFrameIndex m_nIdx;
+ TextFrameIndex m_nLen;
+ sal_uInt16 m_nKanaIdx;
+ bool m_bOnWin : 1;
+ bool m_bNotEOL : 1;
+ bool m_bURLNotify : 1;
+ bool m_bStopUnderflow : 1; // Underflow was stopped e.g. by a FlyPortion
+ bool m_bFootnoteInside : 1; // the current line contains a footnote
+ bool m_bOtherThanFootnoteInside : 1; // the current line contains another portion than a footnote portion.
+ // needed for checking keep together of footnote portion with previous portion
+ bool m_bMulti : 1; // inside a multiportion
+ bool m_bFirstMulti : 1; // this flag is used for two purposes:
+ // - the multiportion is the first lineportion
+ // - indicates, if we are currently in second
+ // line of multi portion
+ bool m_bRuby : 1; // during the formatting of a phonetic line
+ bool m_bHanging : 1; // formatting of hanging punctuation allowed
+ bool m_bScriptSpace : 1; // space between different scripts (Asian/Latin)
+ bool m_bForbiddenChars : 1; // Forbidden start/endline characters
+ bool m_bSnapToGrid : 1; // paragraph snaps to grid
+ sal_uInt8 m_nDirection : 2; // writing direction: 0/90/180/270 degree
+
+protected:
+ void CtorInitTextSizeInfo( OutputDevice* pRenderContext, SwTextFrame *pFrame,
+ TextFrameIndex nIdx);
+ SwTextSizeInfo();
+public:
+ SwTextSizeInfo( const SwTextSizeInfo &rInf );
+ SwTextSizeInfo( const SwTextSizeInfo &rInf, const OUString* pText,
+ TextFrameIndex nIdx = TextFrameIndex(0) );
+ SwTextSizeInfo(SwTextFrame *pTextFrame, TextFrameIndex nIndex = TextFrameIndex(0));
+
+ // GetMultiAttr returns the text attribute of the multiportion,
+ // if rPos is inside any multi-line part.
+ // rPos will set to the end of the multi-line part.
+ std::unique_ptr<SwMultiCreator> GetMultiCreator(TextFrameIndex &rPos, SwMultiPortion const* pM) const;
+
+ bool OnWin() const { return m_bOnWin; }
+ void SetOnWin( const bool bNew ) { m_bOnWin = bNew; }
+ bool NotEOL() const { return m_bNotEOL; }
+ void SetNotEOL( const bool bNew ) { m_bNotEOL = bNew; }
+ bool URLNotify() const { return m_bURLNotify; }
+ bool StopUnderflow() const { return m_bStopUnderflow; }
+ void SetStopUnderflow( const bool bNew ) { m_bStopUnderflow = bNew; }
+ bool IsFootnoteInside() const { return m_bFootnoteInside; }
+ void SetFootnoteInside( const bool bNew ) { m_bFootnoteInside = bNew; }
+ bool IsOtherThanFootnoteInside() const { return m_bOtherThanFootnoteInside; }
+ void SetOtherThanFootnoteInside( const bool bNew ) { m_bOtherThanFootnoteInside = bNew; }
+ bool IsMulti() const { return m_bMulti; }
+ void SetMulti( const bool bNew ) { m_bMulti = bNew; }
+ bool IsFirstMulti() const { return m_bFirstMulti; }
+ void SetFirstMulti( const bool bNew ) { m_bFirstMulti = bNew; }
+ bool IsRuby() const { return m_bRuby; }
+ void SetRuby( const bool bNew ) { m_bRuby = bNew; }
+ bool IsHanging() const { return m_bHanging; }
+ void SetHanging( const bool bNew ) { m_bHanging = bNew; }
+ bool HasScriptSpace() const { return m_bScriptSpace; }
+ void SetScriptSpace( const bool bNew ) { m_bScriptSpace = bNew; }
+ bool HasForbiddenChars() const { return m_bForbiddenChars; }
+ void SetForbiddenChars( const bool bN ) { m_bForbiddenChars = bN; }
+ bool SnapToGrid() const { return m_bSnapToGrid; }
+ void SetSnapToGrid( const bool bN ) { m_bSnapToGrid = bN; }
+ sal_uInt8 GetDirection() const { return m_nDirection; }
+ void SetDirection( const sal_uInt8 nNew ) { m_nDirection = nNew; }
+ bool IsRotated() const { return ( 1 & m_nDirection ); }
+
+ SwViewShell *GetVsh() { return m_pVsh; }
+ const SwViewShell *GetVsh() const { return m_pVsh; }
+
+ vcl::RenderContext *GetOut() { return m_pOut; }
+ const vcl::RenderContext *GetOut() const { return m_pOut; }
+ void SetOut( OutputDevice* pNewOut ) { m_pOut = pNewOut; }
+
+ vcl::RenderContext *GetRefDev() { return m_pRef; }
+ const vcl::RenderContext *GetRefDev() const { return m_pRef; }
+
+ SwFont *GetFont() { return m_pFnt; }
+ const SwFont *GetFont() const { return m_pFnt; }
+ void SetFont( SwFont *pNew ) { m_pFnt = pNew; }
+ void SelectFont();
+ void SetUnderFnt( SwUnderlineFont* pNew ) { m_pUnderFnt = pNew; }
+ SwUnderlineFont* GetUnderFnt() const { return m_pUnderFnt; }
+
+ const SwViewOption &GetOpt() const { return *m_pOpt; }
+ const OUString &GetText() const { return *m_pText; }
+ sal_Unicode GetChar(TextFrameIndex const nPos) const {
+ if (m_pText && nPos < TextFrameIndex(m_pText->getLength())) return (*m_pText)[sal_Int32(nPos)];
+ return 0;
+ }
+
+ sal_uInt16 GetTextHeight() const;
+
+ SwPosSize GetTextSize( OutputDevice* pOut, const SwScriptInfo* pSI,
+ const OUString& rText, TextFrameIndex nIdx,
+ TextFrameIndex nLen ) const;
+ SwPosSize GetTextSize() const;
+ void GetTextSize( const SwScriptInfo* pSI, TextFrameIndex nIdx,
+ TextFrameIndex nLen, const sal_uInt16 nComp,
+ sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff,
+ vcl::TextLayoutCache const* = nullptr) const;
+ inline SwPosSize GetTextSize(const SwScriptInfo* pSI, TextFrameIndex nIdx,
+ TextFrameIndex nLen) const;
+ inline SwPosSize GetTextSize( const OUString &rText ) const;
+
+ TextFrameIndex GetTextBreak( const long nLineWidth,
+ const TextFrameIndex nMaxLen,
+ const sal_uInt16 nComp,
+ vcl::TextLayoutCache const*) const;
+ TextFrameIndex GetTextBreak( const long nLineWidth,
+ const TextFrameIndex nMaxLen,
+ const sal_uInt16 nComp,
+ TextFrameIndex& rExtraCharPos,
+ vcl::TextLayoutCache const*) const;
+
+ sal_uInt16 GetAscent() const;
+
+ TextFrameIndex GetIdx() const { return m_nIdx; }
+ void SetIdx(const TextFrameIndex nNew) { m_nIdx = nNew; }
+ TextFrameIndex GetLen() const { return m_nLen; }
+ void SetLen(const TextFrameIndex nNew) { m_nLen = nNew; }
+ void SetText( const OUString &rNew ){ m_pText = &rNew; }
+
+ // No Bullets for the symbol font!
+ bool IsNoSymbol() const
+ { return RTL_TEXTENCODING_SYMBOL != m_pFnt->GetCharSet( m_pFnt->GetActual() ); }
+
+ void NoteAnimation() const;
+
+ // Home is where Your heart is...
+ SwTextFrame *GetTextFrame() { return m_pFrame; }
+ const SwTextFrame *GetTextFrame() const { return m_pFrame; }
+
+ bool HasHint(TextFrameIndex nPos) const;
+
+ // If Kana Compression is enabled, a minimum and maximum portion width
+ // is calculated. We format lines with minimal size and share remaining
+ // space among compressed kanas.
+ // During formatting, the maximum values of compressible portions are
+ // stored in m_aMaxWidth and discarded after a line has been formatted.
+ void SetMaxWidthDiff( const SwLinePortion *nKey, sal_uInt16 nVal )
+ {
+ m_aMaxWidth.insert( std::make_pair( nKey, nVal ) );
+ };
+ sal_uInt16 GetMaxWidthDiff( const SwLinePortion *nKey )
+ {
+ SwTextPortionMap::iterator it = m_aMaxWidth.find( nKey );
+
+ if( it != m_aMaxWidth.end() )
+ return it->second;
+ else
+ return 0;
+ };
+ void ResetMaxWidthDiff()
+ {
+ m_aMaxWidth.clear();
+ };
+ bool CompressLine()
+ {
+ return !m_aMaxWidth.empty();
+ };
+
+ // Feature: Kana Compression
+
+ sal_uInt16 GetKanaIdx() const { return m_nKanaIdx; }
+ void ResetKanaIdx(){ m_nKanaIdx = 0; }
+ void SetKanaIdx( sal_uInt16 nNew ) { m_nKanaIdx = nNew; }
+ void IncKanaIdx() { ++m_nKanaIdx; }
+ void SetKanaComp( std::deque<sal_uInt16> *pNew ){ m_pKanaComp = pNew; }
+ std::deque<sal_uInt16>* GetpKanaComp() const { return m_pKanaComp; }
+ sal_uInt16 GetKanaComp() const
+ { return ( m_pKanaComp && m_nKanaIdx < m_pKanaComp->size() )
+ ? (*m_pKanaComp)[m_nKanaIdx] : 0; }
+
+ const std::shared_ptr<vcl::TextLayoutCache>& GetCachedVclData() const
+ {
+ return m_pCachedVclData;
+ }
+ void SetCachedVclData(std::shared_ptr<vcl::TextLayoutCache> const& pCachedVclData)
+ {
+ m_pCachedVclData = pCachedVclData;
+ }
+};
+
+class SwTextPaintInfo : public SwTextSizeInfo
+{
+ sw::WrongListIterator *m_pWrongList;
+ sw::WrongListIterator *m_pGrammarCheckList;
+ sw::WrongListIterator *m_pSmartTags;
+ std::vector<long>* pSpaceAdd;
+ const SvxBrushItem *pBrushItem; // For the background
+ SwTextFly aTextFly; // Calculate the FlyFrame
+ Point aPos; // Paint position
+ SwRect aPaintRect; // Original paint rect (from Layout paint)
+
+ sal_uInt16 nSpaceIdx;
+ void DrawText_(const OUString &rText, const SwLinePortion &rPor,
+ const TextFrameIndex nIdx, const TextFrameIndex nLen,
+ const bool bKern, const bool bWrong = false,
+ const bool bSmartTag = false,
+ const bool bGrammarCheck = false );
+
+ SwTextPaintInfo &operator=(const SwTextPaintInfo&) = delete;
+
+protected:
+ SwTextPaintInfo()
+ : m_pWrongList(nullptr)
+ , m_pGrammarCheckList(nullptr)
+ , m_pSmartTags(nullptr)
+ , pSpaceAdd(nullptr)
+ , pBrushItem(nullptr)
+ , nSpaceIdx(0)
+ {}
+
+public:
+ SwTextPaintInfo( const SwTextPaintInfo &rInf );
+ SwTextPaintInfo( const SwTextPaintInfo &rInf, const OUString* pText );
+
+ void CtorInitTextPaintInfo( OutputDevice* pRenderContext, SwTextFrame *pFrame, const SwRect &rPaint );
+
+ const SvxBrushItem *GetBrushItem() const { return pBrushItem; }
+
+ SwTextPaintInfo( SwTextFrame *pFrame, const SwRect &rPaint );
+
+ SwTwips X() const { return aPos.X(); }
+ void X( const long nNew ) { aPos.setX(nNew); }
+ SwTwips Y() const { return aPos.Y(); }
+ void Y( const SwTwips nNew ) { aPos.setY(nNew); }
+
+ SwTextFly& GetTextFly() { return aTextFly; }
+ const SwTextFly& GetTextFly() const { return aTextFly; }
+ inline void DrawText( const OUString &rText, const SwLinePortion &rPor,
+ TextFrameIndex nIdx = TextFrameIndex(0),
+ TextFrameIndex nLen = TextFrameIndex(COMPLETE_STRING),
+ const bool bKern = false) const;
+ inline void DrawText( const SwLinePortion &rPor, TextFrameIndex nLen,
+ const bool bKern = false ) const;
+ inline void DrawMarkedText( const SwLinePortion &rPor, TextFrameIndex nLen,
+ const bool bWrong,
+ const bool bSmartTags,
+ const bool bGrammarCheck ) const;
+
+ void DrawRect( const SwRect &rRect, bool bRetouche ) const;
+
+ void DrawTab( const SwLinePortion &rPor ) const;
+ void DrawLineBreak( const SwLinePortion &rPor ) const;
+ void DrawRedArrow( const SwLinePortion &rPor ) const;
+ void DrawPostIts( bool bScript ) const;
+ void DrawBackground( const SwLinePortion &rPor ) const;
+ void DrawViewOpt( const SwLinePortion &rPor, PortionType nWhich ) const;
+ void DrawBackBrush( const SwLinePortion &rPor ) const;
+
+ /**
+ * Draw character border around a line portion.
+ *
+ * @param[in] rPor line portion around which border have to be drawn.
+ **/
+ void DrawBorder( const SwLinePortion &rPor ) const;
+
+ void DrawCheckBox(const SwFieldFormCheckboxPortion &rPor, bool bChecked) const;
+
+ /**
+ * Calculate the rectangular area where the portion takes place.
+ * @param[in] rPor portion for which the method specify the painting area
+ * @param[out] pRect whole area of the portion
+ * @param[out] pIntersect part of the portion area clipped by OutputDevice's clip region
+ * @param[in] bInsideBox area of portion's content, padding and border, but shadow
+ * is excluded (e.g. for background)
+ **/
+ void CalcRect( const SwLinePortion& rPor, SwRect* pRect,
+ SwRect* pIntersect = nullptr, const bool bInsideBox = false ) const;
+
+ inline SwTwips GetPaintOfst() const;
+ inline void SetPaintOfst( const SwTwips nNew );
+ const Point &GetPos() const { return aPos; }
+ void SetPos( const Point &rNew ) { aPos = rNew; }
+
+ const SwRect &GetPaintRect() const { return aPaintRect; }
+
+ // STUFF FOR JUSTIFIED ALIGNMENT
+
+ sal_uInt16 GetSpaceIdx() const { return nSpaceIdx; }
+ void ResetSpaceIdx(){nSpaceIdx = 0; }
+ void SetSpaceIdx( sal_uInt16 nNew ) { nSpaceIdx = nNew; }
+ void IncSpaceIdx() { ++nSpaceIdx; }
+ void RemoveFirstSpaceAdd() { pSpaceAdd->erase( pSpaceAdd->begin() ); }
+ long GetSpaceAdd() const
+ { return ( pSpaceAdd && nSpaceIdx < pSpaceAdd->size() )
+ ? (*pSpaceAdd)[nSpaceIdx] : 0; }
+
+ void SetpSpaceAdd( std::vector<long>* pNew ){ pSpaceAdd = pNew; }
+ std::vector<long>* GetpSpaceAdd() const { return pSpaceAdd; }
+
+ void SetWrongList(sw::WrongListIterator *const pNew) { m_pWrongList = pNew; }
+ sw::WrongListIterator* GetpWrongList() const { return m_pWrongList; }
+
+ void SetGrammarCheckList(sw::WrongListIterator *const pNew) { m_pGrammarCheckList = pNew; }
+ sw::WrongListIterator* GetGrammarCheckList() const { return m_pGrammarCheckList; }
+
+ void SetSmartTags(sw::WrongListIterator *const pNew) { m_pSmartTags = pNew; }
+ sw::WrongListIterator* GetSmartTags() const { return m_pSmartTags; }
+};
+
+class SwTextFormatInfo : public SwTextPaintInfo
+{
+ // temporary arguments for hyphenation
+ css::beans::PropertyValues m_aHyphVals;
+
+ SwLineLayout *m_pRoot; // The Root of the current line (pCurr)
+ SwLinePortion *m_pLast; // The last Portion
+ SwFlyPortion *m_pFly; // The following FlyPortion
+ SwLinePortion *m_pUnderflow; // Underflow: Last Portion
+ SwLinePortion *m_pRest; // The Rest is the start of the next Line
+
+ SwTabPortion *m_pLastTab; // The _last_ TabPortion
+
+ TextFrameIndex m_nSoftHyphPos; ///< SoftHyphPos for Hyphenation
+ TextFrameIndex m_nLineStart; ///< Current line start in rText
+ TextFrameIndex m_nUnderScorePos; ///< enlarge repaint if underscore has been found
+ TextFrameIndex m_nLastBookmarkPos; ///< need to check for bookmarks at every portion
+ // #i34348# Changed type from sal_uInt16 to SwTwips
+ SwTwips m_nLeft; // Left margin
+ SwTwips m_nRight; // Right margin
+ SwTwips m_nFirst; // EZE
+ /// First or left margin, depending on context.
+ SwTwips m_nLeftMargin = 0;
+ sal_uInt16 m_nRealWidth; // "real" line width
+ sal_uInt16 m_nWidth; // "virtual" line width
+ sal_uInt16 m_nLineHeight; // Final height after CalcLine
+ sal_uInt16 m_nLineNetHeight; // line height without spacing
+ sal_uInt16 m_nForcedLeftMargin; // Shift of left margin due to frame
+
+ bool m_bFull : 1; // Line is full
+ bool m_bFootnoteDone : 1; // Footnote already formatted
+ bool m_bErgoDone : 1; // ErgoDone already formatted
+ bool m_bNumDone : 1; // bNumDone already formatted
+ bool m_bArrowDone : 1; // Arrow to the left for scrolling paragraphs
+ bool m_bStop : 1; // Cancel immediately, discarding the line
+ bool m_bNewLine : 1; // Format another line
+ bool m_bShift : 1; // Position change: Repaint until further notice
+ bool m_bUnderflow : 1; // Context: Underflow() ?
+ bool m_bInterHyph : 1; // Interactive hyphenation?
+ bool m_bAutoHyph : 1; // Automatic hyphenation?
+ bool m_bDropInit : 1; // Set DropWidth
+ bool m_bQuick : 1; // FormatQuick()
+ bool m_bNoEndHyph : 1; // Switch off hyphenation at the line end (due to MaxHyphens)
+ bool m_bNoMidHyph : 1; // Switch off hyphenation before flys (due to MaxHyphens)
+ bool m_bIgnoreFly : 1; // FitToContent ignores flys
+ bool m_bFakeLineStart : 1; // String has been replaced by field portion
+ // info structure only pretends that we are at
+ // the beginning of a line
+ bool m_bTabOverflow : 1; // Tabs are expanding after the end margin
+ bool m_bTestFormat : 1; // Test formatting from WouldFit, no notification etc.
+
+ sal_Unicode m_cTabDecimal; // the current decimal delimiter
+ sal_Unicode m_cHookChar; // For tabs in fields etc.
+ sal_uInt8 m_nMaxHyph; // Max. line count of followup hyphenations
+
+ // Hyphenating ...
+ bool InitHyph( const bool bAuto = false );
+ bool CheckFootnotePortion_( SwLineLayout const * pCurr );
+
+public:
+ void CtorInitTextFormatInfo( OutputDevice* pRenderContext, SwTextFrame *pFrame, const bool bInterHyph = false,
+ const bool bQuick = false, const bool bTst = false );
+ SwTextFormatInfo(OutputDevice* pRenderContext, SwTextFrame *pFrame, const bool bInterHyphL = false,
+ const bool bQuickL = false, const bool bTst = false);
+
+ // For the formatting inside a double line in a line (multi-line portion)
+ // we need a modified text-format-info:
+ SwTextFormatInfo( const SwTextFormatInfo& rInf, SwLineLayout& rLay,
+ SwTwips nActWidth );
+
+ sal_uInt16 Width() const { return m_nWidth; }
+ void Width( const sal_uInt16 nNew ) { m_nWidth = nNew; }
+ void Init();
+
+ /**
+ * Returns the distance between the current horizontal position and the end
+ * of the line.
+ */
+ SwTwips GetLineWidth();
+
+ // Returns the first changed position of the paragraph
+ inline TextFrameIndex GetReformatStart() const;
+
+ // Margins
+ SwTwips Left() const { return m_nLeft; }
+ void Left( const SwTwips nNew ) { m_nLeft = nNew; }
+ SwTwips Right() const { return m_nRight; }
+ void Right( const SwTwips nNew ) { m_nRight = nNew; }
+ SwTwips First() const { return m_nFirst; }
+ void First( const SwTwips nNew ) { m_nFirst = nNew; }
+ void LeftMargin( const SwTwips nNew) { m_nLeftMargin = nNew; }
+ sal_uInt16 RealWidth() const { return m_nRealWidth; }
+ void RealWidth( const sal_uInt16 nNew ) { m_nRealWidth = nNew; }
+ sal_uInt16 ForcedLeftMargin() const { return m_nForcedLeftMargin; }
+ void ForcedLeftMargin( const sal_uInt16 nN ) { m_nForcedLeftMargin = nN; }
+
+ sal_uInt8 &MaxHyph() { return m_nMaxHyph; }
+ const sal_uInt8 &MaxHyph() const { return m_nMaxHyph; }
+
+ SwLineLayout *GetRoot() { return m_pRoot; }
+ const SwLineLayout *GetRoot() const { return m_pRoot; }
+
+ void SetRoot( SwLineLayout *pNew ) { m_pRoot = pNew; }
+ SwLinePortion *GetLast() { return m_pLast; }
+ void SetLast( SwLinePortion *pNewLast ) { m_pLast = pNewLast; }
+ bool IsFull() const { return m_bFull; }
+ void SetFull( const bool bNew ) { m_bFull = bNew; }
+ bool IsHyphForbud() const
+ { return m_pFly ? m_bNoMidHyph : m_bNoEndHyph; }
+ void ChkNoHyph( const sal_uInt8 bEnd, const sal_uInt8 bMid )
+ { m_bNoEndHyph = (m_nMaxHyph && bEnd >= m_nMaxHyph);
+ m_bNoMidHyph = (m_nMaxHyph && bMid >= m_nMaxHyph); }
+ bool IsIgnoreFly() const { return m_bIgnoreFly; }
+ void SetIgnoreFly( const bool bNew ) { m_bIgnoreFly = bNew; }
+ bool IsFakeLineStart() const { return m_bFakeLineStart; }
+ void SetFakeLineStart( const bool bNew ) { m_bFakeLineStart = bNew; }
+ bool IsStop() const { return m_bStop; }
+ void SetStop( const bool bNew ) { m_bStop = bNew; }
+ SwLinePortion *GetRest() { return m_pRest; }
+ void SetRest( SwLinePortion *pNewRest ) { m_pRest = pNewRest; }
+ bool IsNewLine() const { return m_bNewLine; }
+ void SetNewLine( const bool bNew ) { m_bNewLine = bNew; }
+ bool IsShift() const { return m_bShift; }
+ void SetShift( const bool bNew ) { m_bShift = bNew; }
+ bool IsInterHyph() const { return m_bInterHyph; }
+ bool IsUnderflow() const { return m_bUnderflow; }
+ void ClrUnderflow() { m_bUnderflow = false; }
+ bool IsDropInit() const { return m_bDropInit; }
+ void SetDropInit( const bool bNew ) { m_bDropInit = bNew; }
+ bool IsQuick() const { return m_bQuick; }
+ bool IsTest() const { return m_bTestFormat; }
+
+ TextFrameIndex GetLineStart() const { return m_nLineStart; }
+ void SetLineStart(TextFrameIndex const nNew) { m_nLineStart = nNew; }
+
+ // these are used during fly calculation
+ sal_uInt16 GetLineHeight() const { return m_nLineHeight; }
+ void SetLineHeight( const sal_uInt16 nNew ) { m_nLineHeight = nNew; }
+ sal_uInt16 GetLineNetHeight() const { return m_nLineNetHeight; }
+ void SetLineNetHeight( const sal_uInt16 nNew ) { m_nLineNetHeight = nNew; }
+
+ const SwLinePortion *GetUnderflow() const { return m_pUnderflow; }
+ SwLinePortion *GetUnderflow() { return m_pUnderflow; }
+ void SetUnderflow( SwLinePortion *pNew )
+ { m_pUnderflow = pNew; m_bUnderflow = true; }
+ TextFrameIndex GetSoftHyphPos() const { return m_nSoftHyphPos; }
+ void SetSoftHyphPos(TextFrameIndex const nNew) { m_nSoftHyphPos = nNew; }
+
+ inline void SetParaFootnote();
+
+ // FlyFrames
+ SwFlyPortion *GetFly() { return m_pFly; }
+ void SetFly( SwFlyPortion *pNew ) { m_pFly = pNew; }
+
+ inline const SwAttrSet& GetCharAttr() const;
+
+ // Tabs
+ SwTabPortion *GetLastTab() { return m_pLastTab; }
+ void SetLastTab( SwTabPortion *pNew ) { m_pLastTab = pNew; }
+ sal_Unicode GetTabDecimal() const { return m_cTabDecimal; }
+ void SetTabDecimal( const sal_Unicode cNew ) { m_cTabDecimal = cNew;}
+
+ void ClearHookChar() { m_cHookChar = 0; }
+ void SetHookChar( const sal_Unicode cNew ) { m_cHookChar = cNew; }
+ sal_Unicode GetHookChar() const { return m_cHookChar; }
+
+ // Done-Flags
+ bool IsFootnoteDone() const { return m_bFootnoteDone; }
+ void SetFootnoteDone( const bool bNew ) { m_bFootnoteDone = bNew; }
+ bool IsErgoDone() const { return m_bErgoDone; }
+ void SetErgoDone( const bool bNew ) { m_bErgoDone = bNew; }
+ bool IsNumDone() const { return m_bNumDone; }
+ void SetNumDone( const bool bNew ) { m_bNumDone = bNew; }
+ bool IsArrowDone() const { return m_bArrowDone; }
+ void SetArrowDone( const bool bNew ) { m_bArrowDone = bNew; }
+
+ bool CheckCurrentPosBookmark();
+
+ // For SwTextPortion::Hyphenate
+ bool ChgHyph( const bool bNew );
+
+ // Should the hyphenate helper be discarded?
+ bool IsHyphenate() const;
+ TextFrameIndex GetUnderScorePos() const { return m_nUnderScorePos; }
+ void SetUnderScorePos(TextFrameIndex const nNew) { m_nUnderScorePos = nNew; }
+
+ // Calls HyphenateWord() of Hyphenator
+ css::uno::Reference< css::linguistic2::XHyphenatedWord >
+ HyphWord( const OUString &rText, const sal_Int32 nMinTrail );
+ const css::beans::PropertyValues & GetHyphValues() const;
+
+ bool CheckFootnotePortion( SwLineLayout const * pCurr )
+ { return IsFootnoteInside() && CheckFootnotePortion_( pCurr ); }
+
+ // Dropcaps called by SwTextFormatter::CTOR
+ const SwFormatDrop *GetDropFormat() const;
+
+ // Sets the last SwKernPortion as pLast, if it is followed by empty portions
+ bool LastKernPortion();
+
+ // Looks for tabs, TabDec, TXTATR and BRK from nIdx until nEnd.
+ // Return: Position; sets cHookChar if necessary
+ TextFrameIndex ScanPortionEnd(TextFrameIndex nStart, TextFrameIndex nEnd);
+
+ void SetTabOverflow( bool bOverflow ) { m_bTabOverflow = bOverflow; }
+ bool IsTabOverflow() const { return m_bTabOverflow; }
+
+};
+
+/**
+ * For the text replacement and restoration of SwTextSizeInfo.
+ * The way this is done is a bit of a hack: Although rInf is const we change it
+ * anyway.
+ * Because rInf is restored again in the DTOR, we can do this.
+ * You could call it a "logical const", if you wish.
+ */
+class SwTextSlot final
+{
+ OUString aText;
+ std::shared_ptr<vcl::TextLayoutCache> m_pOldCachedVclData;
+ const OUString *pOldText;
+ sw::WrongListIterator * m_pOldSmartTagList;
+ sw::WrongListIterator * m_pOldGrammarCheckList;
+ std::unique_ptr<SwWrongList> m_pTempList;
+ std::unique_ptr<sw::WrongListIterator> m_pTempIter;
+ TextFrameIndex nIdx;
+ TextFrameIndex nLen;
+ bool bOn;
+ SwTextSizeInfo *pInf;
+
+public:
+ // The replacement string originates either from the portion via GetExpText()
+ // or from the rCh, if it is not empty.
+ SwTextSlot( const SwTextSizeInfo *pNew, const SwLinePortion *pPor, bool bTextLen,
+ bool bExgLists, OUString const & rCh = OUString() );
+ ~SwTextSlot();
+};
+
+class SwFontSave
+{
+ SwTextSizeInfo *pInf;
+ SwFont *pFnt;
+ SwAttrIter *pIter;
+public:
+ SwFontSave( const SwTextSizeInfo &rInf, SwFont *pFnt,
+ SwAttrIter* pItr = nullptr );
+ ~SwFontSave();
+};
+
+inline sal_uInt16 SwTextSizeInfo::GetAscent() const
+{
+ assert(GetOut());
+ return const_cast<SwFont*>(GetFont())->GetAscent( m_pVsh, *GetOut() );
+}
+
+inline sal_uInt16 SwTextSizeInfo::GetTextHeight() const
+{
+ assert(GetOut());
+ return const_cast<SwFont*>(GetFont())->GetHeight( m_pVsh, *GetOut() );
+}
+
+inline SwPosSize SwTextSizeInfo::GetTextSize( const OUString &rText ) const
+{
+ return GetTextSize(m_pOut, nullptr, rText, TextFrameIndex(0), TextFrameIndex(rText.getLength()));
+}
+
+inline SwPosSize SwTextSizeInfo::GetTextSize( const SwScriptInfo* pSI,
+ TextFrameIndex const nNewIdx,
+ TextFrameIndex const nNewLen) const
+{
+ return GetTextSize( m_pOut, pSI, *m_pText, nNewIdx, nNewLen );
+}
+
+inline SwTwips SwTextPaintInfo::GetPaintOfst() const
+{
+ return GetParaPortion()->GetRepaint().GetOffset();
+}
+
+inline void SwTextPaintInfo::SetPaintOfst( const SwTwips nNew )
+{
+ GetParaPortion()->GetRepaint().SetOffset( nNew );
+}
+
+inline void SwTextPaintInfo::DrawText( const OUString &rText,
+ const SwLinePortion &rPor,
+ const TextFrameIndex nStart, const TextFrameIndex nLength,
+ const bool bKern ) const
+{
+ const_cast<SwTextPaintInfo*>(this)->DrawText_( rText, rPor, nStart, nLength, bKern );
+}
+
+inline void SwTextPaintInfo::DrawText( const SwLinePortion &rPor,
+ const TextFrameIndex nLength, const bool bKern ) const
+{
+ const_cast<SwTextPaintInfo*>(this)->DrawText_( *m_pText, rPor, m_nIdx, nLength, bKern );
+}
+
+inline void SwTextPaintInfo::DrawMarkedText( const SwLinePortion &rPor,
+ const TextFrameIndex nLength,
+ const bool bWrong,
+ const bool bSmartTags,
+ const bool bGrammarCheck ) const
+{
+ const_cast<SwTextPaintInfo*>(this)->DrawText_( *m_pText, rPor, m_nIdx, nLength, false/*bKern*/, bWrong, bSmartTags, bGrammarCheck );
+}
+
+inline TextFrameIndex SwTextFormatInfo::GetReformatStart() const
+{
+ return GetParaPortion()->GetReformat().Start();
+}
+
+inline const SwAttrSet& SwTextFormatInfo::GetCharAttr() const
+{
+ // sw_redlinehide: this is used for numbering/footnote number portions, so:
+ return GetTextFrame()->GetTextNodeForParaProps()->GetSwAttrSet();
+}
+
+inline void SwTextFormatInfo::SetParaFootnote()
+{
+ GetTextFrame()->SetFootnote( true );
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */