1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <swtypes.hxx>
26 struct SwCursorMoveState
;
27 class SwMarginPortion
;
30 class SwTextIter
: public SwAttrIter
33 SwLineInfo m_aLineInf
;
34 SwTextFrame
*m_pFrame
;
36 SwLineLayout
*m_pCurr
;
37 SwLineLayout
*m_pPrev
;
38 SwTwips m_nFrameStart
;
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_Int32 m_nLineNr
; // Line number
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
50 SwLineLayout
*GetPrev_();
52 // Reset in the first line
54 void CtorInitTextIter( SwTextFrame
*pFrame
, SwTextInfo
*pInf
);
55 explicit SwTextIter(SwTextNode
const * pTextNode
)
56 : SwAttrIter(pTextNode
)
68 , m_bRegisterOn(false)
71 , m_bLastCenter(false)
75 SwTextIter(SwTextFrame
*pTextFrame
, SwTextInfo
*pTextInf
)
76 : SwAttrIter(pTextFrame
->GetTextNodeFirst())
79 , m_bLastCenter(false)
81 CtorInitTextIter(pTextFrame
, pTextInf
);
83 const SwLineLayout
*GetCurr() const { return m_pCurr
; } // NEVER 0!
84 const SwLineLayout
*GetNext() const { return m_pCurr
->GetNext(); }
85 const SwLineLayout
*GetPrev();
86 TextFrameIndex
GetLength() const { return m_pCurr
->GetLen(); }
87 sal_Int32
GetLineNr() const { return m_nLineNr
; }
88 TextFrameIndex
GetStart() const { return m_nStart
; }
89 TextFrameIndex
GetEnd() const { return GetStart() + GetLength(); }
90 SwTwips
Y() const { return m_nY
; }
92 SwTwips
RegStart() const { return m_nRegStart
; }
93 sal_uInt16
RegDiff() const { return m_nRegDiff
; }
94 bool IsRegisterOn() const { return m_bRegisterOn
; }
96 SwTextInfo
&GetInfo() { return *m_pInf
; }
97 const SwTextInfo
&GetInfo() const { return *m_pInf
; }
99 void Top() { Init(); }
101 const SwLineLayout
*Next();
102 const SwLineLayout
*Prev();
104 // Skips the FlyFrames dummy line
105 const SwLineLayout
*NextLine();
106 const SwLineLayout
*PrevLine();
107 const SwLineLayout
*GetNextLine() const;
108 const SwLineLayout
*GetPrevLine();
110 void CharToLine(TextFrameIndex
);
111 void TwipsToLine(const SwTwips
);
113 // Truncates all after pCurr
114 void TruncLines( bool bNoteFollow
= false );
116 SwTwips
GetLineHeight() const { return m_pCurr
->GetRealHeight(); }
117 void CalcAscentAndHeight( SwTwips
&rAscent
, SwTwips
&rHeight
) const;
119 // Lots of trouble for querying pCurr == pPara
120 bool IsFirstTextLine() const
121 { return m_nStart
== GetInfo().GetTextStart() &&
122 !( m_pCurr
->IsDummy() && GetNextLine() ); }
124 // Replacement for the old IsFirstLine()
125 bool IsParaLine() const
126 { return m_pCurr
== m_pInf
->GetParaPortion(); }
128 const SwLineInfo
&GetLineInfo() const { return m_aLineInf
; }
129 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 );
134 SwTextFrame
*GetTextFrame() { return m_pFrame
; }
135 const SwTextFrame
*GetTextFrame() const { return m_pFrame
; }
137 // Counts consecutive hyphens in order to be within the boundary given by MaxHyphens
138 void CntHyphens( sal_uInt8
&nEndCnt
, sal_uInt8
&nMidCnt
) const;
141 class SwTextMargin
: public SwTextIter
147 sal_uInt16 mnDropLeft
;
148 sal_uInt16 mnDropHeight
;
149 sal_uInt16 mnDropDescent
;
150 sal_uInt16 mnDropLines
;
156 // For FormatQuoVadis
157 void Right( const SwTwips nNew
) { mnRight
= nNew
; }
159 void CtorInitTextMargin( SwTextFrame
*pFrame
, SwTextSizeInfo
*pInf
);
160 explicit SwTextMargin(SwTextNode
const * pTextNode
)
161 : SwTextIter(pTextNode
)
169 , mnAdjust(SvxAdjust::Left
)
174 SwTextMargin(SwTextFrame
*pTextFrame
, SwTextSizeInfo
*pTextSizeInf
)
175 : SwTextIter(pTextFrame
->GetTextNodeFirst())
177 CtorInitTextMargin( pTextFrame
, pTextSizeInf
);
179 inline SwTwips
GetLeftMargin() const;
180 inline SwTwips
Left() const;
181 SwTwips
Right() const { return mnRight
; }
182 SwTwips
FirstLeft() const { return mnFirst
; }
183 SwTwips
CurrWidth() const { return m_pCurr
->PrtWidth(); }
184 SwTwips
GetLineStart() const;
185 SwTwips
GetLineEnd() const { return GetLineStart() + CurrWidth(); }
186 Point
GetTopLeft() const { return Point( GetLineStart(), Y() ); }
187 bool IsOneBlock() const { return m_bOneBlock
; }
188 bool IsLastBlock() const { return m_bLastBlock
; }
189 bool IsLastCenter() const { return m_bLastCenter
; }
190 SvxAdjust
GetAdjust() const { return mnAdjust
; }
191 sal_uInt16
GetLineWidth() const
192 { return sal_uInt16( Right() - GetLeftMargin() + 1 ); }
193 SwTwips
GetLeftMin() const { return std::min(mnFirst
, mnLeft
); }
194 bool HasNegFirst() const { return mnFirst
< mnLeft
; }
197 SwTwips
GetTabLeft() const
202 sal_uInt16
GetDropLines() const { return mnDropLines
; }
203 void SetDropLines( const sal_uInt16 nNew
) { mnDropLines
= nNew
; }
204 sal_uInt16
GetDropLeft() const { return mnDropLeft
; }
205 sal_uInt16
GetDropHeight() const { return mnDropHeight
; }
206 void SetDropHeight( const sal_uInt16 nNew
) { mnDropHeight
= nNew
; }
207 sal_uInt16
GetDropDescent() const { return mnDropDescent
; }
208 void SetDropDescent( const sal_uInt16 nNew
) { mnDropDescent
= nNew
; }
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;
216 SwTextSizeInfo
&GetInfo()
217 { return static_cast<SwTextSizeInfo
&>(SwTextIter::GetInfo()); }
218 const SwTextSizeInfo
&GetInfo() const
219 { return static_cast<const SwTextSizeInfo
&>(SwTextIter::GetInfo()); }
223 class SwTextAdjuster
: public SwTextMargin
225 // Adjusts the portion, if we have adjustment and FlyFrames
226 void CalcFlyAdjust( SwLineLayout
*pCurr
);
228 // Calls SplitGlues and CalcBlockAdjust
231 // Creates the glue chain for short lines
232 SwMarginPortion
* CalcRightMargin( SwLineLayout
*pCurr
, SwTwips nReal
= 0 );
234 // Calculate the adjustment (FlyPortions)
235 SwFlyPortion
*CalcFlyPortion( const tools::Long nRealWidth
,
236 const SwRect
&rCurrRect
);
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
);
246 // Is overloaded by SwTextFormatter due to UpdatePos
247 void CalcAdjLine( SwLineLayout
*pCurr
);
249 // For adjusting afterwards
250 void GetAdjusted() const
252 if( m_pCurr
->IsFormatAdj() )
253 const_cast<SwTextAdjuster
*>(this)->CalcAdjLine( m_pCurr
);
256 // Special treatment for DropCaps
257 void CalcDropAdjust();
258 void CalcDropRepaint();
261 class SwTextCursor
: public SwTextAdjuster
263 // A small helper-class to save SwTextCursor member, manipulate them
264 // and to restore them
265 friend class SwTextCursorSave
;
268 static bool s_bRightMargin
;
269 void GetCharRect_(SwRect
*, TextFrameIndex
, SwCursorMoveState
*);
271 void CtorInitTextCursor( SwTextFrame
*pFrame
, SwTextSizeInfo
*pInf
);
272 explicit SwTextCursor(SwTextNode
const * pTextNode
) : SwTextAdjuster(pTextNode
) { }
273 void AddExtraBlankWidth();
275 SwTextCursor( SwTextFrame
*pTextFrame
, SwTextSizeInfo
*pTextSizeInf
)
276 : SwTextAdjuster(pTextFrame
->GetTextNodeFirst())
278 CtorInitTextCursor(pTextFrame
, pTextSizeInf
);
280 void GetCharRect(SwRect
*, TextFrameIndex
, SwCursorMoveState
* = nullptr,
281 const tools::Long nMax
= 0 );
282 void GetEndCharRect(SwRect
*, TextFrameIndex
, SwCursorMoveState
* = nullptr,
283 const tools::Long nMax
= 0 );
284 TextFrameIndex
GetModelPositionForViewPoint( SwPosition
*pPos
, const Point
&rPoint
,
285 bool bChgNode
, SwCursorMoveState
* = nullptr ) const;
286 // Respects ambiguities: For the implementation see below
287 const SwLineLayout
*CharCursorToLine(TextFrameIndex
const nPos
);
289 // calculates baseline for portion rPor
290 // bAutoToCentered indicates, if AUTOMATIC mode means CENTERED or BASELINE
291 SwTwips
AdjustBaseLine( const SwLineLayout
& rLine
, const SwLinePortion
* pPor
,
292 SwTwips nPorHeight
= 0, SwTwips nAscent
= 0,
293 const bool bAutoToCentered
= false ) const;
295 static void SetRightMargin( const bool bNew
){ s_bRightMargin
= bNew
; }
296 static bool IsRightMargin() { return s_bRightMargin
; }
299 // Change current output device to printer, this has to be done before
303 SwTextSizeInfo
* pInf
;
304 VclPtr
<OutputDevice
> pOut
;
307 explicit SwHookOut( SwTextSizeInfo
& rInfo
);
311 inline bool SwTextIter::SeekAndChg( SwTextSizeInfo
&rInf
)
313 return SeekAndChgAttrIter( rInf
.GetIdx(), rInf
.GetOut() );
316 inline bool SwTextIter::SeekAndChgBefore( SwTextSizeInfo
&rInf
)
319 return SeekAndChgAttrIter(rInf
.GetIdx() - TextFrameIndex(1), rInf
.GetOut());
321 return SeekAndChgAttrIter( rInf
.GetIdx(), rInf
.GetOut() );
324 inline bool SwTextIter::SeekStartAndChg( SwTextSizeInfo
&rInf
, const bool bPara
)
326 return SeekStartAndChgAttrIter( rInf
.GetOut(), bPara
);
329 inline SwTwips
SwTextMargin::GetLeftMargin() const
331 return IsFirstTextLine() ? mnFirst
: Left();
334 inline SwTwips
SwTextMargin::Left() const
336 return (mnDropLines
>= m_nLineNr
&& 1 != m_nLineNr
) ? mnFirst
+ mnDropLeft
: mnLeft
;
341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */