merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / text / porlin.cxx
blob1e866c8323c281937e7048af3c39125c54a19b52
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: porlin.cxx,v $
10 * $Revision: 1.27 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #ifndef _OUTDEV_HXX //autogen
36 #include <vcl/outdev.hxx>
37 #endif
38 #include <SwPortionHandler.hxx>
40 #include "errhdl.hxx" // ASSERT
42 #include "txtcfg.hxx"
43 #include "porlin.hxx"
44 #include "inftxt.hxx"
45 #include "portxt.hxx"
46 #include "pormulti.hxx"
47 #include "porglue.hxx"
48 #include "inftxt.hxx"
49 #include "blink.hxx"
50 #ifndef PRODUCT
52 sal_Bool ChkChain( SwLinePortion *pStart )
54 SwLinePortion *pPor = pStart->GetPortion();
55 MSHORT nCount = 0;
56 while( pPor )
58 ++nCount;
59 ASSERT( nCount < 200 && pPor != pStart,
60 "ChkChain(): lost in chains" );
61 if( nCount >= 200 || pPor == pStart )
63 // der Lebensretter
64 pPor = pStart->GetPortion();
65 pStart->SetPortion(0);
66 pPor->Truncate();
67 pStart->SetPortion( pPor );
68 return sal_False;
70 pPor = pPor->GetPortion();
72 return sal_True;
74 #endif
76 #if OSL_DEBUG_LEVEL > 1
77 const sal_Char *GetPortionName( const MSHORT nType );
78 #endif
80 SwLinePortion::~SwLinePortion()
82 if( pBlink )
83 pBlink->Delete( this );
86 SwLinePortion *SwLinePortion::Compress()
88 return GetLen() || Width() ? this : 0;
91 KSHORT SwLinePortion::GetViewWidth( const SwTxtSizeInfo & ) const
93 return 0;
96 /*************************************************************************
97 * SwLinePortion::SwLinePortion( )
98 *************************************************************************/
100 SwLinePortion::SwLinePortion( ) :
101 pPortion( NULL ),
102 nLineLength( 0 ),
103 nAscent( 0 )
107 /*************************************************************************
108 * SwLinePortion::PrePaint()
109 *************************************************************************/
111 void SwLinePortion::PrePaint( const SwTxtPaintInfo& rInf,
112 const SwLinePortion* pLast ) const
114 ASSERT( rInf.OnWin(), "SwLinePortion::PrePaint: don't prepaint on a printer");
115 ASSERT( !Width(), "SwLinePortion::PrePaint: For Width()==0 only!");
117 const KSHORT nViewWidth = GetViewWidth( rInf );
119 if( ! nViewWidth )
120 return;
122 const KSHORT nHalfView = nViewWidth / 2;
123 USHORT nLastWidth = pLast->Width();
125 if ( pLast->InSpaceGrp() && rInf.GetSpaceAdd() )
126 nLastWidth = nLastWidth + (USHORT)pLast->CalcSpacing( rInf.GetSpaceAdd(), rInf );
128 KSHORT nPos;
129 SwTxtPaintInfo aInf( rInf );
131 const BOOL bBidiPor = ( rInf.GetTxtFrm()->IsRightToLeft() ) !=
132 ( 0 != ( TEXT_LAYOUT_BIDI_RTL & rInf.GetOut()->GetLayoutMode() ) );
134 USHORT nDir = bBidiPor ?
135 1800 :
136 rInf.GetFont()->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
138 switch ( nDir )
140 case 0 :
141 nPos = KSHORT( rInf.X() );
142 if( nLastWidth > nHalfView )
143 nPos += nLastWidth - nHalfView;
144 aInf.X( nPos );
145 break;
146 case 900 :
147 nPos = KSHORT( rInf.Y() );
148 if( nLastWidth > nHalfView )
149 nPos -= nLastWidth + nHalfView;
150 aInf.Y( nPos );
151 break;
152 case 1800 :
153 nPos = KSHORT( rInf.X() );
154 if( nLastWidth > nHalfView )
155 nPos -= nLastWidth + nHalfView;
156 aInf.X( nPos );
157 break;
158 case 2700 :
159 nPos = KSHORT( rInf.Y() );
160 if( nLastWidth > nHalfView )
161 nPos += nLastWidth - nHalfView;
162 aInf.Y( nPos );
163 break;
166 SwLinePortion *pThis = (SwLinePortion*)this;
167 pThis->Width( nViewWidth );
168 Paint( aInf );
169 pThis->Width(0);
172 /*************************************************************************
173 * SwLinePortion::CalcTxtSize()
174 *************************************************************************/
176 void SwLinePortion::CalcTxtSize( const SwTxtSizeInfo &rInf )
178 if( GetLen() == rInf.GetLen() )
179 *((SwPosSize*)this) = GetTxtSize( rInf );
180 else
182 SwTxtSizeInfo aInf( rInf );
183 aInf.SetLen( GetLen() );
184 *((SwPosSize*)this) = GetTxtSize( aInf );
188 /*************************************************************************
189 * SwLinePortion::Truncate()
191 * Es werden alle nachfolgenden Portions geloescht.
192 *************************************************************************/
194 void SwLinePortion::_Truncate()
196 SwLinePortion *pPos = pPortion;
198 { ASSERT( pPos != this, "SwLinePortion::Truncate: loop" );
199 SwLinePortion *pLast = pPos;
200 pPos = pPos->GetPortion();
201 pLast->SetPortion( 0 );
202 delete pLast;
204 } while( pPos );
206 pPortion = 0;
209 /*************************************************************************
210 * virtual SwLinePortion::Insert()
212 * Es wird immer hinter uns eingefuegt.
213 *************************************************************************/
215 SwLinePortion *SwLinePortion::Insert( SwLinePortion *pIns )
217 pIns->FindLastPortion()->SetPortion( pPortion );
218 SetPortion( pIns );
219 #ifndef PRODUCT
220 ChkChain( this );
221 #endif
222 return pIns;
225 /*************************************************************************
226 * SwLinePortion::FindLastPortion()
227 *************************************************************************/
229 SwLinePortion *SwLinePortion::FindLastPortion()
231 SwLinePortion *pPos = this;
232 // An das Ende wandern und pLinPortion an den letzten haengen ...
233 while( pPos->GetPortion() )
235 DBG_LOOP;
236 pPos = pPos->GetPortion();
238 return pPos;
241 /*************************************************************************
242 * virtual SwLinePortion::Append()
243 *************************************************************************/
245 SwLinePortion *SwLinePortion::Append( SwLinePortion *pIns )
247 SwLinePortion *pPos = FindLastPortion();
248 pPos->SetPortion( pIns );
249 pIns->SetPortion( 0 );
250 #ifndef PRODUCT
251 ChkChain( this );
252 #endif
253 return pIns;
256 /*************************************************************************
257 * virtual SwLinePortion::Cut()
258 *************************************************************************/
260 SwLinePortion *SwLinePortion::Cut( SwLinePortion *pVictim )
262 SwLinePortion *pPrev = pVictim->FindPrevPortion( this );
263 ASSERT( pPrev, "SwLinePortion::Cut(): can't cut" );
264 pPrev->SetPortion( pVictim->GetPortion() );
265 pVictim->SetPortion(0);
266 return pVictim;
269 /*************************************************************************
270 * SwLinePortion::FindPrevPortion()
271 *************************************************************************/
273 SwLinePortion *SwLinePortion::FindPrevPortion( const SwLinePortion *pRoot )
275 ASSERT( pRoot != this, "SwLinePortion::FindPrevPortion(): invalid root" );
276 SwLinePortion *pPos = (SwLinePortion*)pRoot;
277 while( pPos->GetPortion() && pPos->GetPortion() != this )
279 DBG_LOOP;
280 pPos = pPos->GetPortion();
282 ASSERT( pPos->GetPortion(),
283 "SwLinePortion::FindPrevPortion: blowing in the wind");
284 return pPos;
287 /*************************************************************************
288 * virtual SwLinePortion::GetCrsrOfst()
289 *************************************************************************/
291 xub_StrLen SwLinePortion::GetCrsrOfst( const KSHORT nOfst ) const
293 if( nOfst > ( PrtWidth() / 2 ) )
294 return GetLen();
295 else
296 return 0;
299 /*************************************************************************
300 * virtual SwLinePortion::GetTxtSize()
301 *************************************************************************/
303 SwPosSize SwLinePortion::GetTxtSize( const SwTxtSizeInfo & ) const
305 ASSERT( !this, "SwLinePortion::GetTxtSize: don't ask me about sizes, "
306 "I'm only a stupid SwLinePortion" );
307 return SwPosSize();
310 #ifndef PRODUCT
312 /*************************************************************************
313 * virtual SwLinePortion::Check()
314 *************************************************************************/
316 sal_Bool SwLinePortion::Check( SvStream &, SwTxtSizeInfo & ) //$ ostream
318 return sal_True;
320 #endif
322 /*************************************************************************
323 * virtual SwLinePortion::Format()
324 *************************************************************************/
326 sal_Bool SwLinePortion::Format( SwTxtFormatInfo &rInf )
328 if( rInf.X() > rInf.Width() )
330 Truncate();
331 rInf.SetUnderFlow( this );
332 return sal_True;
335 const SwLinePortion *pLast = rInf.GetLast();
336 Height( pLast->Height() );
337 SetAscent( pLast->GetAscent() );
338 const KSHORT nNewWidth = static_cast<USHORT>(rInf.X() + PrtWidth());
339 // Nur Portions mit echter Breite koennen ein sal_True zurueckliefern
340 // Notizen beispielsweise setzen niemals bFull==sal_True
341 if( rInf.Width() <= nNewWidth && PrtWidth() && ! IsKernPortion() )
343 Truncate();
344 if( nNewWidth > rInf.Width() )
345 PrtWidth( nNewWidth - rInf.Width() );
346 rInf.GetLast()->FormatEOL( rInf );
347 return sal_True;
349 return sal_False;
352 /*************************************************************************
353 * virtual SwLinePortion::FormatEOL()
354 *************************************************************************/
356 // Format end of line
358 void SwLinePortion::FormatEOL( SwTxtFormatInfo & )
361 /*************************************************************************
362 * SwLinePortion::Move()
363 *************************************************************************/
365 void SwLinePortion::Move( SwTxtPaintInfo &rInf )
367 BOOL bB2T = rInf.GetDirection() == DIR_BOTTOM2TOP;
368 const BOOL bFrmDir = rInf.GetTxtFrm()->IsRightToLeft();
369 BOOL bCounterDir = ( ! bFrmDir && DIR_RIGHT2LEFT == rInf.GetDirection() ) ||
370 ( bFrmDir && DIR_LEFT2RIGHT == rInf.GetDirection() );
372 if ( InSpaceGrp() && rInf.GetSpaceAdd() )
374 SwTwips nTmp = PrtWidth() + CalcSpacing( rInf.GetSpaceAdd(), rInf );
375 if( rInf.IsRotated() )
376 rInf.Y( rInf.Y() + ( bB2T ? -nTmp : nTmp ) );
377 else if ( bCounterDir )
378 rInf.X( rInf.X() - nTmp );
379 else
380 rInf.X( rInf.X() + nTmp );
382 else
384 if( InFixMargGrp() && !IsMarginPortion() )
386 rInf.IncSpaceIdx();
387 rInf.IncKanaIdx();
389 if( rInf.IsRotated() )
390 rInf.Y( rInf.Y() + ( bB2T ? -PrtWidth() : PrtWidth() ) );
391 else if ( bCounterDir )
392 rInf.X( rInf.X() - PrtWidth() );
393 else
394 rInf.X( rInf.X() + PrtWidth() );
396 if( IsMultiPortion() && ((SwMultiPortion*)this)->HasTabulator() )
397 rInf.IncSpaceIdx();
399 rInf.SetIdx( rInf.GetIdx() + GetLen() );
402 /*************************************************************************
403 * virtual SwLinePortion::CalcSpacing()
404 *************************************************************************/
406 long SwLinePortion::CalcSpacing( long , const SwTxtSizeInfo & ) const
408 return 0;
411 /*************************************************************************
412 * virtual SwLinePortion::GetExpTxt()
413 *************************************************************************/
415 sal_Bool SwLinePortion::GetExpTxt( const SwTxtSizeInfo &, XubString & ) const
417 return sal_False;
420 /*************************************************************************
421 * virtual SwLinePortion::HandlePortion()
422 *************************************************************************/
424 void SwLinePortion::HandlePortion( SwPortionHandler& rPH ) const
426 String aString;
427 rPH.Special( GetLen(), aString, GetWhichPor() );