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_ITRTXT_HXX
20 #define INCLUDED_SW_SOURCE_CORE_TEXT_ITRTXT_HXX
21 #include <swtypes.hxx>
22 #include "itratr.hxx"
23 #include "inftxt.hxx"
24 
25 struct SwPosition;
26 struct SwCursorMoveState;
27 class SwMarginPortion;
28 class SwFlyPortion;
29 
30 class SwTextIter : public SwAttrIter
31 {
32 protected:
33     SwLineInfo m_aLineInf;
34     SwTextFrame  *m_pFrame;
35     SwTextInfo *m_pInf;
36     SwLineLayout *m_pCurr;
37     SwLineLayout *m_pPrev;
38     SwTwips m_nFrameStart;
39     SwTwips m_nY;
40     SwTwips m_nRegStart;          // The register's start position (Y)
41     TextFrameIndex m_nStart;          // Start in the text string, end = pCurr->GetLen()
42     sal_uInt16 m_nRegDiff;            // Register's line distance
43     sal_uInt16 m_nLineNr;             // Line number
44     bool m_bPrev          : 1;
45     bool m_bRegisterOn    : 1;    // Keep in register
46     bool m_bOneBlock      : 1;    // Justified text: Dispose single words
47     bool m_bLastBlock     : 1;    // Justified text: Also the last line
48     bool m_bLastCenter    : 1;    // Justified text: Center last line
49 
50     SwLineLayout *GetPrev_();
51 
52     // Reset in the first line
53     void Init();
54     void CtorInitTextIter( SwTextFrame *pFrame, SwTextInfo *pInf );
SwTextIter(SwTextNode const * pTextNode)55     explicit SwTextIter(SwTextNode const * pTextNode)
56         : SwAttrIter(pTextNode)
57         , m_pFrame(nullptr)
58         , m_pInf(nullptr)
59         , m_pCurr(nullptr)
60         , m_pPrev(nullptr)
61         , m_nFrameStart(0)
62         , m_nY(0)
63         , m_nRegStart(0)
64         , m_nStart(0)
65         , m_nRegDiff(0)
66         , m_nLineNr(0)
67         , m_bPrev(false)
68         , m_bRegisterOn(false)
69         , m_bOneBlock(false)
70         , m_bLastBlock(false)
71         , m_bLastCenter(false)
72     {
73     }
74 public:
SwTextIter(SwTextFrame * pTextFrame,SwTextInfo * pTextInf)75     SwTextIter(SwTextFrame *pTextFrame, SwTextInfo *pTextInf)
76         : SwAttrIter(pTextFrame->GetTextNodeFirst())
77         , m_bOneBlock(false)
78         , m_bLastBlock(false)
79         , m_bLastCenter(false)
80     {
81         CtorInitTextIter(pTextFrame, pTextInf);
82     }
GetCurr() const83     const SwLineLayout *GetCurr() const { return m_pCurr; } // NEVER 0!
GetNext() const84     const SwLineLayout *GetNext() const { return m_pCurr->GetNext(); }
85            const SwLineLayout *GetPrev();
GetLength() const86     TextFrameIndex GetLength() const { return m_pCurr->GetLen(); }
GetLineNr() const87     sal_uInt16 GetLineNr() const { return m_nLineNr; }
GetStart() const88     TextFrameIndex GetStart() const { return m_nStart; }
GetEnd() const89     TextFrameIndex GetEnd() const { return GetStart() + GetLength(); }
Y() const90     SwTwips Y() const { return m_nY; }
91 
RegStart() const92     SwTwips RegStart() const { return m_nRegStart; }
RegDiff() const93     sal_uInt16 RegDiff() const { return m_nRegDiff; }
IsRegisterOn() const94     bool IsRegisterOn() const { return m_bRegisterOn; }
95 
GetInfo()96     SwTextInfo &GetInfo() { return *m_pInf; }
GetInfo() const97     const SwTextInfo &GetInfo() const { return *m_pInf; }
98 
Top()99     void Top() { Init(); }
100     void Bottom();
101     const SwLineLayout *Next();
102     const SwLineLayout *Prev();
103 
104     // Skips the FlyFrames dummy line
105     const SwLineLayout *NextLine();
106     const SwLineLayout *PrevLine();
107     const SwLineLayout *GetNextLine() const;
108     const SwLineLayout *GetPrevLine();
109 
110     void CharToLine(TextFrameIndex);
111     void TwipsToLine(const SwTwips);
112 
113     // Truncates all after pCurr
114     void TruncLines( bool bNoteFollow = false );
115 
GetLineHeight() const116     sal_uInt16 GetLineHeight() const { return m_pCurr->GetRealHeight(); }
117     void CalcAscentAndHeight( sal_uInt16 &rAscent, sal_uInt16 &rHeight ) const;
118 
119     // Lots of trouble for querying pCurr == pPara
IsFirstTextLine() const120     bool IsFirstTextLine() const
121     { return m_nStart == GetInfo().GetTextStart() &&
122         !( m_pCurr->IsDummy() && GetNextLine() ); }
123 
124     // Replacement for the old IsFirstLine()
IsParaLine() const125     bool IsParaLine() const
126         { return m_pCurr == m_pInf->GetParaPortion(); }
127 
GetLineInfo() const128     const SwLineInfo &GetLineInfo() const { return m_aLineInf; }
GetFirstPos() const129     SwTwips GetFirstPos() const { return m_nFrameStart; }
130     inline bool SeekAndChg( SwTextSizeInfo &rInf );
131     inline bool SeekAndChgBefore( SwTextSizeInfo &rInf );
132     inline bool SeekStartAndChg( SwTextSizeInfo &rInf, const bool bPara=false );
133 
GetTextFrame()134     SwTextFrame *GetTextFrame() { return m_pFrame; }
GetTextFrame() const135     const SwTextFrame *GetTextFrame() const { return m_pFrame; }
136 
137     // Counts consecutive hyphens in order to be within the boundary given by MaxHyphens
138     void CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const;
139 };
140 
141 class SwTextMargin : public SwTextIter
142 {
143 private:
144           SwTwips nLeft;
145           SwTwips nRight;
146           SwTwips nFirst;
147           sal_uInt16  nDropLeft;
148           sal_uInt16  nDropHeight;
149           sal_uInt16  nDropDescent;
150           sal_uInt16  nDropLines;
151           SvxAdjust  nAdjust;
152           // #i91133#
153           SwTwips mnTabLeft;
154 
155 protected:
156     // For FormatQuoVadis
Right(const SwTwips nNew)157     void Right( const SwTwips nNew ) { nRight = nNew; }
158 
159     void CtorInitTextMargin( SwTextFrame *pFrame, SwTextSizeInfo *pInf );
SwTextMargin(SwTextNode const * pTextNode)160     explicit SwTextMargin(SwTextNode const * pTextNode)
161         : SwTextIter(pTextNode)
162         , nLeft(0)
163         , nRight(0)
164         , nFirst(0)
165         , nDropLeft(0)
166         , nDropHeight(0)
167         , nDropDescent(0)
168         , nDropLines(0)
169         , nAdjust(SvxAdjust::Left)
170         , mnTabLeft(0)
171     {
172     }
173 public:
SwTextMargin(SwTextFrame * pTextFrame,SwTextSizeInfo * pTextSizeInf)174     SwTextMargin(SwTextFrame *pTextFrame, SwTextSizeInfo *pTextSizeInf)
175         : SwTextIter(pTextFrame->GetTextNodeFirst())
176     {
177         CtorInitTextMargin( pTextFrame, pTextSizeInf );
178     }
179     inline SwTwips GetLeftMargin() const;
180     inline SwTwips Left() const;
Right() const181     SwTwips Right() const { return nRight; }
FirstLeft() const182     SwTwips FirstLeft() const { return nFirst; }
CurrWidth() const183     SwTwips CurrWidth() const { return m_pCurr->PrtWidth(); }
184            SwTwips GetLineStart() const;
GetLineEnd() const185     SwTwips GetLineEnd() const { return GetLineStart() + CurrWidth(); }
GetTopLeft() const186     Point GetTopLeft() const { return Point( GetLineStart(), Y() ); }
IsOneBlock() const187     bool IsOneBlock() const { return m_bOneBlock; }
IsLastBlock() const188     bool IsLastBlock() const { return m_bLastBlock; }
IsLastCenter() const189     bool IsLastCenter() const { return m_bLastCenter; }
GetAdjust() const190     SvxAdjust GetAdjust() const { return nAdjust; }
GetLineWidth() const191     sal_uInt16 GetLineWidth() const
192            { return sal_uInt16( Right() - GetLeftMargin() + 1 ); }
GetLeftMin() const193     SwTwips GetLeftMin() const { return std::min(nFirst, nLeft); }
HasNegFirst() const194     bool HasNegFirst() const { return nFirst < nLeft; }
195 
196     // #i91133#
GetTabLeft() const197     SwTwips GetTabLeft() const
198     {
199         return mnTabLeft;
200     }
201     // DropCaps
GetDropLines() const202     sal_uInt16 GetDropLines() const { return nDropLines; }
SetDropLines(const sal_uInt16 nNew)203     void SetDropLines( const sal_uInt16 nNew ) { nDropLines = nNew; }
GetDropLeft() const204     sal_uInt16 GetDropLeft() const { return nDropLeft; }
GetDropHeight() const205     sal_uInt16 GetDropHeight() const { return nDropHeight; }
SetDropHeight(const sal_uInt16 nNew)206     void SetDropHeight( const sal_uInt16 nNew ) { nDropHeight = nNew; }
GetDropDescent() const207     sal_uInt16 GetDropDescent() const { return nDropDescent; }
SetDropDescent(const sal_uInt16 nNew)208     void SetDropDescent( const sal_uInt16 nNew ) { nDropDescent = nNew; }
209     void DropInit();
210 
211     // Returns the TextPos for start and end of the current line without whitespace
212     // Implemented in frminf.cxx
213     TextFrameIndex GetTextStart() const;
214     TextFrameIndex GetTextEnd() const;
215 
GetInfo()216     SwTextSizeInfo &GetInfo()
217         { return static_cast<SwTextSizeInfo&>(SwTextIter::GetInfo()); }
GetInfo() const218     const SwTextSizeInfo &GetInfo() const
219         { return static_cast<const SwTextSizeInfo&>(SwTextIter::GetInfo()); }
220 
221 };
222 
223 class SwTextAdjuster : public SwTextMargin
224 {
225     // Adjusts the portion, if we have adjustment and FlyFrames
226     void CalcFlyAdjust( SwLineLayout *pCurr );
227 
228     // Calls SplitGlues and CalcBlockAdjust
229     void FormatBlock( );
230 
231     // Creates the glue chain for short lines
232     SwMarginPortion* CalcRightMargin( SwLineLayout *pCurr, SwTwips nReal = 0 );
233 
234     // Calculate the adjustment (FlyPortions)
235     SwFlyPortion *CalcFlyPortion( const long nRealWidth,
236                                   const SwRect &rCurrRect );
237 
238 protected:
SwTextAdjuster(SwTextNode const * pTextNode)239     explicit SwTextAdjuster(SwTextNode const * pTextNode) : SwTextMargin(pTextNode) { }
240     // Creates the Glues for adjusted paragraphs
241     void CalcNewBlock( SwLineLayout *pCurr, const SwLinePortion *pStopAt,
242         SwTwips nReal = 0, bool bSkipKashida = false );
243     SwTwips CalcKanaAdj( SwLineLayout *pCurr );
244 
245 public:
246     // Is overloaded by SwTextFormatter due to UpdatePos
247     void CalcAdjLine( SwLineLayout *pCurr );
248 
249     // For adjusting afterwards
GetAdjusted() const250     void GetAdjusted() const
251     {
252         if( m_pCurr->IsFormatAdj() )
253             const_cast<SwTextAdjuster*>(this)->CalcAdjLine( m_pCurr );
254     }
255 
256     // Special treatment for DropCaps
257     void CalcDropAdjust();
258     void CalcDropRepaint();
259 };
260 
261 class SwTextCursor : public SwTextAdjuster
262 {
263     // A small helper-class to save SwTextCursor member, manipulate them
264     // and to restore them
265     friend class SwTextCursorSave;
266 
267     // Ambiguities
268     static bool bRightMargin;
269     void GetCharRect_(SwRect *, TextFrameIndex, SwCursorMoveState *);
270 protected:
271     void CtorInitTextCursor( SwTextFrame *pFrame, SwTextSizeInfo *pInf );
SwTextCursor(SwTextNode const * pTextNode)272     explicit SwTextCursor(SwTextNode const * pTextNode) : SwTextAdjuster(pTextNode) { }
273 public:
SwTextCursor(SwTextFrame * pTextFrame,SwTextSizeInfo * pTextSizeInf)274     SwTextCursor( SwTextFrame *pTextFrame, SwTextSizeInfo *pTextSizeInf )
275         : SwTextAdjuster(pTextFrame->GetTextNodeFirst())
276     {
277         CtorInitTextCursor(pTextFrame, pTextSizeInf);
278     }
279     void GetCharRect(SwRect *, TextFrameIndex, SwCursorMoveState* = nullptr,
280         const long nMax = 0 );
281     void GetEndCharRect(SwRect *, TextFrameIndex, SwCursorMoveState* = nullptr,
282         const long nMax = 0 );
283     TextFrameIndex GetCursorOfst( SwPosition *pPos, const Point &rPoint,
284                 bool bChgNode, SwCursorMoveState* = nullptr ) const;
285     // Respects ambiguities: For the implementation see below
286     const SwLineLayout *CharCursorToLine(TextFrameIndex const nPos);
287 
288     // calculates baseline for portion rPor
289     // bAutoToCentered indicates, if AUTOMATIC mode means CENTERED or BASELINE
290     sal_uInt16 AdjustBaseLine( const SwLineLayout& rLine, const SwLinePortion* pPor,
291                            sal_uInt16 nPorHeight = 0, sal_uInt16 nAscent = 0,
292                            const bool bAutoToCentered = false ) const;
293 
SetRightMargin(const bool bNew)294     static void SetRightMargin( const bool bNew ){ bRightMargin = bNew; }
IsRightMargin()295     static bool IsRightMargin() { return bRightMargin; }
296 };
297 
298 // Change current output device to printer, this has to be done before
299 // formatting.
300 class SwHookOut
301 {
302     SwTextSizeInfo* pInf;
303     VclPtr<OutputDevice> pOut;
304     bool const bOnWin;
305 public:
306     explicit SwHookOut( SwTextSizeInfo& rInfo );
307     ~SwHookOut();
308 };
309 
SeekAndChg(SwTextSizeInfo & rInf)310 inline bool SwTextIter::SeekAndChg( SwTextSizeInfo &rInf )
311 {
312     return SeekAndChgAttrIter( rInf.GetIdx(), rInf.GetOut() );
313 }
314 
SeekAndChgBefore(SwTextSizeInfo & rInf)315 inline bool SwTextIter::SeekAndChgBefore( SwTextSizeInfo &rInf )
316 {
317     if ( rInf.GetIdx() )
318         return SeekAndChgAttrIter(rInf.GetIdx() - TextFrameIndex(1), rInf.GetOut());
319     else
320         return SeekAndChgAttrIter( rInf.GetIdx(), rInf.GetOut() );
321 }
322 
SeekStartAndChg(SwTextSizeInfo & rInf,const bool bPara)323 inline bool SwTextIter::SeekStartAndChg( SwTextSizeInfo &rInf, const bool bPara )
324 {
325     return SeekStartAndChgAttrIter( rInf.GetOut(), bPara );
326 }
327 
GetLeftMargin() const328 inline SwTwips SwTextMargin::GetLeftMargin() const
329 {
330     return IsFirstTextLine() ? nFirst : Left();
331 }
332 
Left() const333 inline SwTwips SwTextMargin::Left() const
334 {
335     return (nDropLines >= m_nLineNr && 1 != m_nLineNr) ? nFirst + nDropLeft : nLeft;
336 }
337 
338 #endif
339 
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
341