ITEM: Refactor ItemType
[LibreOffice.git] / sw / source / core / text / inftxt.hxx
blob4a3bf7a1c514c3a8509146e9784e4d4e5243cc14
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 #pragma once
21 #include <memory>
22 #include <optional>
23 #include <com/sun/star/beans/PropertyValues.hpp>
25 #include <map>
27 #include <swtypes.hxx>
28 #include <swrect.hxx>
29 #include <txtfly.hxx>
30 #include <swfont.hxx>
31 #include "porlay.hxx"
32 #include <txtfrm.hxx>
33 #include <ndtxt.hxx>
34 #include <editeng/paravertalignitem.hxx>
36 namespace com::sun::star::linguistic2 { class XHyphenatedWord; }
38 class SvxBrushItem;
39 class SvxLineSpacingItem;
40 class SvxTabStop;
41 class SvxTabStopItem;
42 class SwFlyPortion;
43 class SwFormatDrop;
44 class SwLinePortion;
45 class SwTabPortion;
46 class SwViewOption;
47 class SwViewShell;
48 class SwAttrIter;
49 struct SwMultiCreator;
50 class SwMultiPortion;
51 namespace sw { class WrongListIterator; }
53 #define ARROW_WIDTH 200
54 #define DIR_LEFT2RIGHT 0
55 #define DIR_BOTTOM2TOP 1
56 #define DIR_RIGHT2LEFT 2
57 #define DIR_TOP2BOTTOM 3
59 // Respects the attribute LineSpace when calculating the Height/Ascent
60 class SwLineInfo
62 friend class SwTextIter;
64 std::optional<SvxTabStopItem> m_oRuler;
65 const SvxLineSpacingItem *m_pSpace;
66 SvxParaVertAlignItem::Align m_nVertAlign;
67 SwTwips m_nDefTabStop;
68 bool m_bListTabStopIncluded;
69 tools::Long m_nListTabStopPosition;
71 void CtorInitLineInfo( const SwAttrSet& rAttrSet,
72 const SwTextNode& rTextNode );
74 SW_DLLPUBLIC SwLineInfo();
75 SW_DLLPUBLIC ~SwLineInfo();
76 public:
77 // #i24363# tab stops relative to indent - returns the tab stop following nSearchPos or NULL
78 const SvxTabStop* GetTabStop(const SwTwips nSearchPos, SwTwips& nRight) const;
79 const SvxLineSpacingItem *GetLineSpacing() const { return m_pSpace; }
80 SwTwips GetDefTabStop() const { return m_nDefTabStop; }
81 void SetDefTabStop(SwTwips nNew) const
82 { const_cast<SwLineInfo*>(this)->m_nDefTabStop = nNew; }
84 // vertical alignment
85 SvxParaVertAlignItem::Align GetVertAlign() const { return m_nVertAlign; }
86 bool HasSpecialAlign( bool bVert ) const
87 { return bVert ?
88 ( SvxParaVertAlignItem::Align::Baseline != m_nVertAlign ) :
89 ( SvxParaVertAlignItem::Align::Baseline != m_nVertAlign &&
90 SvxParaVertAlignItem::Align::Automatic != m_nVertAlign ); }
92 sal_uInt16 NumberOfTabStops() const;
94 bool IsListTabStopIncluded() const
96 return m_bListTabStopIncluded;
98 tools::Long GetListTabStopPosition() const
100 return m_nListTabStopPosition;
104 class SwTextInfo
106 // Implementation in txthyph.cxx
107 friend void SetParaPortion( SwTextInfo *pInf, SwParaPortion *pRoot );
108 SwParaPortion *m_pPara;
109 TextFrameIndex m_nTextStart; // TextOfst for Follows
111 protected:
112 SwTextInfo()
113 : m_pPara(nullptr)
114 , m_nTextStart(0)
117 public:
118 void CtorInitTextInfo( SwTextFrame *pFrame );
119 SwTextInfo( const SwTextInfo &rInf );
120 explicit SwTextInfo( SwTextFrame *pFrame ) { CtorInitTextInfo( pFrame ); }
121 SwParaPortion *GetParaPortion() { return m_pPara; }
122 const SwParaPortion *GetParaPortion() const { return m_pPara; }
123 TextFrameIndex GetTextStart() const { return m_nTextStart; }
126 class SwTextSizeInfo : public SwTextInfo
128 private:
129 typedef std::map<SwLinePortion const*, SwTwips> SwTextPortionMap;
131 protected:
132 // during formatting, a small database is built, mapping portion pointers
133 // to their maximum size (used for kana compression)
134 SwTextPortionMap m_aMaxWidth;
135 // for each line, an array of compression values is calculated
136 // this array is passed over to the info structure
137 std::deque<sal_uInt16>* m_pKanaComp;
139 SwViewShell *m_pVsh;
141 // m_pOut is the output device, m_pRef is the device used for formatting
142 VclPtr<OutputDevice> m_pOut;
143 VclPtr<OutputDevice> m_pRef;
145 // performance hack - this is only used by SwTextFormatInfo but
146 // because it's not even possible to dynamic_cast these things
147 // currently it has to be stored here
148 std::shared_ptr<const vcl::text::TextLayoutCache> m_pCachedVclData;
150 SwFont *m_pFnt;
151 SwUnderlineFont *m_pUnderFnt; // Font for underlining
152 SwTextFrame *m_pFrame;
153 const SwViewOption *m_pOpt;
154 const OUString *m_pText;
155 TextFrameIndex m_nIdx;
156 TextFrameIndex m_nLen;
157 TextFrameIndex m_nMeasureLen;
158 std::optional<SwLinePortionLayoutContext> m_nLayoutContext;
159 sal_uInt16 m_nKanaIdx;
160 bool m_bOnWin : 1;
161 bool m_bNotEOL : 1;
162 bool m_bURLNotify : 1;
163 bool m_bStopUnderflow : 1; // Underflow was stopped e.g. by a FlyPortion
164 bool m_bFootnoteInside : 1; // the current line contains a footnote
165 bool m_bOtherThanFootnoteInside : 1; // the current line contains another portion than a footnote portion.
166 // needed for checking keep together of footnote portion with previous portion
167 bool m_bMulti : 1; // inside a multiportion
168 bool m_bFirstMulti : 1; // this flag is used for two purposes:
169 // - the multiportion is the first lineportion
170 // - indicates, if we are currently in second
171 // line of multi portion
172 bool m_bRuby : 1; // during the formatting of a phonetic line
173 bool m_bHanging : 1; // formatting of hanging punctuation allowed
174 bool m_bScriptSpace : 1; // space between different scripts (Asian/Latin)
175 bool m_bForbiddenChars : 1; // Forbidden start/endline characters
176 bool m_bSnapToGrid : 1; // paragraph snaps to grid
177 sal_uInt8 m_nDirection : 2; // writing direction: 0/90/180/270 degree
178 SwTwips m_nExtraSpace; // extra space before shrinking = nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth)
180 protected:
181 void CtorInitTextSizeInfo( OutputDevice* pRenderContext, SwTextFrame *pFrame,
182 TextFrameIndex nIdx);
183 SwTextSizeInfo();
184 public:
185 SwTextSizeInfo( const SwTextSizeInfo &rInf );
186 SwTextSizeInfo( const SwTextSizeInfo &rInf, const OUString* pText,
187 TextFrameIndex nIdx = TextFrameIndex(0) );
188 SW_DLLPUBLIC SwTextSizeInfo(SwTextFrame *pTextFrame, TextFrameIndex nIndex = TextFrameIndex(0));
190 // GetMultiAttr returns the text attribute of the multiportion,
191 // if rPos is inside any multi-line part.
192 // rPos will set to the end of the multi-line part.
193 std::optional<SwMultiCreator> GetMultiCreator(TextFrameIndex &rPos, SwMultiPortion const* pM) const;
195 bool OnWin() const { return m_bOnWin; }
196 void SetOnWin( const bool bNew ) { m_bOnWin = bNew; }
197 bool NotEOL() const { return m_bNotEOL; }
198 void SetNotEOL( const bool bNew ) { m_bNotEOL = bNew; }
199 bool URLNotify() const { return m_bURLNotify; }
200 bool StopUnderflow() const { return m_bStopUnderflow; }
201 void SetStopUnderflow( const bool bNew ) { m_bStopUnderflow = bNew; }
202 bool IsFootnoteInside() const { return m_bFootnoteInside; }
203 void SetFootnoteInside( const bool bNew ) { m_bFootnoteInside = bNew; }
204 bool IsOtherThanFootnoteInside() const { return m_bOtherThanFootnoteInside; }
205 void SetOtherThanFootnoteInside( const bool bNew ) { m_bOtherThanFootnoteInside = bNew; }
206 bool IsMulti() const { return m_bMulti; }
207 void SetMulti( const bool bNew ) { m_bMulti = bNew; }
208 bool IsFirstMulti() const { return m_bFirstMulti; }
209 void SetFirstMulti( const bool bNew ) { m_bFirstMulti = bNew; }
210 bool IsRuby() const { return m_bRuby; }
211 void SetRuby( const bool bNew ) { m_bRuby = bNew; }
212 bool IsHanging() const { return m_bHanging; }
213 void SetHanging( const bool bNew ) { m_bHanging = bNew; }
214 bool HasScriptSpace() const { return m_bScriptSpace; }
215 void SetScriptSpace( const bool bNew ) { m_bScriptSpace = bNew; }
216 bool HasForbiddenChars() const { return m_bForbiddenChars; }
217 void SetForbiddenChars( const bool bN ) { m_bForbiddenChars = bN; }
218 bool SnapToGrid() const { return m_bSnapToGrid; }
219 void SetSnapToGrid( const bool bN ) { m_bSnapToGrid = bN; }
220 sal_uInt8 GetDirection() const { return m_nDirection; }
221 void SetDirection( const sal_uInt8 nNew ) { m_nDirection = nNew; }
222 bool IsRotated() const { return ( 1 & m_nDirection ); }
224 SwViewShell *GetVsh() { return m_pVsh; }
225 const SwViewShell *GetVsh() const { return m_pVsh; }
227 vcl::RenderContext *GetOut() { return m_pOut; }
228 const vcl::RenderContext *GetOut() const { return m_pOut; }
229 void SetOut( OutputDevice* pNewOut ) { m_pOut = pNewOut; }
231 vcl::RenderContext *GetRefDev() { return m_pRef; }
232 const vcl::RenderContext *GetRefDev() const { return m_pRef; }
234 SwFont *GetFont() { return m_pFnt; }
235 const SwFont *GetFont() const { return m_pFnt; }
236 void SetFont( SwFont *pNew ) { m_pFnt = pNew; }
237 void SelectFont();
238 void SetUnderFnt( SwUnderlineFont* pNew ) { m_pUnderFnt = pNew; }
239 SwUnderlineFont* GetUnderFnt() const { return m_pUnderFnt; }
241 const SwViewOption &GetOpt() const { return *m_pOpt; }
242 const OUString &GetText() const { return *m_pText; }
243 sal_Unicode GetChar(TextFrameIndex const nPos) const {
244 if (m_pText && nPos < TextFrameIndex(m_pText->getLength())) return (*m_pText)[sal_Int32(nPos)];
245 return 0;
248 sal_uInt16 GetTextHeight() const;
250 SwPosSize GetTextSize( OutputDevice* pOut, const SwScriptInfo* pSI,
251 const OUString& rText, TextFrameIndex nIdx,
252 TextFrameIndex nLen ) const;
253 SwPosSize GetTextSize(std::optional<SwLinePortionLayoutContext> nLayoutContext
254 = std::nullopt) const;
255 void GetTextSize(const SwScriptInfo* pSI, TextFrameIndex nIdx, TextFrameIndex nLen,
256 std::optional<SwLinePortionLayoutContext> nLayoutContext,
257 const sal_uInt16 nComp, SwTwips& nMinSize, tools::Long& nMaxSizeDiff,
258 SwTwips& nExtraAscent, SwTwips& nExtraDescent,
259 vcl::text::TextLayoutCache const* = nullptr) const;
260 inline SwPosSize GetTextSize(const SwScriptInfo* pSI, TextFrameIndex nIdx,
261 TextFrameIndex nLen) const;
262 inline SwPosSize GetTextSize( const OUString &rText ) const;
264 TextFrameIndex GetTextBreak( const tools::Long nLineWidth,
265 const TextFrameIndex nMaxLen,
266 const sal_uInt16 nComp,
267 vcl::text::TextLayoutCache const*) const;
268 TextFrameIndex GetTextBreak( const tools::Long nLineWidth,
269 const TextFrameIndex nMaxLen,
270 const sal_uInt16 nComp,
271 TextFrameIndex& rExtraCharPos,
272 vcl::text::TextLayoutCache const*) const;
274 sal_uInt16 GetAscent() const;
275 sal_uInt16 GetHangingBaseline() const;
277 TextFrameIndex GetIdx() const { return m_nIdx; }
278 void SetIdx(const TextFrameIndex nNew) { m_nIdx = nNew; }
279 TextFrameIndex GetLen() const { return m_nLen; }
280 void SetLen(const TextFrameIndex nNew) { m_nLen = nNew; }
281 TextFrameIndex GetMeasureLen() const { return m_nMeasureLen; }
282 void SetMeasureLen(const TextFrameIndex nNew) { m_nMeasureLen = nNew; }
283 void SetText( const OUString &rNew ){ m_pText = &rNew; }
285 const std::optional<SwLinePortionLayoutContext> & GetLayoutContext() const { return m_nLayoutContext; }
287 void SetLayoutContext(std::optional<SwLinePortionLayoutContext> nNew)
289 m_nLayoutContext = nNew;
292 // No Bullets for the symbol font!
293 bool IsNoSymbol() const
294 { return RTL_TEXTENCODING_SYMBOL != m_pFnt->GetCharSet( m_pFnt->GetActual() ); }
296 void NoteAnimation() const;
298 // Home is where Your heart is...
299 SwTextFrame *GetTextFrame() { return m_pFrame; }
300 const SwTextFrame *GetTextFrame() const { return m_pFrame; }
302 bool HasHint(TextFrameIndex nPos) const;
304 // extra space before shrinking = nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth)
305 void SetExtraSpace(SwTwips nVal) { m_nExtraSpace = nVal; }
306 SwTwips GetExtraSpace() const { return m_nExtraSpace; }
308 // If Kana Compression is enabled, a minimum and maximum portion width
309 // is calculated. We format lines with minimal size and share remaining
310 // space among compressed kanas.
311 // During formatting, the maximum values of compressible portions are
312 // stored in m_aMaxWidth and discarded after a line has been formatted.
313 void SetMaxWidthDiff(const SwLinePortion* nKey, SwTwips nVal)
315 m_aMaxWidth.insert( std::make_pair( nKey, nVal ) );
317 SwTwips GetMaxWidthDiff(const SwLinePortion* nKey)
319 SwTextPortionMap::iterator it = m_aMaxWidth.find( nKey );
321 if( it != m_aMaxWidth.end() )
322 return it->second;
323 else
324 return 0;
326 void ResetMaxWidthDiff()
328 m_aMaxWidth.clear();
330 bool CompressLine()
332 return !m_aMaxWidth.empty();
335 // Feature: Kana Compression
337 sal_uInt16 GetKanaIdx() const { return m_nKanaIdx; }
338 void ResetKanaIdx(){ m_nKanaIdx = 0; }
339 void SetKanaIdx( sal_uInt16 nNew ) { m_nKanaIdx = nNew; }
340 void IncKanaIdx() { ++m_nKanaIdx; }
341 void SetKanaComp( std::deque<sal_uInt16> *pNew ){ m_pKanaComp = pNew; }
342 std::deque<sal_uInt16>* GetpKanaComp() const { return m_pKanaComp; }
343 sal_uInt16 GetKanaComp() const
344 { return ( m_pKanaComp && m_nKanaIdx < m_pKanaComp->size() )
345 ? (*m_pKanaComp)[m_nKanaIdx] : 0; }
347 const std::shared_ptr<const vcl::text::TextLayoutCache>& GetCachedVclData() const
349 return m_pCachedVclData;
351 void SetCachedVclData(std::shared_ptr<const vcl::text::TextLayoutCache> const& pCachedVclData)
353 m_pCachedVclData = pCachedVclData;
357 class SwTextPaintInfo : public SwTextSizeInfo
359 sw::WrongListIterator *m_pWrongList;
360 sw::WrongListIterator *m_pGrammarCheckList;
361 sw::WrongListIterator *m_pSmartTags;
362 std::vector<tools::Long>* m_pSpaceAdd;
363 const SvxBrushItem *m_pBrushItem; // For the background
364 SwTextFly m_aTextFly; // Calculate the FlyFrame
365 Point m_aPos; // Paint position
366 SwRect m_aPaintRect; // Original paint rect (from Layout paint)
368 sal_uInt16 m_nSpaceIdx;
369 void DrawText_(const OUString &rText, const SwLinePortion &rPor,
370 const TextFrameIndex nIdx, const TextFrameIndex nLen,
371 const bool bKern, const bool bWrong = false,
372 const bool bSmartTag = false,
373 const bool bGrammarCheck = false );
375 SwTextPaintInfo &operator=(const SwTextPaintInfo&) = delete;
376 void NotifyURL_(const SwLinePortion& rPor) const;
378 protected:
379 SwTextPaintInfo()
380 : m_pWrongList(nullptr)
381 , m_pGrammarCheckList(nullptr)
382 , m_pSmartTags(nullptr)
383 , m_pSpaceAdd(nullptr)
384 , m_pBrushItem(nullptr)
385 , m_nSpaceIdx(0)
388 public:
389 SwTextPaintInfo( const SwTextPaintInfo &rInf );
390 SwTextPaintInfo( const SwTextPaintInfo &rInf, const OUString* pText );
392 void CtorInitTextPaintInfo( OutputDevice* pRenderContext, SwTextFrame *pFrame, const SwRect &rPaint );
394 const SvxBrushItem *GetBrushItem() const { return m_pBrushItem; }
396 SwTextPaintInfo( SwTextFrame *pFrame, const SwRect &rPaint );
398 SwTwips X() const { return m_aPos.X(); }
399 void X( const tools::Long nNew ) { m_aPos.setX(nNew); }
400 SwTwips Y() const { return m_aPos.Y(); }
401 void Y( const SwTwips nNew ) { m_aPos.setY(nNew); }
403 SwTextFly& GetTextFly() { return m_aTextFly; }
404 const SwTextFly& GetTextFly() const { return m_aTextFly; }
405 inline void DrawText( const OUString &rText, const SwLinePortion &rPor,
406 TextFrameIndex nIdx = TextFrameIndex(0),
407 TextFrameIndex nLen = TextFrameIndex(COMPLETE_STRING),
408 const bool bKern = false) const;
409 inline void DrawText( const SwLinePortion &rPor, TextFrameIndex nLen,
410 const bool bKern = false ) const;
411 inline void DrawMarkedText( const SwLinePortion &rPor, TextFrameIndex nLen,
412 const bool bWrong,
413 const bool bSmartTags,
414 const bool bGrammarCheck ) const;
416 void DrawRect( const SwRect &rRect, bool bRetouche ) const;
418 void DrawTab( const SwLinePortion &rPor ) const;
419 void DrawLineBreak( const SwLinePortion &rPor ) const;
420 void DrawRedArrow( const SwLinePortion &rPor ) const;
421 void DrawPostIts( bool bScript ) const;
422 void DrawBackground( const SwLinePortion &rPor, const Color *pColor=nullptr ) const;
423 void DrawViewOpt( const SwLinePortion &rPor, PortionType nWhich, const Color *pColor=nullptr ) const;
424 void DrawBackBrush( const SwLinePortion &rPor ) const;
427 * Draw character border around a line portion.
429 * @param[in] rPor line portion around which border have to be drawn.
431 void DrawBorder( const SwLinePortion &rPor ) const;
433 void DrawCheckBox(const SwFieldFormCheckboxPortion &rPor, bool bChecked) const;
435 void DrawCSDFHighlighting(const SwLinePortion &rPor) const;
437 void NotifyURL(const SwLinePortion& rPor) const
439 if (URLNotify())
440 NotifyURL_(rPor);
444 * Calculate the rectangular area where the portion takes place.
445 * @param[in] rPor portion for which the method specify the painting area
446 * @param[out] pRect whole area of the portion
447 * @param[out] pIntersect part of the portion area clipped by OutputDevice's clip region
448 * @param[in] bInsideBox area of portion's content, padding and border, but shadow
449 * is excluded (e.g. for background)
451 void CalcRect( const SwLinePortion& rPor, SwRect* pRect,
452 SwRect* pIntersect = nullptr, const bool bInsideBox = false ) const;
454 inline SwTwips GetPaintOfst() const;
455 inline void SetPaintOfst( const SwTwips nNew );
456 const Point &GetPos() const { return m_aPos; }
457 void SetPos( const Point &rNew ) { m_aPos = rNew; }
459 const SwRect &GetPaintRect() const { return m_aPaintRect; }
461 // STUFF FOR JUSTIFIED ALIGNMENT
463 sal_uInt16 GetSpaceIdx() const { return m_nSpaceIdx; }
464 void ResetSpaceIdx(){m_nSpaceIdx = 0; }
465 void SetSpaceIdx( sal_uInt16 nNew ) { m_nSpaceIdx = nNew; }
466 void IncSpaceIdx() { ++m_nSpaceIdx; }
467 void RemoveFirstSpaceAdd() { m_pSpaceAdd->erase( m_pSpaceAdd->begin() ); }
468 tools::Long GetSpaceAdd( bool bShrink = false ) const
469 { return ( m_pSpaceAdd && m_nSpaceIdx < m_pSpaceAdd->size() &&
470 // get shrink data only if asked explicitly, otherwise zero it
471 ( bShrink || (*m_pSpaceAdd)[m_nSpaceIdx] < LONG_MAX/2 ) )
472 ? (*m_pSpaceAdd)[m_nSpaceIdx] : 0; }
474 void SetpSpaceAdd( std::vector<tools::Long>* pNew ){ m_pSpaceAdd = pNew; }
475 std::vector<tools::Long>* GetpSpaceAdd() const { return m_pSpaceAdd; }
477 void SetWrongList(sw::WrongListIterator *const pNew) { m_pWrongList = pNew; }
478 sw::WrongListIterator* GetpWrongList() const { return m_pWrongList; }
480 void SetGrammarCheckList(sw::WrongListIterator *const pNew) { m_pGrammarCheckList = pNew; }
481 sw::WrongListIterator* GetGrammarCheckList() const { return m_pGrammarCheckList; }
483 void SetSmartTags(sw::WrongListIterator *const pNew) { m_pSmartTags = pNew; }
484 sw::WrongListIterator* GetSmartTags() const { return m_pSmartTags; }
487 class SwTextFormatInfo : public SwTextPaintInfo
489 // temporary arguments for hyphenation
490 css::beans::PropertyValues m_aHyphVals;
492 SwLineLayout *m_pRoot; // The Root of the current line (pCurr)
493 SwLinePortion *m_pLast; // The last Portion
494 SwFlyPortion *m_pFly; // The following FlyPortion
495 SwLinePortion *m_pUnderflow; // Underflow: Last Portion
496 SwLinePortion *m_pRest; // The Rest is the start of the next Line
498 SwTabPortion *m_pLastTab; // The _last_ TabPortion
500 TextFrameIndex m_nSoftHyphPos; ///< SoftHyphPos for Hyphenation
501 TextFrameIndex m_nLineStart; ///< Current line start in rText
502 TextFrameIndex m_nLastBookmarkPos; ///< need to check for bookmarks at every portion
503 // #i34348# Changed type from sal_uInt16 to SwTwips
504 SwTwips m_nLeft; // Left margin
505 SwTwips m_nRight; // Right margin
506 SwTwips m_nFirst; // EZE
507 /// First or left margin, depending on context.
508 SwTwips m_nLeftMargin = 0;
509 SwTwips m_nRealWidth; // "real" line width
510 SwTwips m_nWidth; // "virtual" line width
511 SwTwips m_nLineHeight; // Final height after CalcLine
512 SwTwips m_nLineNetHeight; // line height without spacing
513 SwTwips m_nForcedLeftMargin; // Shift of left margin due to frame
514 SwTwips m_nExtraAscent = 0; // Enlarge clipping area for glyphs above the line height
515 SwTwips m_nExtraDescent = 0; // Enlarge clipping area for glyphs below the line height
517 bool m_bFull : 1; // Line is full
518 bool m_bFootnoteDone : 1; // Footnote already formatted
519 bool m_bErgoDone : 1; // ErgoDone already formatted
520 bool m_bNumDone : 1; // bNumDone already formatted
521 bool m_bArrowDone : 1; // Arrow to the left for scrolling paragraphs
522 bool m_bStop : 1; // Cancel immediately, discarding the line
523 bool m_bNewLine : 1; // Format another line
524 bool m_bShift : 1; // Position change: Repaint until further notice
525 bool m_bUnderflow : 1; // Context: Underflow() ?
526 bool m_bInterHyph : 1; // Interactive hyphenation?
527 bool m_bAutoHyph : 1; // Automatic hyphenation?
528 bool m_bDropInit : 1; // Set DropWidth
529 bool m_bQuick : 1; // FormatQuick()
530 bool m_bNoEndHyph : 1; // Switch off hyphenation at the line end (due to MaxHyphens)
531 bool m_bNoMidHyph : 1; // Switch off hyphenation before flys (due to MaxHyphens)
532 bool m_bIgnoreFly : 1; // FitToContent ignores flys
533 bool m_bFakeLineStart : 1; // String has been replaced by field portion
534 // info structure only pretends that we are at
535 // the beginning of a line
536 bool m_bTabOverflow : 1; // Tabs are expanding after the end margin
537 bool m_bTestFormat : 1; // Test formatting from WouldFit, no notification etc.
539 sal_Unicode m_cTabDecimal; // the current decimal delimiter
540 sal_Unicode m_cHookChar; // For tabs in fields etc.
541 sal_uInt8 m_nMaxHyph; // Max. line count of followup hyphenations
543 // Used to stop justification after center/right/decimal tab stops - see tdf#tdf#106234
544 enum class TabSeen
546 None,
547 Left,
548 Center,
549 Right,
550 Decimal,
551 } m_eLastTabsSeen = TabSeen::None;
553 // Hyphenating ...
554 bool InitHyph( const bool bAuto = false );
555 bool CheckFootnotePortion_( SwLineLayout const * pCurr );
557 public:
558 void CtorInitTextFormatInfo( OutputDevice* pRenderContext, SwTextFrame *pFrame, const bool bInterHyph = false,
559 const bool bQuick = false, const bool bTst = false );
560 SwTextFormatInfo(OutputDevice* pRenderContext, SwTextFrame *pFrame, const bool bInterHyphL = false,
561 const bool bQuickL = false, const bool bTst = false);
563 // For the formatting inside a double line in a line (multi-line portion)
564 // we need a modified text-format-info:
565 SwTextFormatInfo( const SwTextFormatInfo& rInf, SwLineLayout& rLay,
566 SwTwips nActWidth );
568 SwTwips Width() const { return m_nWidth; }
569 void Width(const SwTwips nNew) { m_nWidth = nNew; }
570 void Init();
573 * Returns the distance between the current horizontal position and the end
574 * of the line.
576 SwTwips GetLineWidth();
578 // Returns the first changed position of the paragraph
579 inline TextFrameIndex GetReformatStart() const;
581 // Margins
582 SwTwips Left() const { return m_nLeft; }
583 void Left( const SwTwips nNew ) { m_nLeft = nNew; }
584 SwTwips Right() const { return m_nRight; }
585 void Right( const SwTwips nNew ) { m_nRight = nNew; }
586 SwTwips First() const { return m_nFirst; }
587 void First( const SwTwips nNew ) { m_nFirst = nNew; }
588 void LeftMargin( const SwTwips nNew) { m_nLeftMargin = nNew; }
589 SwTwips RealWidth() const { return m_nRealWidth; }
590 void RealWidth(const SwTwips nNew) { m_nRealWidth = nNew; }
591 SwTwips ForcedLeftMargin() const { return m_nForcedLeftMargin; }
592 void ForcedLeftMargin(const SwTwips nN) { m_nForcedLeftMargin = nN; }
594 sal_uInt8 &MaxHyph() { return m_nMaxHyph; }
595 const sal_uInt8 &MaxHyph() const { return m_nMaxHyph; }
597 SwLineLayout *GetRoot() { return m_pRoot; }
598 const SwLineLayout *GetRoot() const { return m_pRoot; }
600 void SetRoot( SwLineLayout *pNew ) { m_pRoot = pNew; }
601 SwLinePortion *GetLast() { return m_pLast; }
602 void SetLast(SwLinePortion* pNewLast);
603 bool IsFull() const { return m_bFull; }
604 void SetFull( const bool bNew ) { m_bFull = bNew; }
605 bool IsHyphForbud() const
606 { return m_pFly ? m_bNoMidHyph : m_bNoEndHyph; }
607 void ChkNoHyph( const sal_uInt8 bEnd, const sal_uInt8 bMid )
608 { m_bNoEndHyph = (m_nMaxHyph && bEnd >= m_nMaxHyph);
609 m_bNoMidHyph = (m_nMaxHyph && bMid >= m_nMaxHyph); }
610 bool IsIgnoreFly() const { return m_bIgnoreFly; }
611 void SetIgnoreFly( const bool bNew ) { m_bIgnoreFly = bNew; }
612 bool IsFakeLineStart() const { return m_bFakeLineStart; }
613 void SetFakeLineStart( const bool bNew ) { m_bFakeLineStart = bNew; }
614 bool IsStop() const { return m_bStop; }
615 void SetStop( const bool bNew ) { m_bStop = bNew; }
616 SwLinePortion *GetRest() { return m_pRest; }
617 void SetRest( SwLinePortion *pNewRest ) { m_pRest = pNewRest; }
618 bool IsNewLine() const { return m_bNewLine; }
619 void SetNewLine( const bool bNew ) { m_bNewLine = bNew; }
620 bool IsShift() const { return m_bShift; }
621 void SetShift( const bool bNew ) { m_bShift = bNew; }
622 bool IsInterHyph() const { return m_bInterHyph; }
623 bool IsUnderflow() const { return m_bUnderflow; }
624 void ClrUnderflow() { m_bUnderflow = false; }
625 bool IsDropInit() const { return m_bDropInit; }
626 void SetDropInit( const bool bNew ) { m_bDropInit = bNew; }
627 bool IsQuick() const { return m_bQuick; }
628 bool IsTest() const { return m_bTestFormat; }
629 // see tdf#106234
630 void UpdateTabSeen(PortionType);
631 bool DontBlockJustify() const
633 return m_eLastTabsSeen == TabSeen::Center || m_eLastTabsSeen == TabSeen::Right
634 || m_eLastTabsSeen == TabSeen::Decimal;
637 TextFrameIndex GetLineStart() const { return m_nLineStart; }
638 void SetLineStart(TextFrameIndex const nNew) { m_nLineStart = nNew; }
640 // these are used during fly calculation
641 SwTwips GetLineHeight() const { return m_nLineHeight; }
642 void SetLineHeight(const SwTwips nNew) { m_nLineHeight = nNew; }
643 SwTwips GetLineNetHeight() const { return m_nLineNetHeight; }
644 void SetLineNetHeight(const SwTwips nNew) { m_nLineNetHeight = nNew; }
646 const SwLinePortion *GetUnderflow() const { return m_pUnderflow; }
647 SwLinePortion *GetUnderflow() { return m_pUnderflow; }
648 void SetUnderflow( SwLinePortion *pNew )
649 { m_pUnderflow = pNew; m_bUnderflow = true; }
650 TextFrameIndex GetSoftHyphPos() const { return m_nSoftHyphPos; }
651 void SetSoftHyphPos(TextFrameIndex const nNew) { m_nSoftHyphPos = nNew; }
653 inline void SetParaFootnote();
655 // FlyFrames
656 SwFlyPortion *GetFly() { return m_pFly; }
657 void SetFly( SwFlyPortion *pNew ) { m_pFly = pNew; }
659 inline const SwAttrSet& GetCharAttr() const;
661 // Tabs
662 SwTabPortion *GetLastTab() { return m_pLastTab; }
663 void SetLastTab( SwTabPortion *pNew ) { m_pLastTab = pNew; }
664 sal_Unicode GetTabDecimal() const { return m_cTabDecimal; }
665 void SetTabDecimal( const sal_Unicode cNew ) { m_cTabDecimal = cNew;}
667 void ClearHookChar() { m_cHookChar = 0; }
668 void SetHookChar( const sal_Unicode cNew ) { m_cHookChar = cNew; }
669 sal_Unicode GetHookChar() const { return m_cHookChar; }
671 // Done-Flags
672 bool IsFootnoteDone() const { return m_bFootnoteDone; }
673 void SetFootnoteDone( const bool bNew ) { m_bFootnoteDone = bNew; }
674 bool IsErgoDone() const { return m_bErgoDone; }
675 void SetErgoDone( const bool bNew ) { m_bErgoDone = bNew; }
676 bool IsNumDone() const { return m_bNumDone; }
677 void SetNumDone( const bool bNew ) { m_bNumDone = bNew; }
678 bool IsArrowDone() const { return m_bArrowDone; }
679 void SetArrowDone( const bool bNew ) { m_bArrowDone = bNew; }
681 bool CheckCurrentPosBookmark();
683 // For SwTextPortion::Hyphenate
684 bool ChgHyph( const bool bNew );
686 // Should the hyphenate helper be discarded?
687 bool IsHyphenate() const;
689 SwTwips GetExtraAscent() const { return m_nExtraAscent; }
690 void SetExtraAscent(SwTwips nNew) { m_nExtraAscent = std::max(m_nExtraAscent, nNew); }
692 SwTwips GetExtraDescent() const { return m_nExtraDescent; }
693 void SetExtraDescent(SwTwips nNew) { m_nExtraDescent = std::max(m_nExtraDescent, nNew); }
695 // Calls HyphenateWord() of Hyphenator
696 css::uno::Reference< css::linguistic2::XHyphenatedWord >
697 HyphWord( const OUString &rText, const sal_Int32 nMinTrail );
698 const css::beans::PropertyValues & GetHyphValues() const;
700 bool CheckFootnotePortion( SwLineLayout const * pCurr )
701 { return IsFootnoteInside() && CheckFootnotePortion_( pCurr ); }
703 // Dropcaps called by SwTextFormatter::CTOR
704 const SwFormatDrop *GetDropFormat() const;
706 // Sets the last SwKernPortion as pLast, if it is followed by empty portions
707 bool LastKernPortion();
709 // Looks for tabs, TabDec, TXTATR and BRK from nIdx until nEnd.
710 // Return: Position; sets cHookChar if necessary
711 TextFrameIndex ScanPortionEnd(TextFrameIndex nStart, TextFrameIndex nEnd);
713 void SetTabOverflow( bool bOverflow ) { m_bTabOverflow = bOverflow; }
714 bool IsTabOverflow() const { return m_bTabOverflow; }
719 * For the text replacement and restoration of SwTextSizeInfo.
720 * The way this is done is a bit of a hack: Although rInf is const we change it
721 * anyway.
722 * Because rInf is restored again in the DTOR, we can do this.
723 * You could call it a "logical const", if you wish.
725 class SwTextSlot final
727 OUString aText;
728 std::shared_ptr<const vcl::text::TextLayoutCache> m_pOldCachedVclData;
729 const OUString *pOldText;
730 sw::WrongListIterator * m_pOldSmartTagList;
731 sw::WrongListIterator * m_pOldGrammarCheckList;
732 std::unique_ptr<SwWrongList> m_pTempList;
733 std::unique_ptr<sw::WrongListIterator> m_pTempIter;
734 TextFrameIndex nIdx;
735 TextFrameIndex nLen;
736 TextFrameIndex nMeasureLen;
737 bool bOn;
738 SwTextSizeInfo *pInf;
740 public:
741 // The replacement string originates either from the portion via GetExpText()
742 // or from the rCh, if it is not empty.
743 SwTextSlot( const SwTextSizeInfo *pNew, const SwLinePortion *pPor, bool bTextLen,
744 bool bExgLists, OUString const & rCh = OUString() );
745 ~SwTextSlot();
748 class SwFontSave
750 SwTextSizeInfo *pInf;
751 SwFont *pFnt;
752 SwAttrIter *pIter;
753 public:
754 SwFontSave( const SwTextSizeInfo &rInf, SwFont *pFnt,
755 SwAttrIter* pItr = nullptr );
756 ~SwFontSave();
759 inline sal_uInt16 SwTextSizeInfo::GetAscent() const
761 assert(GetOut());
762 return const_cast<SwFont*>(GetFont())->GetAscent( m_pVsh, *GetOut() );
765 inline sal_uInt16 SwTextSizeInfo::GetTextHeight() const
767 assert(GetOut());
768 return const_cast<SwFont*>(GetFont())->GetHeight(m_pVsh, *GetOut(), SnapToGrid());
771 inline sal_uInt16 SwTextSizeInfo::GetHangingBaseline() const
773 assert(GetOut());
774 return const_cast<SwFont*>(GetFont())->GetHangingBaseline( m_pVsh, *GetOut() );
777 inline SwPosSize SwTextSizeInfo::GetTextSize( const OUString &rText ) const
779 return GetTextSize(m_pOut, nullptr, rText, TextFrameIndex(0), TextFrameIndex(rText.getLength()));
782 inline SwPosSize SwTextSizeInfo::GetTextSize( const SwScriptInfo* pSI,
783 TextFrameIndex const nNewIdx,
784 TextFrameIndex const nNewLen) const
786 return GetTextSize( m_pOut, pSI, *m_pText, nNewIdx, nNewLen );
789 inline SwTwips SwTextPaintInfo::GetPaintOfst() const
791 return GetParaPortion()->GetRepaint().GetOffset();
794 inline void SwTextPaintInfo::SetPaintOfst( const SwTwips nNew )
796 GetParaPortion()->GetRepaint().SetOffset( nNew );
799 inline void SwTextPaintInfo::DrawText( const OUString &rText,
800 const SwLinePortion &rPor,
801 const TextFrameIndex nStart, const TextFrameIndex nLength,
802 const bool bKern ) const
804 const_cast<SwTextPaintInfo*>(this)->DrawText_( rText, rPor, nStart, nLength, bKern );
807 inline void SwTextPaintInfo::DrawText( const SwLinePortion &rPor,
808 const TextFrameIndex nLength, const bool bKern ) const
810 const_cast<SwTextPaintInfo*>(this)->DrawText_( *m_pText, rPor, m_nIdx, nLength, bKern );
813 inline void SwTextPaintInfo::DrawMarkedText( const SwLinePortion &rPor,
814 const TextFrameIndex nLength,
815 const bool bWrong,
816 const bool bSmartTags,
817 const bool bGrammarCheck ) const
819 const_cast<SwTextPaintInfo*>(this)->DrawText_( *m_pText, rPor, m_nIdx, nLength, false/*bKern*/, bWrong, bSmartTags, bGrammarCheck );
822 inline TextFrameIndex SwTextFormatInfo::GetReformatStart() const
824 return GetParaPortion()->GetReformat().Start();
827 inline const SwAttrSet& SwTextFormatInfo::GetCharAttr() const
829 // sw_redlinehide: this is used for numbering/footnote number portions, so:
830 return GetTextFrame()->GetTextNodeForParaProps()->GetSwAttrSet();
833 inline void SwTextFormatInfo::SetParaFootnote()
835 GetTextFrame()->SetFootnote( true );
838 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */