LibreOffice Module sw (master) 1
itrtxt.cxx
Go to the documentation of this file.
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
20#include <ndtxt.hxx>
21#include <txatbase.hxx>
22#include <paratr.hxx>
23#include <vcl/outdev.hxx>
25
26#include "pormulti.hxx"
27#include <pagefrm.hxx>
28#include <tgrditem.hxx>
29#include "porfld.hxx"
30
31#include "itrtxt.hxx"
32#include <txtfrm.hxx>
33
35{
36 assert(pNewFrame->GetPara());
37
38 CtorInitAttrIter( *pNewFrame->GetTextNodeFirst(), pNewFrame->GetPara()->GetScriptInfo(), pNewFrame );
39
40 SwTextNode const*const pNode = pNewFrame->GetTextNodeForParaProps();
41
42 m_pFrame = pNewFrame;
43 m_pInf = pNewInf;
44 m_aLineInf.CtorInitLineInfo( pNode->GetSwAttrSet(), *pNode );
47
48 // Order is important: only execute FillRegister if GetValue!=0
51}
52
54{
58 m_bPrev = true;
59 m_pPrev = nullptr;
60 m_nLineNr = 1;
61}
62
63void SwTextIter::CalcAscentAndHeight( SwTwips &rAscent, SwTwips &rHeight ) const
64{
65 rHeight = GetLineHeight();
66 rAscent = m_pCurr->GetAscent() + rHeight - m_pCurr->Height();
67}
68
70{
71 m_pPrev = nullptr;
72 m_bPrev = true;
74 if( m_pCurr == pLay )
75 return nullptr;
76 while( pLay->GetNext() != m_pCurr )
77 pLay = pLay->GetNext();
78 m_pPrev = pLay;
79 return m_pPrev;
80}
81
83{
84 if(! m_bPrev)
85 GetPrev_();
86 return m_pPrev;
87}
88
90{
91 if( !m_bPrev )
92 GetPrev_();
93 if( m_pPrev )
94 {
95 m_bPrev = false;
99 if( !m_pCurr->IsDummy() && !(--m_nLineNr) )
100 ++m_nLineNr;
101 return m_pCurr;
102 }
103 else
104 return nullptr;
105}
106
108{
109 if(m_pCurr->GetNext())
110 {
112 m_bPrev = true;
114 m_nY += GetLineHeight();
115 if( m_pCurr->GetLen() || ( m_nLineNr>1 && !m_pCurr->IsDummy() ) )
116 ++m_nLineNr;
118 return m_pCurr;
119 }
120 else
121 return nullptr;
122}
123
125{
126 const SwLineLayout *pNext = Next();
127 while( pNext && pNext->IsDummy() && pNext->GetNext() )
128 {
129 pNext = Next();
130 }
131 return pNext;
132}
133
135{
136 const SwLineLayout *pNext = m_pCurr->GetNext();
137 while( pNext && pNext->IsDummy() && pNext->GetNext() )
138 {
139 pNext = pNext->GetNext();
140 }
141 return pNext;
142}
143
145{
146 const SwLineLayout *pRoot = m_pInf->GetParaPortion();
147 if( pRoot == m_pCurr )
148 return nullptr;
149 const SwLineLayout *pLay = pRoot;
150
151 while( pLay->GetNext() != m_pCurr )
152 pLay = pLay->GetNext();
153
154 if( pLay->IsDummy() )
155 {
156 const SwLineLayout *pTmp = pRoot;
157 pLay = pRoot->IsDummy() ? nullptr : pRoot;
158 while( pTmp->GetNext() != m_pCurr )
159 {
160 if( !pTmp->IsDummy() )
161 pLay = pTmp;
162 pTmp = pTmp->GetNext();
163 }
164 }
165
166 // If nothing has changed, then there are only dummy's
167 return pLay;
168}
169
171{
172 const SwLineLayout *pMyPrev = Prev();
173 if( !pMyPrev )
174 return nullptr;
175
176 const SwLineLayout *pLast = pMyPrev;
177 while( pMyPrev && pMyPrev->IsDummy() )
178 {
179 pLast = pMyPrev;
180 pMyPrev = Prev();
181 }
182 return pMyPrev ? pMyPrev : pLast;
183}
184
186{
187 while( Next() )
188 {
189 // nothing
190 }
191}
192
194{
195 while( m_nStart + m_pCurr->GetLen() <= nChar && Next() )
196 ;
197 while( m_nStart > nChar && Prev() )
198 ;
199}
200
201// 1170: takes into account ambiguities:
203{
204 CharToLine( nPosition );
205 if( nPosition != m_nStart )
206 s_bRightMargin = false;
207 bool bPrevious = s_bRightMargin && m_pCurr->GetLen() && GetPrev() &&
208 GetPrev()->GetLen();
209 if (bPrevious && nPosition && CH_BREAK == GetInfo().GetChar(nPosition - TextFrameIndex(1)))
210 bPrevious = false;
211 return bPrevious ? PrevLine() : m_pCurr;
212}
213
215 const SwLinePortion* pPor,
216 SwTwips nPorHeight, SwTwips nPorAscent,
217 const bool bAutoToCentered ) const
218{
219 if ( pPor )
220 {
221 nPorHeight = pPor->Height();
222 nPorAscent = pPor->GetAscent();
223 }
224
225 SwTwips nOfst = rLine.GetRealHeight() - rLine.Height();
226
227 SwTextGridItem const*const pGrid(GetGridItem(m_pFrame->FindPageFrame()));
228
229 if ( pGrid && GetInfo().SnapToGrid() && pGrid->IsSquaredMode() )
230 {
231 const sal_uInt16 nRubyHeight = pGrid->GetRubyHeight();
232 const bool bRubyTop = ! pGrid->GetRubyTextBelow();
233
234 if ( GetInfo().IsMulti() )
235 // we are inside the GetCharRect recursion for multi portions
236 // we center the portion in its surrounding line
237 nOfst = ( m_pCurr->Height() - nPorHeight ) / 2 + nPorAscent;
238 else
239 {
240 // We have to take care for ruby portions.
241 // The ruby portion is NOT centered
242 nOfst = nOfst + nPorAscent;
243
244 if ( ! pPor || ! pPor->IsMultiPortion() ||
245 ! static_cast<const SwMultiPortion*>(pPor)->IsRuby() )
246 {
247 // Portions which are bigger than on grid distance are
248 // centered inside the whole line.
249
250 //for text refactor
251 const sal_uInt16 nLineNet = rLine.Height() - nRubyHeight;
252 //const sal_uInt16 nLineNet = ( nPorHeight > nGridWidth ) ?
253 // rLine.Height() - nRubyHeight :
254 // nGridWidth;
255 nOfst += ( nLineNet - nPorHeight ) / 2;
256 if ( bRubyTop )
257 nOfst += nRubyHeight;
258 }
259 }
260 }
261 else
262 {
263 switch ( GetLineInfo().GetVertAlign() ) {
265 nOfst = nOfst + nPorAscent;
266 break;
268 OSL_ENSURE( rLine.Height() >= nPorHeight, "Portion height > Line height");
269 nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent;
270 break;
272 nOfst += rLine.Height() - nPorHeight + nPorAscent;
273 break;
275 if ( bAutoToCentered || GetInfo().GetTextFrame()->IsVertical() )
276 {
277 // Vertical text has these cases to calculate the baseline:
278 // - Implicitly TB and RL: the origo is the top right corner, offset is the
279 // ascent.
280 // - (Implicitly TB and) LR: the origo is the top left corner, offset is the
281 // descent.
282 // - BT and LR: the origo is the bottom left corner, offset is the ascent.
284 nOfst += rLine.Height() - ( rLine.Height() - nPorHeight ) / 2 - nPorAscent;
285 else
286 nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent;
287 break;
288 }
289 [[fallthrough]];
291 // base line
292 if (pPor && pPor->GetHangingBaseline())
293 {
294 nOfst += rLine.GetAscent() // Romn baseline of the line.
295 - rLine.GetHangingBaseline() // Hanging baseline of the line.
296 + pPor->GetHangingBaseline(); // Romn baseline of the portion.
297 }
298 else
299 nOfst = nOfst + rLine.GetAscent();
300 break;
301 }
302 }
303
304 return nOfst;
305}
306
308{
309 while( m_nY + GetLineHeight() <= y && Next() )
310 ;
311 while( m_nY > y && Prev() )
312 ;
313}
314
315// Local helper function to check, if pCurr needs a field rest portion:
316static bool lcl_NeedsFieldRest( const SwLineLayout* pCurr )
317{
318 const SwLinePortion *pPor = pCurr->GetNextPortion();
319 bool bRet = false;
320 while( pPor && !bRet )
321 {
322 bRet = pPor->InFieldGrp() && static_cast<const SwFieldPortion*>(pPor)->HasFollow();
323 if( !pPor->GetNextPortion() || !pPor->GetNextPortion()->InFieldGrp() )
324 break;
325 pPor = pPor->GetNextPortion();
326 }
327 return bRet;
328}
329
330void SwTextIter::TruncLines( bool bNoteFollow )
331{
332 SwLineLayout *pDel = m_pCurr->GetNext();
333 TextFrameIndex const nEnd = m_nStart + m_pCurr->GetLen();
334
335 if( pDel )
336 {
337 m_pCurr->SetNext( nullptr );
338 if (MaybeHasHints() && bNoteFollow)
339 {
342
343 // bug 88534: wrong positioning of flys
344 SwTextFrame* pFollow = GetTextFrame()->GetFollow();
345 if ( pFollow && ! pFollow->IsLocked() &&
346 nEnd == pFollow->GetOffset() )
347 {
348 TextFrameIndex nRangeEnd = nEnd;
349 SwLineLayout* pLine = pDel;
350
351 // determine range to be searched for flys anchored as characters
352 while ( pLine )
353 {
354 nRangeEnd = nRangeEnd + pLine->GetLen();
355 pLine = pLine->GetNext();
356 }
357
358 // examine hints in range nEnd - (nEnd + nRangeChar)
359 SwTextNode const* pNode(nullptr);
361 for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
362 {
363 if( RES_TXTATR_FLYCNT == pHt->Which() )
364 {
365 // check if hint is in our range
366 TextFrameIndex const nTmpPos(
367 GetTextFrame()->MapModelToView(pNode, pHt->GetStart()));
368 if ( nEnd <= nTmpPos && nTmpPos < nRangeEnd )
369 pFollow->InvalidateRange_(
370 SwCharRange( nTmpPos, nTmpPos ) );
371 }
372 }
373 }
374 }
375 delete pDel;
376 }
377 if( m_pCurr->IsDummy() &&
378 !m_pCurr->GetLen() &&
380 {
382 }
383 if (MaybeHasHints())
384 m_pFrame->RemoveFootnote( nEnd );
385}
386
387void SwTextIter::CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const
388{
389 nEndCnt = 0;
390 nMidCnt = 0;
391 if ( m_bPrev && m_pPrev && !m_pPrev->IsEndHyph() && !m_pPrev->IsMidHyph() )
392 return;
394 if( m_pCurr == pLay )
395 return;
396 while( pLay != m_pCurr )
397 {
398 if ( pLay->IsEndHyph() )
399 nEndCnt++;
400 else
401 nEndCnt = 0;
402 if ( pLay->IsMidHyph() )
403 nMidCnt++;
404 else
405 nMidCnt = 0;
406 pLay = pLay->GetNext();
407 }
408}
409
410// Change current output device to formatting device, this has to be done before
411// formatting.
413 pInf( &rInfo ),
414 pOut( rInfo.GetOut() ),
415 bOnWin( rInfo.OnWin() )
416{
417 OSL_ENSURE( rInfo.GetRefDev(), "No reference device for text formatting" );
418
419 // set new values
420 rInfo.SetOut( rInfo.GetRefDev() );
421 rInfo.SetOnWin( false );
422}
423
425{
426 pInf->SetOut( pOut );
427 pInf->SetOnWin( bOnWin );
428}
429
430/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
bool GetValue() const
bool MaybeHasHints() const
Definition: itratr.cxx:123
void CtorInitAttrIter(SwTextNode &rTextNode, SwScriptInfo &rScrInf, SwTextFrame const *pFrame=nullptr)
Definition: redlnitr.cxx:520
const SwRegisterItem & GetRegister(bool=true) const
Definition: paratr.hxx:198
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:726
const SwRect & getFrameArea() const
Definition: frame.hxx:179
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
bool IsVertLRBT() const
Definition: frame.hxx:983
bool IsVertical() const
Definition: frame.hxx:973
bool IsVertLR() const
Definition: frame.hxx:979
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
SwTextSizeInfo * pInf
Definition: itrtxt.hxx:303
VclPtr< OutputDevice > pOut
Definition: itrtxt.hxx:304
~SwHookOut()
Definition: itrtxt.cxx:424
bool bOnWin
Definition: itrtxt.hxx:305
SwHookOut(SwTextSizeInfo &rInfo)
Definition: itrtxt.cxx:412
void CtorInitLineInfo(const SwAttrSet &rAttrSet, const SwTextNode &rTextNode)
Definition: inftxt.cxx:99
SvxParaVertAlignItem::Align GetVertAlign() const
Definition: inftxt.hxx:85
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:79
bool IsRest() const
Definition: porlay.hxx:129
SwLineLayout * GetNext()
Definition: porlay.hxx:159
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:225
bool IsMidHyph() const
Definition: porlay.hxx:125
bool IsDummy() const
Definition: porlay.hxx:151
void SetRealHeight(SwTwips nNew)
Definition: porlay.hxx:168
SwTwips GetRealHeight() const
Definition: porlay.hxx:169
bool IsEndHyph() const
Definition: porlay.hxx:123
void SetNext(SwLineLayout *pNew)
Definition: porlay.hxx:161
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:52
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:75
TextFrameIndex GetLen() const
Definition: porlin.hxx:77
SwTwips GetHangingBaseline() const
Definition: porlin.hxx:89
SwTwips & GetAscent()
Definition: porlin.hxx:80
bool IsMultiPortion() const
Definition: porlin.hxx:143
bool InFieldGrp() const
Definition: porlin.hxx:111
void SetFollowField(const bool bNew)
Definition: porlay.hxx:313
SwScriptInfo & GetScriptInfo()
Definition: porlay.hxx:291
SwTwips Height() const
Definition: possiz.hxx:49
void Pos(const Point &rNew)
Definition: swrect.hxx:171
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const SwLineLayout * CharCursorToLine(TextFrameIndex const nPos)
Definition: itrtxt.cxx:202
static bool s_bRightMargin
Definition: itrtxt.hxx:268
SwTwips AdjustBaseLine(const SwLineLayout &rLine, const SwLinePortion *pPor, SwTwips nPorHeight=0, SwTwips nAscent=0, const bool bAutoToCentered=false) const
Definition: itrtxt.cxx:214
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:163
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:859
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:442
bool FillRegister(SwTwips &rRegStart, sal_uInt16 &rRegDiff)
Determines the start position and step size of the register.
Definition: porrst.cxx:466
void RemoveFootnote(TextFrameIndex nStart, TextFrameIndex nLen=TextFrameIndex(COMPLETE_STRING))
Footnote.
Definition: txtftn.cxx:407
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
bool IsLocked() const
Definition: txtfrm.hxx:521
void InvalidateRange_(const SwCharRange &, const tools::Long=0)
Definition: txtfrm.cxx:1696
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:461
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1306
bool GetRubyTextBelow() const
Definition: tgrditem.hxx:85
bool IsSquaredMode() const
Definition: tgrditem.hxx:104
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
SwParaPortion * GetParaPortion()
Definition: inftxt.hxx:121
TextFrameIndex GetTextStart() const
Definition: inftxt.hxx:123
const SwLineLayout * NextLine()
Definition: itrtxt.cxx:124
SwTwips m_nRegStart
Definition: itrtxt.hxx:40
void Init()
Definition: itrtxt.cxx:53
SwTwips m_nY
Definition: itrtxt.hxx:39
void TruncLines(bool bNoteFollow=false)
Definition: itrtxt.cxx:330
void Bottom()
Definition: itrtxt.cxx:185
sal_uInt16 m_nLineNr
Definition: itrtxt.hxx:43
const SwLineLayout * PrevLine()
Definition: itrtxt.cxx:170
void TwipsToLine(const SwTwips)
Definition: itrtxt.cxx:307
SwTwips m_nFrameStart
Definition: itrtxt.hxx:38
const SwLineLayout * GetPrevLine()
Definition: itrtxt.cxx:144
SwLineLayout * m_pCurr
Definition: itrtxt.hxx:36
SwTwips GetLineHeight() const
Definition: itrtxt.hxx:116
const SwLineLayout * Next()
Definition: itrtxt.cxx:107
SwLineLayout * m_pPrev
Definition: itrtxt.hxx:37
SwTextFrame * m_pFrame
Definition: itrtxt.hxx:34
void CharToLine(TextFrameIndex)
Definition: itrtxt.cxx:193
SwTextInfo & GetInfo()
Definition: itrtxt.hxx:96
const SwLineLayout * Prev()
Definition: itrtxt.cxx:89
SwTextFrame * GetTextFrame()
Definition: itrtxt.hxx:134
TextFrameIndex m_nStart
Definition: itrtxt.hxx:41
void CalcAscentAndHeight(SwTwips &rAscent, SwTwips &rHeight) const
Definition: itrtxt.cxx:63
const SwLineInfo & GetLineInfo() const
Definition: itrtxt.hxx:128
const SwLineLayout * GetNextLine() const
Definition: itrtxt.cxx:134
bool m_bRegisterOn
Definition: itrtxt.hxx:45
void CntHyphens(sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const
Definition: itrtxt.cxx:387
SwTextInfo * m_pInf
Definition: itrtxt.hxx:35
sal_uInt16 m_nRegDiff
Definition: itrtxt.hxx:42
bool m_bPrev
Definition: itrtxt.hxx:44
SwLineInfo m_aLineInf
Definition: itrtxt.hxx:33
const SwLineLayout * GetPrev()
Definition: itrtxt.cxx:82
SwLineLayout * GetPrev_()
Definition: itrtxt.cxx:69
void CtorInitTextIter(SwTextFrame *pFrame, SwTextInfo *pInf)
Definition: itrtxt.cxx:34
SwTextSizeInfo & GetInfo()
Definition: itrtxt.hxx:216
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:84
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:285
vcl::RenderContext * GetRefDev()
Definition: inftxt.hxx:228
void SetOnWin(const bool bNew)
Definition: inftxt.hxx:193
void SetOut(OutputDevice *pNewOut)
Definition: inftxt.hxx:226
SwTextAttr const * NextAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:91
float y
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(58)
static bool lcl_NeedsFieldRest(const SwLineLayout *pCurr)
Definition: itrtxt.cxx:316
double getLength(const B2DPolygon &rCandidate)
tools::Long SnapToGrid(std::vector< sal_Int32 > &rKernArray, const OUString &rText, sal_Int32 nStt, sal_Int32 nLen, tools::Long nGridWidth, bool bForceLeft)
Snap ideographs to text grids: a) Ideographic open brackets are aligned to the rightmost edge of span...
Definition: justify.cxx:172
TextFrameIndex MapModelToView(MergedPara const &, SwTextNode const *pNode, sal_Int32 nIndex)
Definition: txtfrm.cxx:1186
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2595
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
tools::Long SwTwips
Definition: swtypes.hxx:51
unsigned char sal_uInt8
oslFileHandle & pOut