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