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