Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <vcl/outdev.hxx>
30 : : #include <SwPortionHandler.hxx>
31 : :
32 : : #include "porlin.hxx"
33 : : #include "inftxt.hxx"
34 : : #include "portxt.hxx"
35 : : #include "pormulti.hxx"
36 : : #include "porglue.hxx"
37 : : #include "blink.hxx"
38 : : #if OSL_DEBUG_LEVEL > 0
39 : :
40 : : sal_Bool ChkChain( SwLinePortion *pStart )
41 : : {
42 : : SwLinePortion *pPor = pStart->GetPortion();
43 : : MSHORT nCount = 0;
44 : : while( pPor )
45 : : {
46 : : ++nCount;
47 : : OSL_ENSURE( nCount < 200 && pPor != pStart,
48 : : "ChkChain(): lost in chains" );
49 : : if( nCount >= 200 || pPor == pStart )
50 : : {
51 : : // der Lebensretter
52 : : pPor = pStart->GetPortion();
53 : : pStart->SetPortion(0);
54 : : pPor->Truncate();
55 : : pStart->SetPortion( pPor );
56 : : return sal_False;
57 : : }
58 : : pPor = pPor->GetPortion();
59 : : }
60 : : return sal_True;
61 : : }
62 : : #endif
63 : :
64 : :
65 : 26601 : SwLinePortion::~SwLinePortion()
66 : : {
67 [ + + ]: 26601 : if( pBlink )
68 : 3032 : pBlink->Delete( this );
69 [ - + ]: 26601 : }
70 : :
71 : 7807 : SwLinePortion *SwLinePortion::Compress()
72 : : {
73 [ + + ][ + + ]: 7807 : return GetLen() || Width() ? this : 0;
74 : : }
75 : :
76 : 2909 : KSHORT SwLinePortion::GetViewWidth( const SwTxtSizeInfo & ) const
77 : : {
78 : 2909 : return 0;
79 : : }
80 : :
81 : : /*************************************************************************
82 : : * SwLinePortion::SwLinePortion( )
83 : : *************************************************************************/
84 : :
85 : 23429 : SwLinePortion::SwLinePortion( ) :
86 : : pPortion( NULL ),
87 : : nLineLength( 0 ),
88 : 23429 : nAscent( 0 )
89 : : {
90 : 23429 : }
91 : :
92 : : /*************************************************************************
93 : : * SwLinePortion::PrePaint()
94 : : *************************************************************************/
95 : :
96 : 5392 : void SwLinePortion::PrePaint( const SwTxtPaintInfo& rInf,
97 : : const SwLinePortion* pLast ) const
98 : : {
99 : : OSL_ENSURE( rInf.OnWin(), "SwLinePortion::PrePaint: don't prepaint on a printer");
100 : : OSL_ENSURE( !Width(), "SwLinePortion::PrePaint: For Width()==0 only!");
101 : :
102 [ + - ]: 5392 : const KSHORT nViewWidth = GetViewWidth( rInf );
103 : :
104 [ + + ]: 5392 : if( ! nViewWidth )
105 : 5392 : return;
106 : :
107 : 1388 : const KSHORT nHalfView = nViewWidth / 2;
108 : 1388 : sal_uInt16 nLastWidth = pLast->Width();
109 : :
110 [ + - ][ + - ]: 1388 : if ( pLast->InSpaceGrp() && rInf.GetSpaceAdd() )
[ - + ][ - + ]
[ + - ]
111 [ # # ][ # # ]: 0 : nLastWidth = nLastWidth + (sal_uInt16)pLast->CalcSpacing( rInf.GetSpaceAdd(), rInf );
112 : :
113 : : KSHORT nPos;
114 [ + - ]: 1388 : SwTxtPaintInfo aInf( rInf );
115 : :
116 [ + - ]: 1388 : const sal_Bool bBidiPor = ( rInf.GetTxtFrm()->IsRightToLeft() ) !=
117 : 1388 : ( 0 != ( TEXT_LAYOUT_BIDI_RTL & rInf.GetOut()->GetLayoutMode() ) );
118 : :
119 : : sal_uInt16 nDir = bBidiPor ?
120 : : 1800 :
121 [ + - ][ + - ]: 1388 : rInf.GetFont()->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
[ + - ]
122 : :
123 [ + - - - : 1388 : switch ( nDir )
- ]
124 : : {
125 : : case 0 :
126 : 1388 : nPos = KSHORT( rInf.X() );
127 [ + + ]: 1388 : if( nLastWidth > nHalfView )
128 : 1072 : nPos += nLastWidth - nHalfView;
129 : 1388 : aInf.X( nPos );
130 : 1388 : break;
131 : : case 900 :
132 : 0 : nPos = KSHORT( rInf.Y() );
133 [ # # ]: 0 : if( nLastWidth > nHalfView )
134 : 0 : nPos -= nLastWidth + nHalfView;
135 : 0 : aInf.Y( nPos );
136 : 0 : break;
137 : : case 1800 :
138 : 0 : nPos = KSHORT( rInf.X() );
139 [ # # ]: 0 : if( nLastWidth > nHalfView )
140 : 0 : nPos -= nLastWidth + nHalfView;
141 : 0 : aInf.X( nPos );
142 : 0 : break;
143 : : case 2700 :
144 : 0 : nPos = KSHORT( rInf.Y() );
145 [ # # ]: 0 : if( nLastWidth > nHalfView )
146 : 0 : nPos += nLastWidth - nHalfView;
147 : 0 : aInf.Y( nPos );
148 : 0 : break;
149 : : }
150 : :
151 : 1388 : SwLinePortion *pThis = (SwLinePortion*)this;
152 : 1388 : pThis->Width( nViewWidth );
153 [ + - ]: 1388 : Paint( aInf );
154 [ + - ]: 5392 : pThis->Width(0);
155 : : }
156 : :
157 : : /*************************************************************************
158 : : * SwLinePortion::CalcTxtSize()
159 : : *************************************************************************/
160 : :
161 : 133 : void SwLinePortion::CalcTxtSize( const SwTxtSizeInfo &rInf )
162 : : {
163 [ + - ]: 133 : if( GetLen() == rInf.GetLen() )
164 : 133 : *((SwPosSize*)this) = GetTxtSize( rInf );
165 : : else
166 : : {
167 [ # # ]: 0 : SwTxtSizeInfo aInf( rInf );
168 : 0 : aInf.SetLen( GetLen() );
169 [ # # ]: 0 : *((SwPosSize*)this) = GetTxtSize( aInf );
170 : : }
171 : 133 : }
172 : :
173 : : /*************************************************************************
174 : : * SwLinePortion::Truncate()
175 : : *
176 : : * Es werden alle nachfolgenden Portions geloescht.
177 : : *************************************************************************/
178 : :
179 : 5501 : void SwLinePortion::_Truncate()
180 : : {
181 : 5501 : SwLinePortion *pPos = pPortion;
182 [ + + ]: 12169 : do
183 : : { OSL_ENSURE( pPos != this, "SwLinePortion::Truncate: loop" );
184 : 12169 : SwLinePortion *pLast = pPos;
185 : 12169 : pPos = pPos->GetPortion();
186 : 12169 : pLast->SetPortion( 0 );
187 [ + - ]: 12169 : delete pLast;
188 : :
189 : : } while( pPos );
190 : :
191 : 5501 : pPortion = 0;
192 : 5501 : }
193 : :
194 : : /*************************************************************************
195 : : * virtual SwLinePortion::Insert()
196 : : *
197 : : * Es wird immer hinter uns eingefuegt.
198 : : *************************************************************************/
199 : :
200 : 5229 : SwLinePortion *SwLinePortion::Insert( SwLinePortion *pIns )
201 : : {
202 : 5229 : pIns->FindLastPortion()->SetPortion( pPortion );
203 : 5229 : SetPortion( pIns );
204 : : #if OSL_DEBUG_LEVEL > 0
205 : : ChkChain( this );
206 : : #endif
207 : 5229 : return pIns;
208 : : }
209 : :
210 : : /*************************************************************************
211 : : * SwLinePortion::FindLastPortion()
212 : : *************************************************************************/
213 : :
214 : 7167 : SwLinePortion *SwLinePortion::FindLastPortion()
215 : : {
216 : 7167 : SwLinePortion *pPos = this;
217 : : // An das Ende wandern und pLinPortion an den letzten haengen ...
218 [ + + ]: 9068 : while( pPos->GetPortion() )
219 : : {
220 : 1901 : pPos = pPos->GetPortion();
221 : : }
222 : 7167 : return pPos;
223 : : }
224 : :
225 : : /*************************************************************************
226 : : * virtual SwLinePortion::Append()
227 : : *************************************************************************/
228 : :
229 : 969 : SwLinePortion *SwLinePortion::Append( SwLinePortion *pIns )
230 : : {
231 : 969 : SwLinePortion *pPos = FindLastPortion();
232 : 969 : pPos->SetPortion( pIns );
233 : 969 : pIns->SetPortion( 0 );
234 : : #if OSL_DEBUG_LEVEL > 0
235 : : ChkChain( this );
236 : : #endif
237 : 969 : return pIns;
238 : : }
239 : :
240 : : /*************************************************************************
241 : : * virtual SwLinePortion::Cut()
242 : : *************************************************************************/
243 : :
244 : 607 : SwLinePortion *SwLinePortion::Cut( SwLinePortion *pVictim )
245 : : {
246 : 607 : SwLinePortion *pPrev = pVictim->FindPrevPortion( this );
247 : : OSL_ENSURE( pPrev, "SwLinePortion::Cut(): can't cut" );
248 : 607 : pPrev->SetPortion( pVictim->GetPortion() );
249 : 607 : pVictim->SetPortion(0);
250 : 607 : return pVictim;
251 : : }
252 : :
253 : : /*************************************************************************
254 : : * SwLinePortion::FindPrevPortion()
255 : : *************************************************************************/
256 : :
257 : 863 : SwLinePortion *SwLinePortion::FindPrevPortion( const SwLinePortion *pRoot )
258 : : {
259 : : OSL_ENSURE( pRoot != this, "SwLinePortion::FindPrevPortion(): invalid root" );
260 : 863 : SwLinePortion *pPos = (SwLinePortion*)pRoot;
261 [ + - ][ + + ]: 1119 : while( pPos->GetPortion() && pPos->GetPortion() != this )
[ + + ]
262 : : {
263 : 256 : pPos = pPos->GetPortion();
264 : : }
265 : : OSL_ENSURE( pPos->GetPortion(),
266 : : "SwLinePortion::FindPrevPortion: blowing in the wind");
267 : 863 : return pPos;
268 : : }
269 : :
270 : : /*************************************************************************
271 : : * virtual SwLinePortion::GetCrsrOfst()
272 : : *************************************************************************/
273 : :
274 : 62 : xub_StrLen SwLinePortion::GetCrsrOfst( const KSHORT nOfst ) const
275 : : {
276 [ + + ]: 62 : if( nOfst > ( PrtWidth() / 2 ) )
277 : 4 : return GetLen();
278 : : else
279 : 62 : return 0;
280 : : }
281 : :
282 : : /*************************************************************************
283 : : * virtual SwLinePortion::GetTxtSize()
284 : : *************************************************************************/
285 : :
286 : 0 : SwPosSize SwLinePortion::GetTxtSize( const SwTxtSizeInfo & ) const
287 : : {
288 : : OSL_ENSURE( !this, "SwLinePortion::GetTxtSize: don't ask me about sizes, "
289 : : "I'm only a stupid SwLinePortion" );
290 : 0 : return SwPosSize();
291 : : }
292 : :
293 : : /*************************************************************************
294 : : * virtual SwLinePortion::Format()
295 : : *************************************************************************/
296 : :
297 : 322 : sal_Bool SwLinePortion::Format( SwTxtFormatInfo &rInf )
298 : : {
299 [ - + ]: 322 : if( rInf.X() > rInf.Width() )
300 : : {
301 : 0 : Truncate();
302 : 0 : rInf.SetUnderFlow( this );
303 : 0 : return sal_True;
304 : : }
305 : :
306 : 322 : const SwLinePortion *pLast = rInf.GetLast();
307 : 322 : Height( pLast->Height() );
308 : 322 : SetAscent( pLast->GetAscent() );
309 : 322 : const KSHORT nNewWidth = static_cast<sal_uInt16>(rInf.X() + PrtWidth());
310 : : // Nur Portions mit echter Breite koennen ein sal_True zurueckliefern
311 : : // Notizen beispielsweise setzen niemals bFull==sal_True
312 [ # # ][ # # ]: 322 : if( rInf.Width() <= nNewWidth && PrtWidth() && ! IsKernPortion() )
[ - + ][ - + ]
313 : : {
314 : 0 : Truncate();
315 [ # # ]: 0 : if( nNewWidth > rInf.Width() )
316 : 0 : PrtWidth( nNewWidth - rInf.Width() );
317 : 0 : rInf.GetLast()->FormatEOL( rInf );
318 : 0 : return sal_True;
319 : : }
320 : 322 : return sal_False;
321 : : }
322 : :
323 : : /*************************************************************************
324 : : * virtual SwLinePortion::FormatEOL()
325 : : *************************************************************************/
326 : :
327 : : // Format end of line
328 : :
329 : 26 : void SwLinePortion::FormatEOL( SwTxtFormatInfo & )
330 : 26 : { }
331 : :
332 : : /*************************************************************************
333 : : * SwLinePortion::Move()
334 : : *************************************************************************/
335 : :
336 : 109104 : void SwLinePortion::Move( SwTxtPaintInfo &rInf )
337 : : {
338 : 109104 : sal_Bool bB2T = rInf.GetDirection() == DIR_BOTTOM2TOP;
339 : 109104 : const sal_Bool bFrmDir = rInf.GetTxtFrm()->IsRightToLeft();
340 : 109104 : sal_Bool bCounterDir = ( ! bFrmDir && DIR_RIGHT2LEFT == rInf.GetDirection() ) ||
341 [ - + ][ # # ]: 218208 : ( bFrmDir && DIR_LEFT2RIGHT == rInf.GetDirection() );
[ + - + - ]
342 : :
343 [ + + ][ - + ]: 109104 : if ( InSpaceGrp() && rInf.GetSpaceAdd() )
[ - + ]
344 : : {
345 : 0 : SwTwips nTmp = PrtWidth() + CalcSpacing( rInf.GetSpaceAdd(), rInf );
346 [ # # ]: 0 : if( rInf.IsRotated() )
347 [ # # ]: 0 : rInf.Y( rInf.Y() + ( bB2T ? -nTmp : nTmp ) );
348 [ # # ]: 0 : else if ( bCounterDir )
349 : 0 : rInf.X( rInf.X() - nTmp );
350 : : else
351 : 0 : rInf.X( rInf.X() + nTmp );
352 : : }
353 : : else
354 : : {
355 [ + + ][ + + ]: 109104 : if( InFixMargGrp() && !IsMarginPortion() )
[ + + ]
356 : : {
357 : 681 : rInf.IncSpaceIdx();
358 : 681 : rInf.IncKanaIdx();
359 : : }
360 [ - + ]: 109104 : if( rInf.IsRotated() )
361 [ # # ]: 0 : rInf.Y( rInf.Y() + ( bB2T ? -PrtWidth() : PrtWidth() ) );
362 [ - + ]: 109104 : else if ( bCounterDir )
363 : 0 : rInf.X( rInf.X() - PrtWidth() );
364 : : else
365 : 109104 : rInf.X( rInf.X() + PrtWidth() );
366 : : }
367 [ + + ][ - + ]: 109104 : if( IsMultiPortion() && ((SwMultiPortion*)this)->HasTabulator() )
[ - + ]
368 : 0 : rInf.IncSpaceIdx();
369 : :
370 : 109104 : rInf.SetIdx( rInf.GetIdx() + GetLen() );
371 : 109104 : }
372 : :
373 : : /*************************************************************************
374 : : * virtual SwLinePortion::CalcSpacing()
375 : : *************************************************************************/
376 : :
377 : 0 : long SwLinePortion::CalcSpacing( long , const SwTxtSizeInfo & ) const
378 : : {
379 : 0 : return 0;
380 : : }
381 : :
382 : : /*************************************************************************
383 : : * virtual SwLinePortion::GetExpTxt()
384 : : *************************************************************************/
385 : :
386 : 0 : sal_Bool SwLinePortion::GetExpTxt( const SwTxtSizeInfo &, XubString & ) const
387 : : {
388 : 0 : return sal_False;
389 : : }
390 : :
391 : : /*************************************************************************
392 : : * virtual SwLinePortion::HandlePortion()
393 : : *************************************************************************/
394 : :
395 : 7 : void SwLinePortion::HandlePortion( SwPortionHandler& rPH ) const
396 : : {
397 [ + - ]: 7 : String aString;
398 [ + - ][ + - ]: 7 : rPH.Special( GetLen(), aString, GetWhichPor(), Height(), Width() );
399 : 7 : }
400 : :
401 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|