LibreOffice Module sw (master)  1
porlin.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 <vcl/outdev.hxx>
21 #include <SwPortionHandler.hxx>
22 
23 #include "porlin.hxx"
24 #include "inftxt.hxx"
25 #include "portxt.hxx"
26 #include "pormulti.hxx"
27 #include "porglue.hxx"
28 #include <blink.hxx>
29 #if OSL_DEBUG_LEVEL > 0
30 
31 static bool ChkChain( SwLinePortion *pStart )
32 {
33  SwLinePortion *pPor = pStart->GetNextPortion();
34  sal_uInt16 nCount = 0;
35  while( pPor )
36  {
37  ++nCount;
38  OSL_ENSURE( nCount < 200 && pPor != pStart,
39  "ChkChain(): lost in chains" );
40  if( nCount >= 200 || pPor == pStart )
41  {
42  // the lifesaver
43  pPor = pStart->GetNextPortion();
44  pStart->SetNextPortion(nullptr);
45  pPor->Truncate();
46  pStart->SetNextPortion( pPor );
47  return false;
48  }
49  pPor = pPor->GetNextPortion();
50  }
51  return true;
52 }
53 #endif
54 
56 {
57  if( pBlink )
58  pBlink->Delete( this );
59 }
60 
62 {
63  return GetLen() || Width() ? this : nullptr;
64 }
65 
66 sal_uInt16 SwLinePortion::GetViewWidth( const SwTextSizeInfo & ) const
67 {
68  return 0;
69 }
70 
72  mpNextPortion( nullptr ),
73  nLineLength( 0 ),
74  nAscent( 0 ),
75  nWhichPor( PortionType::NONE ),
76  m_bJoinBorderWithPrev(false),
77  m_bJoinBorderWithNext(false)
78 {
79 }
80 
82  const SwLinePortion* pLast ) const
83 {
84  OSL_ENSURE( rInf.OnWin(), "SwLinePortion::PrePaint: don't prepaint on a printer");
85  OSL_ENSURE( !Width(), "SwLinePortion::PrePaint: For Width()==0 only!");
86 
87  const sal_uInt16 nViewWidth = GetViewWidth( rInf );
88 
89  if( ! nViewWidth )
90  return;
91 
92  const sal_uInt16 nHalfView = nViewWidth / 2;
93  sal_uInt16 nLastWidth = pLast->Width();
94 
95  if ( pLast->InSpaceGrp() && rInf.GetSpaceAdd() )
96  nLastWidth = nLastWidth + static_cast<sal_uInt16>(pLast->CalcSpacing( rInf.GetSpaceAdd(), rInf ));
97 
98  sal_uInt16 nPos;
99  SwTextPaintInfo aInf( rInf );
100 
101  const bool bBidiPor = rInf.GetTextFrame()->IsRightToLeft() !=
102  bool( ComplexTextLayoutFlags::BiDiRtl & rInf.GetOut()->GetLayoutMode() );
103 
104  sal_uInt16 nDir = bBidiPor ?
105  1800 :
106  rInf.GetFont()->GetOrientation( rInf.GetTextFrame()->IsVertical() );
107 
108  switch ( nDir )
109  {
110  case 0 :
111  nPos = sal_uInt16( rInf.X() );
112  if( nLastWidth > nHalfView )
113  nPos += nLastWidth - nHalfView;
114  aInf.X( nPos );
115  break;
116  case 900 :
117  nPos = sal_uInt16( rInf.Y() );
118  if( nLastWidth > nHalfView )
119  nPos -= nLastWidth + nHalfView;
120  aInf.Y( nPos );
121  break;
122  case 1800 :
123  nPos = sal_uInt16( rInf.X() );
124  if( nLastWidth > nHalfView )
125  nPos -= nLastWidth + nHalfView;
126  aInf.X( nPos );
127  break;
128  case 2700 :
129  nPos = sal_uInt16( rInf.Y() );
130  if( nLastWidth > nHalfView )
131  nPos += nLastWidth - nHalfView;
132  aInf.Y( nPos );
133  break;
134  }
135 
136  SwLinePortion *pThis = const_cast<SwLinePortion*>(this);
137  pThis->Width( nViewWidth );
138  Paint( aInf );
139  pThis->Width(0);
140 }
141 
143 {
144  if( GetLen() == rInf.GetLen() )
145  *static_cast<SwPosSize*>(this) = GetTextSize( rInf );
146  else
147  {
148  SwTextSizeInfo aInf( rInf );
149  aInf.SetLen( GetLen() );
150  *static_cast<SwPosSize*>(this) = GetTextSize( aInf );
151  }
152 }
153 
154 // all following portions will be deleted
156 {
158  do
159  {
160  OSL_ENSURE( pPos != this, "SwLinePortion::Truncate: loop" );
161  SwLinePortion *pLast = pPos;
162  pPos = pPos->GetNextPortion();
163  pLast->SetNextPortion( nullptr );
164  delete pLast;
165 
166  } while( pPos );
167 
168  mpNextPortion = nullptr;
169 }
170 
171 // It always will be inserted after us.
173 {
175  SetNextPortion( pIns );
176 #if OSL_DEBUG_LEVEL > 0
177  ChkChain( this );
178 #endif
179  return pIns;
180 }
181 
183 {
184  SwLinePortion *pPos = this;
185  // Find the end and link pLinPortion to the last one...
186  while( pPos->GetNextPortion() )
187  {
188  pPos = pPos->GetNextPortion();
189  }
190  return pPos;
191 }
192 
194 {
195  SwLinePortion *pPos = FindLastPortion();
196  pPos->SetNextPortion( pIns );
197  pIns->SetNextPortion( nullptr );
198 #if OSL_DEBUG_LEVEL > 0
199  ChkChain( this );
200 #endif
201  return pIns;
202 }
203 
205 {
206  SwLinePortion *pPrev = pVictim->FindPrevPortion( this );
207  OSL_ENSURE( pPrev, "SwLinePortion::Cut(): can't cut" );
208  pPrev->SetNextPortion( pVictim->GetNextPortion() );
209  pVictim->SetNextPortion(nullptr);
210  return pVictim;
211 }
212 
214 {
215  OSL_ENSURE( pRoot != this, "SwLinePortion::FindPrevPortion(): invalid root" );
216  SwLinePortion *pPos = const_cast<SwLinePortion*>(pRoot);
217  while( pPos->GetNextPortion() && pPos->GetNextPortion() != this )
218  {
219  pPos = pPos->GetNextPortion();
220  }
221  OSL_ENSURE( pPos->GetNextPortion(),
222  "SwLinePortion::FindPrevPortion: blowing in the wind");
223  return pPos;
224 }
225 
226 TextFrameIndex SwLinePortion::GetCursorOfst(const sal_uInt16 nOfst) const
227 {
228  if( nOfst > ( PrtWidth() / 2 ) )
229  return GetLen();
230  else
231  return TextFrameIndex(0);
232 }
233 
235 {
236  OSL_ENSURE( false, "SwLinePortion::GetTextSize: don't ask me about sizes, "
237  "I'm only a stupid SwLinePortion" );
238  return SwPosSize();
239 }
240 
242 {
243  if( rInf.X() > rInf.Width() )
244  {
245  Truncate();
246  rInf.SetUnderflow( this );
247  return true;
248  }
249 
250  const SwLinePortion *pLast = rInf.GetLast();
251  Height( pLast->Height() );
252  SetAscent( pLast->GetAscent() );
253  const sal_uInt16 nNewWidth = static_cast<sal_uInt16>(rInf.X() + PrtWidth());
254  // Only portions with true width can return true
255  // Notes for example never set bFull==true
256  if( rInf.Width() <= nNewWidth && PrtWidth() && ! IsKernPortion() )
257  {
258  Truncate();
259  if( nNewWidth > rInf.Width() )
260  PrtWidth( nNewWidth - rInf.Width() );
261  rInf.GetLast()->FormatEOL( rInf );
262  return true;
263  }
264  return false;
265 }
266 
267 // Format end of line
268 
270 { }
271 
273 {
274  bool bB2T = rInf.GetDirection() == DIR_BOTTOM2TOP;
275  const bool bFrameDir = rInf.GetTextFrame()->IsRightToLeft();
276  bool bCounterDir = ( ! bFrameDir && DIR_RIGHT2LEFT == rInf.GetDirection() ) ||
277  ( bFrameDir && DIR_LEFT2RIGHT == rInf.GetDirection() );
278 
279  if ( InSpaceGrp() && rInf.GetSpaceAdd() )
280  {
281  SwTwips nTmp = PrtWidth() + CalcSpacing( rInf.GetSpaceAdd(), rInf );
282  if( rInf.IsRotated() )
283  rInf.Y( rInf.Y() + ( bB2T ? -nTmp : nTmp ) );
284  else if ( bCounterDir )
285  rInf.X( rInf.X() - nTmp );
286  else
287  rInf.X( rInf.X() + nTmp );
288  }
289  else
290  {
291  if( InFixMargGrp() && !IsMarginPortion() )
292  {
293  rInf.IncSpaceIdx();
294  rInf.IncKanaIdx();
295  }
296  if( rInf.IsRotated() )
297  rInf.Y( rInf.Y() + ( bB2T ? -PrtWidth() : PrtWidth() ) );
298  else if ( bCounterDir )
299  rInf.X( rInf.X() - PrtWidth() );
300  else
301  rInf.X( rInf.X() + PrtWidth() );
302  }
303  if( IsMultiPortion() && static_cast<SwMultiPortion*>(this)->HasTabulator() )
304  rInf.IncSpaceIdx();
305 
306  rInf.SetIdx( rInf.GetIdx() + GetLen() );
307 }
308 
309 long SwLinePortion::CalcSpacing( long , const SwTextSizeInfo & ) const
310 {
311  return 0;
312 }
313 
314 bool SwLinePortion::GetExpText( const SwTextSizeInfo &, OUString & ) const
315 {
316  return false;
317 }
318 
320 {
321  rPH.Special( GetLen(), OUString(), GetWhichPor(), Height(), Width() );
322 }
323 
324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool Format(SwTextFormatInfo &rInf)
Definition: porlin.cxx:241
void Move(SwTextPaintInfo &rInf)
Definition: porlin.cxx:272
bool InSpaceGrp() const
Definition: porlin.hxx:108
sal_uInt16 Height() const
Definition: possiz.hxx:44
SwFont * GetFont()
Definition: inftxt.hxx:238
void Truncate_()
Definition: porlin.cxx:155
void CalcTextSize(const SwTextSizeInfo &rInfo)
Definition: porlin.cxx:142
static bool ChkChain(SwLinePortion *pStart)
Definition: porlin.cxx:31
The SwPortionHandler interface implements a visitor for the layout engine's text portions.
ComplexTextLayoutFlags GetLayoutMode() const
long SwTwips
Definition: swtypes.hxx:49
sal_uInt16 GetOrientation(const bool bVertLayout=false, const bool bVertFormatLRBT=false) const
Definition: swfont.cxx:436
virtual SwLinePortion * Compress()
Definition: porlin.cxx:61
bool IsMarginPortion() const
Definition: porlin.hxx:123
virtual void Paint(const SwTextPaintInfo &rInf) const =0
void IncSpaceIdx()
Definition: inftxt.hxx:445
long GetSpaceAdd() const
Definition: inftxt.hxx:447
#define DIR_BOTTOM2TOP
Definition: inftxt.hxx:55
sal_uInt8 GetDirection() const
Definition: inftxt.hxx:224
bool InFixMargGrp() const
Definition: porlin.hxx:107
SwTwips Y() const
Definition: inftxt.hxx:387
virtual void Special(TextFrameIndex nLength, const OUString &rText, PortionType nType, sal_Int32 nHeight=0, sal_Int32 nWidth=0, const SwFont *pFont=nullptr)=0
special portion.
void IncKanaIdx()
Definition: inftxt.hxx:328
virtual SwLinePortion * Append(SwLinePortion *pPortion)
Definition: porlin.cxx:193
virtual TextFrameIndex GetCursorOfst(sal_uInt16 nOfst) const
the parameter is actually SwTwips apparently?
Definition: porlin.cxx:226
virtual sal_uInt16 GetViewWidth(const SwTextSizeInfo &rInf) const
Definition: porlin.cxx:66
#define DIR_LEFT2RIGHT
Definition: inftxt.hxx:54
SwPosSize(const sal_uInt16 nW=0, const sal_uInt16 nH=0)
Definition: possiz.hxx:31
virtual bool GetExpText(const SwTextSizeInfo &rInf, OUString &rText) const
Definition: porlin.cxx:314
vcl::RenderContext * GetOut()
Definition: inftxt.hxx:231
void SetUnderflow(SwLinePortion *pNew)
Definition: inftxt.hxx:606
bool IsKernPortion() const
Definition: porlin.hxx:131
sal_uInt16 Width() const
Definition: inftxt.hxx:533
virtual void HandlePortion(SwPortionHandler &rPH) const
Definition: porlin.cxx:319
PortionType
Definition: txttypes.hxx:22
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:278
void PrePaint(const SwTextPaintInfo &rInf, const SwLinePortion *pLast) const
Definition: porlin.cxx:81
SwLinePortion * Cut(SwLinePortion *pVictim)
Definition: porlin.cxx:204
TextFrameIndex GetLen() const
Definition: porlin.hxx:73
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:291
void Truncate()
Definition: porlin.hxx:195
SwLinePortion * mpNextPortion
Definition: porlin.hxx:53
bool IsMultiPortion() const
Definition: porlin.hxx:133
SwTwips X() const
Definition: inftxt.hxx:385
virtual ~SwLinePortion()
Definition: porlin.cxx:55
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:49
#define DIR_RIGHT2LEFT
Definition: inftxt.hxx:56
void SetLen(const TextFrameIndex nNew)
Definition: inftxt.hxx:281
PortionType GetWhichPor() const
Definition: porlin.hxx:94
SwLinePortion * FindLastPortion()
Definition: porlin.cxx:182
bool OnWin() const
Definition: inftxt.hxx:199
bool IsRightToLeft() const
Definition: frame.hxx:963
virtual SwPosSize GetTextSize(const SwTextSizeInfo &rInfo) const
Definition: porlin.cxx:234
TextFrameIndex GetLen() const
Definition: inftxt.hxx:280
SwLinePortion * FindPrevPortion(const SwLinePortion *pRoot)
Definition: porlin.cxx:213
sal_uInt16 Width() const
Definition: possiz.hxx:46
SwLinePortion * GetLast()
Definition: inftxt.hxx:566
void SetNextPortion(SwLinePortion *pNew)
Definition: porlin.hxx:75
void SetAscent(const sal_uInt16 nNewAsc)
Definition: porlin.hxx:78
bool IsVertical() const
Definition: frame.hxx:949
virtual void FormatEOL(SwTextFormatInfo &rInf)
Definition: porlin.cxx:269
bool IsRotated() const
Definition: inftxt.hxx:226
sal_uInt16 PrtWidth() const
Definition: porlin.hxx:80
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:71
void SetIdx(const TextFrameIndex nNew)
Definition: inftxt.hxx:279
sal_Int32 nPos
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...
virtual long CalcSpacing(long nSpaceAdd, const SwTextSizeInfo &rInf) const
Definition: porlin.cxx:309
sal_uInt16 & GetAscent()
Definition: porlin.hxx:76
virtual SwLinePortion * Insert(SwLinePortion *pPortion)
Definition: porlin.cxx:172