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