Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : #ifndef INCLUDED_SW_SOURCE_CORE_TEXT_INFTXT_HXX
20 : #define INCLUDED_SW_SOURCE_CORE_TEXT_INFTXT_HXX
21 : #include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
22 : #include <com/sun/star/beans/PropertyValues.hpp>
23 :
24 : #include <map>
25 :
26 : #include "swtypes.hxx"
27 : #include "swrect.hxx"
28 : #include "txtfly.hxx"
29 : #include "swfont.hxx"
30 : #include "porlay.hxx"
31 : #include "txtfrm.hxx"
32 : #include "ndtxt.hxx"
33 : #include <editeng/paravertalignitem.hxx>
34 : #include <sal/log.hxx>
35 :
36 : namespace vcl { class Font; }
37 : class OutputDevice;
38 : class SvxBrushItem;
39 : class SvxLineSpacingItem;
40 : class SvxTabStop;
41 : class SvxTabStopItem;
42 : class SwAttrSet;
43 : class SwFieldPortion;
44 : class SwFlyPortion;
45 : class SwFormatDrop;
46 : class SwLineLayout;
47 : class SwLinePortion;
48 : class SwParaPortion;
49 : class SwTabPortion;
50 : class SwTextFrm;
51 : class SwTextSizeInfo;
52 : class SwViewOption;
53 : class SwViewShell;
54 : class SwAttrIter;
55 : struct SwMultiCreator;
56 : class SwMultiPortion;
57 : class SwWrongList;
58 :
59 : #define ARROW_WIDTH 200
60 : #define DIR_LEFT2RIGHT 0
61 : #define DIR_BOTTOM2TOP 1
62 : #define DIR_RIGHT2LEFT 2
63 : #define DIR_TOP2BOTTOM 3
64 :
65 : #ifdef DBG_UTIL
66 : #define OPTDBG( rInf ) (rInf).IsOptDbg()
67 : #else
68 : #define OPTDBG( rInf ) false
69 : #endif
70 :
71 : // Respects the attribute LineSpace when calculating the Height/Ascent
72 : class SwLineInfo
73 : {
74 : friend class SwTextIter;
75 :
76 : SvxTabStopItem* pRuler;
77 : const SvxLineSpacingItem *pSpace;
78 : sal_uInt16 nVertAlign;
79 : sal_uInt16 nDefTabStop;
80 : bool bListTabStopIncluded;
81 : long nListTabStopPosition;
82 :
83 : void CtorInitLineInfo( const SwAttrSet& rAttrSet,
84 : const SwTextNode& rTextNode );
85 :
86 : SwLineInfo();
87 : ~SwLineInfo();
88 : public:
89 : // #i24363# tab stops relative to indent - returns the tab stop following nSearchPos or NULL
90 : const SvxTabStop *GetTabStop( const SwTwips nSearchPos,
91 : const SwTwips nRight ) const;
92 103876 : inline const SvxLineSpacingItem *GetLineSpacing() const { return pSpace; }
93 14189 : inline sal_uInt16 GetDefTabStop() const { return nDefTabStop; }
94 6709 : inline void SetDefTabStop( sal_uInt16 nNew ) const
95 6709 : { const_cast<SwLineInfo*>(this)->nDefTabStop = nNew; }
96 :
97 : // vertical alignment
98 57108 : inline sal_uInt16 GetVertAlign() const { return nVertAlign; }
99 21431 : inline bool HasSpecialAlign( bool bVert ) const
100 : { return bVert ?
101 0 : ( SvxParaVertAlignItem::BASELINE != nVertAlign ) :
102 42787 : ( SvxParaVertAlignItem::BASELINE != nVertAlign &&
103 64218 : SvxParaVertAlignItem::AUTOMATIC != nVertAlign ); }
104 :
105 : sal_uInt16 NumberOfTabStops() const;
106 :
107 5952 : inline bool IsListTabStopIncluded() const
108 : {
109 5952 : return bListTabStopIncluded;
110 : }
111 3964 : inline long GetListTabStopPosition() const
112 : {
113 3964 : return nListTabStopPosition;
114 : }
115 :
116 : friend SvStream & WriteSwLineInfo( SvStream &rOS, const SwLineInfo &rInf );
117 : };
118 :
119 : class SwTextInfo
120 : {
121 : // Implementation in txthyph.cxx
122 : friend void SetParaPortion( SwTextInfo *pInf, SwParaPortion *pRoot );
123 : SwParaPortion *m_pPara;
124 : sal_Int32 m_nTextStart; // TextOfst for Follows
125 :
126 : protected:
127 184615 : SwTextInfo()
128 : : m_pPara(0)
129 184615 : , m_nTextStart(0)
130 184615 : {}
131 :
132 : public:
133 : void CtorInitTextInfo( SwTextFrm *pFrm );
134 : SwTextInfo( const SwTextInfo &rInf );
135 218 : explicit SwTextInfo( SwTextFrm *pFrm ) { CtorInitTextInfo( pFrm ); }
136 1447079 : SwParaPortion *GetParaPortion() { return m_pPara; }
137 829696 : const SwParaPortion *GetParaPortion() const { return m_pPara; }
138 740210 : sal_Int32 GetTextStart() const { return m_nTextStart; }
139 :
140 : friend SvStream & WriteSwTextInfo( SvStream &rOS, const SwTextInfo &rInf );
141 : };
142 :
143 311094 : class SwTextSizeInfo : public SwTextInfo
144 : {
145 : private:
146 : typedef ::std::map< sal_uIntPtr, sal_uInt16 > SwTextPortionMap;
147 :
148 : protected:
149 : // during formatting, a small database is built, mapping portion pointers
150 : // to their maximum size (used for kana compression)
151 : SwTextPortionMap m_aMaxWidth;
152 : // for each line, an array of compression values is calculated
153 : // this array is passed over to the info structure
154 : std::deque<sal_uInt16>* m_pKanaComp;
155 :
156 : SwViewShell *m_pVsh;
157 :
158 : // m_pOut is the output device, m_pRef is the device used for formatting
159 : VclPtr<OutputDevice> m_pOut;
160 : VclPtr<OutputDevice> m_pRef;
161 :
162 : // performance hack - this is only used by SwTextFormatInfo but
163 : // because it's not even possible to dynamic_cast these things
164 : // currently it has to be stored here
165 : std::shared_ptr<vcl::TextLayoutCache> m_pCachedVclData;
166 :
167 : SwFont *m_pFnt;
168 : SwUnderlineFont *m_pUnderFnt; // Font for underlining
169 : SwTextFrm *m_pFrm;
170 : const SwViewOption *m_pOpt;
171 : const OUString *m_pText;
172 : sal_Int32 m_nIdx, m_nLen;
173 : sal_uInt16 m_nKanaIdx;
174 : bool m_bOnWin : 1;
175 : bool m_bNotEOL : 1;
176 : bool m_bURLNotify : 1;
177 : bool m_bStopUnderflow : 1; // Underflow was stopped e.g. by a FlyPortion
178 : bool m_bFootnoteInside : 1; // the current line contains a footnote
179 : bool m_bOtherThanFootnoteInside : 1; // the current line contains another portion than a footnote portion.
180 : // needed for checking keep together of footnote portion with previous portion
181 : bool m_bMulti : 1; // inside a multiportion
182 : bool m_bFirstMulti : 1; // this flag is used for two purposes:
183 : // - the multiportion is the first lineportion
184 : // - indicates, if we are currently in second
185 : // line of multi portion
186 : bool m_bRuby : 1; // during the formatting of a phonetic line
187 : bool m_bHanging : 1; // formatting of hanging punctuation allowed
188 : bool m_bScriptSpace : 1; // space between different scripts (Asian/Latin)
189 : bool m_bForbiddenChars : 1; // Forbidden start/endline characters
190 : bool m_bSnapToGrid : 1; // paragraph snaps to grid
191 : sal_uInt8 m_nDirection : 2; // writing direction: 0/90/180/270 degree
192 :
193 : protected:
194 : void CtorInitTextSizeInfo( SwTextFrm *pFrm, SwFont *pFnt = 0,
195 : const sal_Int32 nIdx = 0,
196 : const sal_Int32 nLen = COMPLETE_STRING );
197 69633 : SwTextSizeInfo()
198 : : m_pKanaComp(0)
199 : , m_pVsh(0)
200 : , m_pOut(0)
201 : , m_pRef(0)
202 : , m_pFnt(0)
203 : , m_pUnderFnt(0)
204 : , m_pFrm(0)
205 : , m_pOpt(0)
206 : , m_pText(0)
207 : , m_nIdx(0)
208 : , m_nLen(0)
209 : , m_nKanaIdx(0)
210 : , m_bOnWin (false)
211 : , m_bNotEOL (false)
212 : , m_bURLNotify(false)
213 : , m_bStopUnderflow(false)
214 : , m_bFootnoteInside(false)
215 : , m_bOtherThanFootnoteInside(false)
216 : , m_bMulti(false)
217 : , m_bFirstMulti(false)
218 : , m_bRuby(false)
219 : , m_bHanging(false)
220 : , m_bScriptSpace(false)
221 : , m_bForbiddenChars(false)
222 : , m_bSnapToGrid(false)
223 69633 : , m_nDirection(0)
224 69633 : {}
225 : public:
226 : SwTextSizeInfo( const SwTextSizeInfo &rInf );
227 : SwTextSizeInfo( const SwTextSizeInfo &rInf, const OUString* pText,
228 : const sal_Int32 nIdx = 0,
229 : const sal_Int32 nLen = COMPLETE_STRING );
230 :
231 114982 : SwTextSizeInfo( SwTextFrm *pTextFrm, SwFont *pTextFnt = 0,
232 : const sal_Int32 nIndex = 0,
233 : const sal_Int32 nLength = COMPLETE_STRING )
234 114982 : : m_bOnWin(false)
235 : {
236 114982 : CtorInitTextSizeInfo( pTextFrm, pTextFnt, nIndex, nLength );
237 114982 : }
238 :
239 : // GetMultiAttr returns the text attribute of the multiportion,
240 : // if rPos is inside any multi-line part.
241 : // rPos will set to the end of the multi-line part.
242 : SwMultiCreator* GetMultiCreator( sal_Int32 &rPos, SwMultiPortion* pM ) const;
243 :
244 419891 : inline bool OnWin() const { return m_bOnWin; }
245 173078 : inline void SetOnWin( const bool bNew ) { m_bOnWin = bNew; }
246 132441 : inline bool NotEOL() const { return m_bNotEOL; }
247 26822 : inline void SetNotEOL( const bool bNew ) { m_bNotEOL = bNew; }
248 126479 : inline bool URLNotify() const { return m_bURLNotify; }
249 : inline void SetURLNotify( const bool bNew ) { m_bURLNotify = bNew; }
250 126509 : inline bool StopUnderflow() const { return m_bStopUnderflow; }
251 215318 : inline void SetStopUnderflow( const bool bNew ) { m_bStopUnderflow = bNew; }
252 206642 : inline bool IsFootnoteInside() const { return m_bFootnoteInside; }
253 80330 : inline void SetFootnoteInside( const bool bNew ) { m_bFootnoteInside = bNew; }
254 257104 : inline bool IsOtherThanFootnoteInside() const { return m_bOtherThanFootnoteInside; }
255 210810 : inline void SetOtherThanFootnoteInside( const bool bNew ) { m_bOtherThanFootnoteInside = bNew; }
256 258109 : inline bool IsMulti() const { return m_bMulti; }
257 2432 : inline void SetMulti( const bool bNew ) { m_bMulti = bNew; }
258 129604 : inline bool IsFirstMulti() const { return m_bFirstMulti; }
259 709 : inline void SetFirstMulti( const bool bNew ) { m_bFirstMulti = bNew; }
260 257424 : inline bool IsRuby() const { return m_bRuby; }
261 443 : inline void SetRuby( const bool bNew ) { m_bRuby = bNew; }
262 160259 : inline bool IsHanging() const { return m_bHanging; }
263 55817 : inline void SetHanging( const bool bNew ) { m_bHanging = bNew; }
264 351421 : inline bool HasScriptSpace() const { return m_bScriptSpace; }
265 55817 : inline void SetScriptSpace( const bool bNew ) { m_bScriptSpace = bNew; }
266 160259 : inline bool HasForbiddenChars() const { return m_bForbiddenChars; }
267 55817 : inline void SetForbiddenChars( const bool bN ) { m_bForbiddenChars = bN; }
268 300230 : inline bool SnapToGrid() const { return m_bSnapToGrid; }
269 185078 : inline void SetSnapToGrid( const bool bN ) { m_bSnapToGrid = bN; }
270 715051 : inline sal_uInt8 GetDirection() const { return m_nDirection; }
271 338 : inline void SetDirection( const sal_uInt8 nNew ) { m_nDirection = nNew; }
272 326496 : inline bool IsRotated() const { return ( 1 & m_nDirection ); }
273 :
274 270547 : inline SwViewShell *GetVsh() { return m_pVsh; }
275 351917 : inline const SwViewShell *GetVsh() const { return m_pVsh; }
276 :
277 632777 : inline vcl::RenderContext *GetOut() { return m_pOut; }
278 499857 : inline const vcl::RenderContext *GetOut() const { return m_pOut; }
279 168545 : inline void SetOut( OutputDevice* pNewOut ) { m_pOut = pNewOut; }
280 :
281 210809 : inline vcl::RenderContext *GetRefDev() { return m_pRef; }
282 : inline const vcl::RenderContext *GetRefDev() const { return m_pRef; }
283 :
284 1620724 : inline SwFont *GetFont() { return m_pFnt; }
285 642362 : inline const SwFont *GetFont() const { return m_pFnt; }
286 295160 : inline void SetFont( SwFont *pNew ) { m_pFnt = pNew; }
287 : void SelectFont();
288 56438 : inline void SetUnderFnt( SwUnderlineFont* pNew ) { m_pUnderFnt = pNew; }
289 218295 : inline SwUnderlineFont* GetUnderFnt() const { return m_pUnderFnt; }
290 :
291 524214 : inline const SwViewOption &GetOpt() const { return *m_pOpt; }
292 2419746 : inline const OUString &GetText() const { return *m_pText; }
293 4052507 : inline sal_Unicode GetChar( const sal_Int32 nPos ) const
294 4052507 : { if (m_pText && nPos < m_pText->getLength()) return (*m_pText)[ nPos ]; return 0; }
295 :
296 : sal_uInt16 GetTextHeight() const;
297 :
298 : SwPosSize GetTextSize( OutputDevice* pOut, const SwScriptInfo* pSI,
299 : const OUString& rText, const sal_Int32 nIdx,
300 : const sal_Int32 nLen, const sal_uInt16 nComp ) const;
301 : SwPosSize GetTextSize() const;
302 : void GetTextSize( const SwScriptInfo* pSI, const sal_Int32 nIdx,
303 : const sal_Int32 nLen, const sal_uInt16 nComp,
304 : sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff,
305 : vcl::TextLayoutCache const* = nullptr) const;
306 : inline SwPosSize GetTextSize( const SwScriptInfo* pSI, const sal_Int32 nIdx,
307 : const sal_Int32 nLen, const sal_uInt16 nComp ) const;
308 : inline SwPosSize GetTextSize( const OUString &rText ) const;
309 :
310 : sal_Int32 GetTextBreak( const long nLineWidth,
311 : const sal_Int32 nMaxLen,
312 : const sal_uInt16 nComp,
313 : vcl::TextLayoutCache const* = nullptr) const;
314 : sal_Int32 GetTextBreak( const long nLineWidth,
315 : const sal_Int32 nMaxLen,
316 : const sal_uInt16 nComp,
317 : sal_Int32& rExtraCharPos,
318 : vcl::TextLayoutCache const* = nullptr) const;
319 :
320 : sal_uInt16 GetAscent() const;
321 :
322 4173964 : inline sal_Int32 GetIdx() const { return m_nIdx; }
323 629839 : inline void SetIdx( const sal_Int32 nNew ) { m_nIdx = nNew; }
324 850850 : inline sal_Int32 GetLen() const { return m_nLen; }
325 750292 : inline void SetLen( const sal_Int32 nNew ) { m_nLen = nNew; }
326 47666 : inline void SetText( const OUString &rNew ){ m_pText = &rNew; }
327 :
328 : friend SvStream & WriteSwTextSizeInfo( SvStream &rOS, const SwTextSizeInfo &rInf );
329 :
330 : // No Bullets for the symbol font!
331 0 : inline bool IsNoSymbol() const
332 0 : { return RTL_TEXTENCODING_SYMBOL != m_pFnt->GetCharSet( m_pFnt->GetActual() ); }
333 :
334 : void NoteAnimation() const;
335 :
336 : // Home is where Your heart is...
337 1132329 : inline SwTextFrm *GetTextFrm() { return m_pFrm; }
338 615217 : inline const SwTextFrm *GetTextFrm() const { return m_pFrm; }
339 :
340 7991 : inline bool HasHint( sal_Int32 nPos ) const
341 7991 : { return _HasHint( m_pFrm->GetTextNode(), nPos ); }
342 : static bool _HasHint( const SwTextNode* pTextNode, sal_Int32 nPos );
343 :
344 : // If Kana Compression is enabled, a minimum and maximum portion width
345 : // is calculated. We format lines with minimal size and share remaining
346 : // space among compressed kanas.
347 : // During formatting, the maximum values of compressable portions are
348 : // stored in m_aMaxWidth and discarded after a line has been formatted.
349 0 : inline void SetMaxWidthDiff( const void *nKey, sal_uInt16 nVal )
350 : {
351 0 : m_aMaxWidth.insert( ::std::make_pair( reinterpret_cast<sal_uIntPtr>(nKey), nVal ) );
352 0 : };
353 0 : inline sal_uInt16 GetMaxWidthDiff( const void *nKey )
354 : {
355 0 : SwTextPortionMap::iterator it = m_aMaxWidth.find( reinterpret_cast<sal_uIntPtr>(nKey) );
356 :
357 0 : if( it != m_aMaxWidth.end() )
358 0 : return it->second;
359 : else
360 0 : return 0;
361 : };
362 15 : inline void ResetMaxWidthDiff()
363 : {
364 15 : m_aMaxWidth.clear();
365 15 : };
366 80170 : inline bool CompressLine()
367 : {
368 80170 : return !m_aMaxWidth.empty();
369 : };
370 :
371 : // Feature: Kana Compression
372 :
373 126479 : inline sal_uInt16 GetKanaIdx() const { return m_nKanaIdx; }
374 75776 : inline void ResetKanaIdx(){ m_nKanaIdx = 0; }
375 2324 : inline void SetKanaIdx( sal_uInt16 nNew ) { m_nKanaIdx = nNew; }
376 30974 : inline void IncKanaIdx() { ++m_nKanaIdx; }
377 78100 : inline void SetKanaComp( std::deque<sal_uInt16> *pNew ){ m_pKanaComp = pNew; }
378 126479 : inline std::deque<sal_uInt16>* GetpKanaComp() const { return m_pKanaComp; }
379 20449 : inline sal_uInt16 GetKanaComp() const
380 0 : { return ( m_pKanaComp && m_nKanaIdx < m_pKanaComp->size() )
381 20449 : ? (*m_pKanaComp)[m_nKanaIdx] : 0; }
382 :
383 96102 : std::shared_ptr<vcl::TextLayoutCache> GetCachedVclData() const
384 : {
385 96102 : return m_pCachedVclData;
386 : }
387 103483 : void SetCachedVclData(std::shared_ptr<vcl::TextLayoutCache> const& pCachedVclData)
388 : {
389 103483 : m_pCachedVclData = pCachedVclData;
390 103483 : }
391 :
392 : #ifdef DBG_UTIL
393 : bool IsOptDbg() const;
394 : #endif
395 : };
396 :
397 126835 : class SwTextPaintInfo : public SwTextSizeInfo
398 : {
399 : const SwWrongList *pWrongList;
400 : const SwWrongList *pGrammarCheckList;
401 : const SwWrongList *pSmartTags;
402 : std::vector<long>* pSpaceAdd;
403 : const SvxBrushItem *pBrushItem; // For the background
404 : SwRect aItemRect; // Also for the background
405 : SwTextFly aTextFly; // Calculate the FlyFrm
406 : Point aPos; // Paint position
407 : SwRect aPaintRect; // Original paint rect (from Layout paint)
408 :
409 : sal_uInt16 nSpaceIdx;
410 : void _DrawText( const OUString &rText, const SwLinePortion &rPor,
411 : const sal_Int32 nIdx, const sal_Int32 nLen,
412 : const bool bKern, const bool bWrong = false,
413 : const bool bSmartTag = false,
414 : const bool bGrammarCheck = false );
415 :
416 : SwTextPaintInfo &operator=(const SwTextPaintInfo&) SAL_DELETED_FUNCTION;
417 : void _NotifyURL( const SwLinePortion &rPor ) const;
418 :
419 : protected:
420 55817 : SwTextPaintInfo()
421 : : pWrongList(0)
422 : , pGrammarCheckList(0)
423 : , pSmartTags(0)
424 : , pSpaceAdd(0)
425 : #ifdef DBG_UTIL
426 : , pBrushItem(reinterpret_cast<SvxBrushItem*>(-1))
427 : #else
428 : , pBrushItem(0)
429 : #endif
430 55817 : , nSpaceIdx(0)
431 55817 : {}
432 :
433 : public:
434 : SwTextPaintInfo( const SwTextPaintInfo &rInf );
435 : SwTextPaintInfo( const SwTextPaintInfo &rInf, const OUString* pText );
436 :
437 : void CtorInitTextPaintInfo( SwTextFrm *pFrame, const SwRect &rPaint );
438 :
439 : void SetBack( const SvxBrushItem *pItem,
440 : const SwRect &rRect ) { pBrushItem = pItem; aItemRect = rRect;}
441 57202 : const SvxBrushItem *GetBrushItem() const { return pBrushItem; }
442 0 : const SwRect &GetBrushRect() const { return aItemRect; }
443 :
444 13816 : inline SwTextPaintInfo( SwTextFrm *pFrame, const SwRect &rPaint )
445 13816 : { CtorInitTextPaintInfo( pFrame, rPaint ); }
446 :
447 1099606 : inline SwTwips X() const { return aPos.X(); }
448 406777 : inline void X( const long nNew ) { aPos.X() = nNew; }
449 174411 : inline SwTwips Y() const { return aPos.Y(); }
450 195624 : inline void Y( const SwTwips nNew ) { aPos.Y() = nNew; }
451 :
452 396525 : inline SwTextFly& GetTextFly() { return aTextFly; }
453 108615 : inline const SwTextFly& GetTextFly() const { return aTextFly; }
454 : inline void DrawText( const OUString &rText, const SwLinePortion &rPor,
455 : const sal_Int32 nIdx = 0,
456 : const sal_Int32 nLen = COMPLETE_STRING,
457 : const bool bKern = false) const;
458 : inline void DrawText( const SwLinePortion &rPor, const sal_Int32 nLen,
459 : const bool bKern = false ) const;
460 : inline void DrawMarkedText( const SwLinePortion &rPor, const sal_Int32 nLen,
461 : const bool bKern,
462 : const bool bWrong,
463 : const bool bSmartTags,
464 : const bool bGrammarCheck ) const;
465 :
466 : void DrawRect( const SwRect &rRect, bool bNoGraphic = false,
467 : bool bRetouche = true ) const;
468 :
469 : void DrawTab( const SwLinePortion &rPor ) const;
470 : void DrawLineBreak( const SwLinePortion &rPor ) const;
471 : void DrawRedArrow( const SwLinePortion &rPor ) const;
472 : void DrawPostIts( const SwLinePortion &rPor, bool bScript ) const;
473 : void DrawBackground( const SwLinePortion &rPor ) const;
474 : void DrawViewOpt( const SwLinePortion &rPor, const sal_uInt16 nWhich ) const;
475 : void DrawBackBrush( const SwLinePortion &rPor ) const;
476 :
477 : /**
478 : * Draw character border around a line portion.
479 : *
480 : * @param[in] rPor line portion around which border have to be drawn.
481 : **/
482 : void DrawBorder( const SwLinePortion &rPor ) const;
483 :
484 : void DrawCheckBox(const SwFieldFormCheckboxPortion &rPor, bool bChecked) const;
485 :
486 0 : inline void NotifyURL( const SwLinePortion &rPor ) const
487 0 : { if( URLNotify() ) _NotifyURL( rPor ); }
488 :
489 : /**
490 : * Calculate the rectangular area where the portion takes place.
491 : * @param[in] rPor portion for which the method specify the painting area
492 : * @param[out] pRect whole area of the portion
493 : * @param[out] pIntersect part of the portion area clipped by OutputDevice's clip region
494 : * @param[in] bInsideBox area of portion's content, padding and border, but shadow
495 : * is excluded (e.g. for background)
496 : **/
497 : void CalcRect( const SwLinePortion& rPor, SwRect* pRect,
498 : SwRect* pIntersect = 0, const bool bInsideBox = false ) const;
499 :
500 : inline SwTwips GetPaintOfst() const;
501 : inline void SetPaintOfst( const SwTwips nNew );
502 196792 : inline const Point &GetPos() const { return aPos; }
503 75788 : inline void SetPos( const Point &rNew ) { aPos = rNew; }
504 :
505 98222 : inline const SwRect &GetPaintRect() const { return aPaintRect; }
506 : inline void SetPaintRect( const SwRect &rNew ) { aPaintRect = rNew; }
507 :
508 : friend SvStream & WriteSwTextPaintInfo( SvStream &rOS, const SwTextPaintInfo &rInf );
509 :
510 : // STUFF FOR JUSTIFIED ALIGNMENT
511 :
512 57371 : inline sal_uInt16 GetSpaceIdx() const { return nSpaceIdx; }
513 75936 : inline void ResetSpaceIdx(){nSpaceIdx = 0; }
514 323 : inline void SetSpaceIdx( sal_uInt16 nNew ) { nSpaceIdx = nNew; }
515 30974 : inline void IncSpaceIdx() { ++nSpaceIdx; }
516 0 : inline void RemoveFirstSpaceAdd() { pSpaceAdd->erase( pSpaceAdd->begin() ); }
517 294261 : inline long GetSpaceAdd() const
518 9359 : { return ( pSpaceAdd && nSpaceIdx < pSpaceAdd->size() )
519 303620 : ? (*pSpaceAdd)[nSpaceIdx] : 0; }
520 :
521 76259 : inline void SetpSpaceAdd( std::vector<long>* pNew ){ pSpaceAdd = pNew; }
522 57371 : inline std::vector<long>* GetpSpaceAdd() const { return pSpaceAdd; }
523 :
524 12654 : inline void SetWrongList( const SwWrongList *pNew ){ pWrongList = pNew; }
525 75341 : inline const SwWrongList* GetpWrongList() const { return pWrongList; }
526 :
527 12654 : inline void SetGrammarCheckList( const SwWrongList *pNew ){ pGrammarCheckList = pNew; }
528 79838 : inline const SwWrongList* GetGrammarCheckList() const { return pGrammarCheckList; }
529 :
530 12654 : inline void SetSmartTags( const SwWrongList *pNew ){ pSmartTags = pNew; }
531 79838 : inline const SwWrongList* GetSmartTags() const { return pSmartTags; }
532 : };
533 :
534 59782 : class SwTextFormatInfo : public SwTextPaintInfo
535 : {
536 : // temporary arguments for hyphenation
537 : com::sun::star::beans::PropertyValues aHyphVals;
538 :
539 : SwLineLayout *pRoot; // The Root of the current line (pCurr)
540 : SwLinePortion *pLast; // The last Portion
541 : SwFlyPortion *pFly; // The following FlyPortion
542 : SwFieldPortion *pLastField; // Wrapped Field
543 : SwLinePortion *pUnderflow; // Underflow: Last Portion
544 : SwLinePortion *pRest; // The Rest is the start of the next Line
545 :
546 : SwTabPortion *pLastTab; // The _last_ TabPortion
547 :
548 : sal_Int32 nSoftHyphPos; // SoftHyphPos forr Hyphenation
549 : sal_Int32 nLineStart; // Current line start in rText
550 : sal_Int32 nUnderScorePos; // enlarge repaint if underscore has been found
551 : // #i34348# Changed type from sal_uInt16 to SwTwips
552 : SwTwips nLeft; // Left margin
553 : SwTwips nRight; // Right margin
554 : SwTwips nFirst; // EZE
555 : sal_uInt16 nRealWidth; // "real" line width
556 : sal_uInt16 nWidth; // "virtual" line width
557 : sal_uInt16 nLineHeight; // Final height after CalcLine
558 : sal_uInt16 nLineNetHeight; // line height without spacing
559 : sal_uInt16 nForcedLeftMargin; // Shift of left margin due to frame
560 :
561 : sal_Int16 nMinLeading; // minimum number of chars before hyphenation point
562 : sal_Int16 nMinTrailing; // minimum number of chars after hyphenation point
563 : sal_Int16 nMinWordLength; // minimum length of word to be hyphenated
564 :
565 : bool bFull : 1; // Line is full
566 : bool bFootnoteDone : 1; // Footnote already formatted
567 : bool bErgoDone : 1; // ErgoDone already formatted
568 : bool bNumDone : 1; // bNumDone already formatted
569 : bool bArrowDone : 1; // Arrow to the left for scrolling paragraphs
570 : bool bStop : 1; // Cancel immediately, discarding the line
571 : bool bNewLine : 1; // Format another line
572 : bool bShift : 1; // Position change: Repaint until further notice
573 : bool bUnderflow : 1; // Context: Underflow() ?
574 : bool bInterHyph : 1; // Interactive hyphenation?
575 : bool bAutoHyph : 1; // Automatic hyphenation?
576 : bool bDropInit : 1; // Set DropWidth
577 : bool bQuick : 1; // FormatQuick()
578 : bool bNoEndHyph : 1; // Switch off hyphenation at the line end (due to MaxHyphens)
579 : bool bNoMidHyph : 1; // Switch off hyphenation before flys (due to MaxHyphens)
580 : bool bIgnoreFly : 1; // FitToContent ignores flys
581 : bool bFakeLineStart : 1; // String has been replaced by field portion
582 : // info structure only pretends that we are at
583 : // the beginning of a line
584 : bool bTabOverflow : 1; // Tabs are expanding after the end margin
585 : bool bTestFormat : 1; // Test formatting from WouldFit, no notification etc.
586 :
587 : sal_Unicode cTabDecimal; // the current decimal delimiter
588 : sal_Unicode cHookChar; // For tabs in fields etc.
589 : sal_uInt8 nMaxHyph; // Max. line count of followup hyphenations
590 :
591 : // Hyphenating ...
592 : bool InitHyph( const bool bAuto = false );
593 : bool _CheckFootnotePortion( SwLineLayout* pCurr );
594 :
595 : public:
596 : void CtorInitTextFormatInfo( SwTextFrm *pFrm, const bool bInterHyph = false,
597 : const bool bQuick = false, const bool bTst = false );
598 55817 : inline SwTextFormatInfo(SwTextFrm *pFrame, const bool bInterHyphL = false,
599 : const bool bQuickL = false, const bool bTst = false)
600 55817 : { CtorInitTextFormatInfo( pFrame, bInterHyphL, bQuickL, bTst ); }
601 :
602 : // For the formatting inside a double line in a line (multi-line portion)
603 : // we need a modified text-format-info:
604 : SwTextFormatInfo( const SwTextFormatInfo& rInf, SwLineLayout& rLay,
605 : SwTwips nActWidth );
606 :
607 382737 : inline sal_uInt16 Width() const { return nWidth; }
608 86316 : inline void Width( const sal_uInt16 nNew ) { nWidth = nNew; }
609 : void Init();
610 :
611 : // Returns the first changed position of the paragraph
612 : inline sal_Int32 GetReformatStart() const;
613 :
614 : // Margins
615 583 : inline SwTwips Left() const { return nLeft; }
616 84658 : inline void Left( const SwTwips nNew ) { nLeft = nNew; }
617 84658 : inline SwTwips Right() const { return nRight; }
618 84658 : inline void Right( const SwTwips nNew ) { nRight = nNew; }
619 583 : inline SwTwips First() const { return nFirst; }
620 84658 : inline void First( const SwTwips nNew ) { nFirst = nNew; }
621 220782 : inline sal_uInt16 RealWidth() const { return nRealWidth; }
622 84944 : inline void RealWidth( const sal_uInt16 nNew ) { nRealWidth = nNew; }
623 583 : inline sal_uInt16 ForcedLeftMargin() const { return nForcedLeftMargin; }
624 84717 : inline void ForcedLeftMargin( const sal_uInt16 nN ) { nForcedLeftMargin = nN; }
625 :
626 102358 : inline sal_uInt8 &MaxHyph() { return nMaxHyph; }
627 : inline const sal_uInt8 &MaxHyph() const { return nMaxHyph; }
628 :
629 17882 : inline SwLineLayout *GetRoot() { return pRoot; }
630 30 : inline const SwLineLayout *GetRoot() const { return pRoot; }
631 :
632 84658 : inline void SetRoot( SwLineLayout *pNew ) { pRoot = pNew; }
633 1298175 : inline SwLinePortion *GetLast() { return pLast; }
634 350919 : inline void SetLast( SwLinePortion *pNewLast ) { pLast = pNewLast; }
635 303183 : inline bool IsFull() const { return bFull; }
636 179808 : inline void SetFull( const bool bNew ) { bFull = bNew; }
637 0 : inline bool IsHyphForbud() const
638 0 : { return pFly ? bNoMidHyph : bNoEndHyph; }
639 : inline void SetHyphForbud( const bool bNew )
640 : { if ( pFly ) bNoMidHyph = bNew; else bNoEndHyph = bNew; }
641 169351 : inline void ChkNoHyph( const sal_uInt8 bEnd, const sal_uInt8 bMid )
642 169351 : { bNoEndHyph = (nMaxHyph && bEnd >= nMaxHyph);
643 169351 : bNoMidHyph = (nMaxHyph && bMid >= nMaxHyph); }
644 48723 : inline bool IsIgnoreFly() const { return bIgnoreFly; }
645 4045 : inline void SetIgnoreFly( const bool bNew ) { bIgnoreFly = bNew; }
646 1848 : inline bool IsFakeLineStart() const { return bFakeLineStart; }
647 29759 : inline void SetFakeLineStart( const bool bNew ) { bFakeLineStart = bNew; }
648 756556 : inline bool IsStop() const { return bStop; }
649 246 : inline void SetStop( const bool bNew ) { bStop = bNew; }
650 982447 : inline SwLinePortion *GetRest() { return pRest; }
651 18171 : inline void SetRest( SwLinePortion *pNewRest ) { pRest = pNewRest; }
652 276989 : inline bool IsNewLine() const { return bNewLine; }
653 538 : inline void SetNewLine( const bool bNew ) { bNewLine = bNew; }
654 34876 : inline bool IsShift() const { return bShift; }
655 54155 : inline void SetShift( const bool bNew ) { bShift = bNew; }
656 0 : inline bool IsInterHyph() const { return bInterHyph; }
657 : inline bool IsAutoHyph() const { return bAutoHyph; }
658 119719 : inline bool IsUnderflow() const { return bUnderflow; }
659 94359 : inline void ClrUnderflow() { bUnderflow = false; }
660 80185 : inline bool IsDropInit() const { return bDropInit; }
661 12 : inline void SetDropInit( const bool bNew ) { bDropInit = bNew; }
662 62707 : inline bool IsQuick() const { return bQuick; }
663 150120 : inline bool IsTest() const { return bTestFormat; }
664 :
665 535264 : inline sal_Int32 GetLineStart() const { return nLineStart; }
666 156300 : inline void SetLineStart( const sal_Int32 nNew ) { nLineStart = nNew; }
667 :
668 : // these are used during fly calculation
669 122052 : inline sal_uInt16 GetLineHeight() const { return nLineHeight; }
670 80185 : inline void SetLineHeight( const sal_uInt16 nNew ) { nLineHeight = nNew; }
671 23 : inline sal_uInt16 GetLineNetHeight() const { return nLineNetHeight; }
672 80185 : inline void SetLineNetHeight( const sal_uInt16 nNew ) { nLineNetHeight = nNew; }
673 :
674 : inline const SwLinePortion *GetUnderflow() const { return pUnderflow; }
675 215481 : inline SwLinePortion *GetUnderflow() { return pUnderflow; }
676 284 : inline void SetUnderflow( SwLinePortion *pNew )
677 284 : { pUnderflow = pNew; bUnderflow = true; }
678 260 : inline sal_Int32 GetSoftHyphPos() const { return nSoftHyphPos; }
679 179 : inline void SetSoftHyphPos( const sal_Int32 nNew ) { nSoftHyphPos = nNew; }
680 :
681 : inline void SetParaFootnote();
682 :
683 : // FlyFrms
684 563103 : inline SwFlyPortion *GetFly() { return pFly; }
685 171438 : inline void SetFly( SwFlyPortion *pNew ) { pFly = pNew; }
686 :
687 : inline const SwAttrSet& GetCharAttr() const;
688 :
689 : // Tabs
690 323789 : inline SwTabPortion *GetLastTab() { return pLastTab; }
691 5542 : inline void SetLastTab( SwTabPortion *pNew ) { pLastTab = pNew; }
692 3040 : inline sal_Unicode GetTabDecimal() const { return cTabDecimal; }
693 24 : inline void SetTabDecimal( const sal_Unicode cNew ) { cTabDecimal = cNew;}
694 :
695 : // Last*
696 : inline SwFieldPortion *GetLastField() { return pLastField; }
697 : inline void SetLastField( SwFieldPortion *pNew ) { pLastField = pNew; }
698 :
699 11582 : inline void ClearHookChar() { cHookChar = 0; }
700 2244 : inline void SetHookChar( const sal_Unicode cNew ) { cHookChar = cNew; }
701 184149 : inline sal_Unicode GetHookChar() const { return cHookChar; }
702 :
703 : // Done-Flags
704 55512 : inline bool IsFootnoteDone() const { return bFootnoteDone; }
705 48443 : inline void SetFootnoteDone( const bool bNew ) { bFootnoteDone = bNew; }
706 279089 : inline bool IsErgoDone() const { return bErgoDone; }
707 131093 : inline void SetErgoDone( const bool bNew ) { bErgoDone = bNew; }
708 158631 : inline bool IsNumDone() const { return bNumDone; }
709 152901 : inline void SetNumDone( const bool bNew ) { bNumDone = bNew; }
710 223702 : inline bool IsArrowDone() const { return bArrowDone; }
711 119334 : inline void SetArrowDone( const bool bNew ) { bArrowDone = bNew; }
712 :
713 : // For SwTextPortion::Hyphenate
714 : inline bool IsSoftHyph( const sal_Int32 nPos ) const;
715 : bool ChgHyph( const bool bNew );
716 :
717 : // Should the hyphenate helper be discarded?
718 : bool IsHyphenate() const;
719 100283 : inline sal_Int32 GetUnderScorePos() const { return nUnderScorePos; }
720 142 : inline void SetUnderScorePos( sal_Int32 nNew ) { nUnderScorePos = nNew; }
721 :
722 : // Calls HyphenateWord() of Hyphenator
723 : ::com::sun::star::uno::Reference<
724 : ::com::sun::star::linguistic2::XHyphenatedWord >
725 : HyphWord( const OUString &rText, const sal_Int32 nMinTrail );
726 : const com::sun::star::beans::PropertyValues &
727 : GetHyphValues() const;
728 :
729 80163 : bool CheckFootnotePortion( SwLineLayout* pCurr )
730 80163 : { return IsFootnoteInside() && _CheckFootnotePortion( pCurr ); }
731 :
732 : // Dropcaps called by SwTextFormatter::CTOR
733 : const SwFormatDrop *GetDropFormat() const;
734 :
735 : // Sets the last SwKernPortion as pLast, if it is followed by empty portions
736 : bool LastKernPortion();
737 :
738 : // Looks for tabs, TabDec, TXTATR and BRK from nIdx until nEnd.
739 : // Return: Position; sets cHookChar if necessary
740 : sal_Int32 ScanPortionEnd( const sal_Int32 nStart, const sal_Int32 nEnd );
741 :
742 : friend SvStream & WriteSwTextFormatInfo( SvStream &rOS, const SwTextFormatInfo &rInf );
743 :
744 84694 : inline void SetTabOverflow( bool bOverflow ) { bTabOverflow = bOverflow; }
745 37 : inline bool IsTabOverflow() { return bTabOverflow; }
746 :
747 : };
748 :
749 : /**
750 : * For the text replacement and restoration of SwTextSizeInfo.
751 : * The way this is done is a bit of a hack: Although rInf is const we change it
752 : * anyway.
753 : * Because rInf is restorated again in the DTOR, we can do this.
754 : * You could call it a "logical const", if you wish.
755 : */
756 : class SwTextSlot
757 : {
758 : OUString aText;
759 : std::shared_ptr<vcl::TextLayoutCache> m_pOldCachedVclData;
760 : const OUString *pOldText;
761 : const SwWrongList* pOldSmartTagList;
762 : const SwWrongList* pOldGrammarCheckList;
763 : SwWrongList* pTempList;
764 : sal_Int32 nIdx;
765 : sal_Int32 nLen;
766 : bool bOn;
767 : protected:
768 : SwTextSizeInfo *pInf;
769 : public:
770 : // The replacement string originates either from the portion via GetExpText()
771 : // or from the rCh, if it is not empty.
772 : SwTextSlot( const SwTextSizeInfo *pNew, const SwLinePortion *pPor, bool bTextLen,
773 : bool bExgLists, OUString const & rCh = OUString() );
774 : ~SwTextSlot();
775 : bool IsOn() const { return bOn; }
776 : };
777 :
778 : class SwFontSave
779 : {
780 : SwTextSizeInfo *pInf;
781 : SwFont *pFnt;
782 : SwAttrIter *pIter;
783 : public:
784 : SwFontSave( const SwTextSizeInfo &rInf, SwFont *pFnt,
785 : SwAttrIter* pItr = NULL );
786 : ~SwFontSave();
787 : };
788 :
789 220675 : inline sal_uInt16 SwTextSizeInfo::GetAscent() const
790 : {
791 : SAL_WARN_IF( !GetOut(), "sw.core", "SwTextSizeInfo::GetAscent() without m_pOut" );
792 :
793 220675 : return const_cast<SwFont*>(GetFont())->GetAscent( m_pVsh, *GetOut() );
794 : }
795 :
796 220671 : inline sal_uInt16 SwTextSizeInfo::GetTextHeight() const
797 : {
798 : SAL_WARN_IF( !GetOut(), "sw.core", "SwTextSizeInfo::GetTextHeight() without m_pOut" );
799 :
800 220671 : return const_cast<SwFont*>(GetFont())->GetHeight( m_pVsh, *GetOut() );
801 : }
802 :
803 568 : inline SwPosSize SwTextSizeInfo::GetTextSize( const OUString &rText ) const
804 : {
805 568 : return GetTextSize( m_pOut, 0, rText, 0, rText.getLength(), 0 );
806 : }
807 :
808 0 : inline SwPosSize SwTextSizeInfo::GetTextSize( const SwScriptInfo* pSI,
809 : const sal_Int32 nNewIdx,
810 : const sal_Int32 nNewLen,
811 : const sal_uInt16 nCompress ) const
812 : {
813 0 : return GetTextSize( m_pOut, pSI, *m_pText, nNewIdx, nNewLen, nCompress );
814 : }
815 :
816 265618 : inline SwTwips SwTextPaintInfo::GetPaintOfst() const
817 : {
818 265618 : return GetParaPortion()->GetRepaint().GetOfst();
819 : }
820 :
821 300068 : inline void SwTextPaintInfo::SetPaintOfst( const SwTwips nNew )
822 : {
823 300068 : GetParaPortion()->GetRepaint().SetOfst( nNew );
824 300068 : }
825 :
826 85 : inline void SwTextPaintInfo::DrawText( const OUString &rText,
827 : const SwLinePortion &rPor,
828 : const sal_Int32 nStart, const sal_Int32 nLength,
829 : const bool bKern ) const
830 : {
831 85 : const_cast<SwTextPaintInfo*>(this)->_DrawText( rText, rPor, nStart, nLength, bKern );
832 85 : }
833 :
834 14283 : inline void SwTextPaintInfo::DrawText( const SwLinePortion &rPor,
835 : const sal_Int32 nLength, const bool bKern ) const
836 : {
837 14283 : const_cast<SwTextPaintInfo*>(this)->_DrawText( *m_pText, rPor, m_nIdx, nLength, bKern );
838 14283 : }
839 :
840 6081 : inline void SwTextPaintInfo::DrawMarkedText( const SwLinePortion &rPor,
841 : const sal_Int32 nLength,
842 : const bool bKern,
843 : const bool bWrong,
844 : const bool bSmartTags,
845 : const bool bGrammarCheck ) const
846 : {
847 6081 : const_cast<SwTextPaintInfo*>(this)->_DrawText( *m_pText, rPor, m_nIdx, nLength, bKern, bWrong, bSmartTags, bGrammarCheck );
848 6081 : }
849 :
850 182266 : inline sal_Int32 SwTextFormatInfo::GetReformatStart() const
851 : {
852 182266 : return GetParaPortion()->GetReformat().Start();
853 : }
854 :
855 7074 : inline const SwAttrSet& SwTextFormatInfo::GetCharAttr() const
856 : {
857 7074 : return GetTextFrm()->GetTextNode()->GetSwAttrSet();
858 : }
859 :
860 145 : inline void SwTextFormatInfo::SetParaFootnote()
861 : {
862 145 : GetTextFrm()->SetFootnote( true );
863 145 : }
864 :
865 : inline bool SwTextFormatInfo::IsSoftHyph( const sal_Int32 nPos ) const
866 : {
867 : return CHAR_SOFTHYPHEN == GetTextFrm()->GetTextNode()->GetText()[nPos];
868 : }
869 :
870 : #endif
871 :
872 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|