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 mnLeft;
145 SwTwips mnRight;
146 SwTwips mnFirst;
147 sal_uInt16 mnDropLeft;
148 sal_uInt16 mnDropHeight;
149 sal_uInt16 mnDropDescent;
150 sal_uInt16 mnDropLines;
151 SvxAdjust mnAdjust;
152 // #i91133#
153 SwTwips mnTabLeft;
154
155 protected:
156 // For FormatQuoVadis
Right(const SwTwips nNew)157 void Right( const SwTwips nNew ) { mnRight = nNew; }
158
159 void CtorInitTextMargin( SwTextFrame *pFrame, SwTextSizeInfo *pInf );
SwTextMargin(SwTextNode const * pTextNode)160 explicit SwTextMargin(SwTextNode const * pTextNode)
161 : SwTextIter(pTextNode)
162 , mnLeft(0)
163 , mnRight(0)
164 , mnFirst(0)
165 , mnDropLeft(0)
166 , mnDropHeight(0)
167 , mnDropDescent(0)
168 , mnDropLines(0)
169 , mnAdjust(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 mnRight; }
FirstLeft() const182 SwTwips FirstLeft() const { return mnFirst; }
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 mnAdjust; }
GetLineWidth() const191 sal_uInt16 GetLineWidth() const
192 { return sal_uInt16( Right() - GetLeftMargin() + 1 ); }
GetLeftMin() const193 SwTwips GetLeftMin() const { return std::min(mnFirst, mnLeft); }
HasNegFirst() const194 bool HasNegFirst() const { return mnFirst < mnLeft; }
195
196 // #i91133#
GetTabLeft() const197 SwTwips GetTabLeft() const
198 {
199 return mnTabLeft;
200 }
201 // DropCaps
GetDropLines() const202 sal_uInt16 GetDropLines() const { return mnDropLines; }
SetDropLines(const sal_uInt16 nNew)203 void SetDropLines( const sal_uInt16 nNew ) { mnDropLines = nNew; }
GetDropLeft() const204 sal_uInt16 GetDropLeft() const { return mnDropLeft; }
GetDropHeight() const205 sal_uInt16 GetDropHeight() const { return mnDropHeight; }
SetDropHeight(const sal_uInt16 nNew)206 void SetDropHeight( const sal_uInt16 nNew ) { mnDropHeight = nNew; }
GetDropDescent() const207 sal_uInt16 GetDropDescent() const { return mnDropDescent; }
SetDropDescent(const sal_uInt16 nNew)208 void SetDropDescent( const sal_uInt16 nNew ) { mnDropDescent = 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 tools::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 s_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 tools::Long nMax = 0 );
281 void GetEndCharRect(SwRect *, TextFrameIndex, SwCursorMoveState* = nullptr,
282 const tools::Long nMax = 0 );
283 TextFrameIndex GetModelPositionForViewPoint( 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 ){ s_bRightMargin = bNew; }
IsRightMargin()295 static bool IsRightMargin() { return s_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 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() ? mnFirst : Left();
331 }
332
Left() const333 inline SwTwips SwTextMargin::Left() const
334 {
335 return (mnDropLines >= m_nLineNr && 1 != m_nLineNr) ? mnFirst + mnDropLeft : mnLeft;
336 }
337
338 #endif
339
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
341