1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: porlin.cxx,v $
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>
38 #include <SwPortionHandler.hxx>
40 #include "errhdl.hxx" // ASSERT
46 #include "pormulti.hxx"
47 #include "porglue.hxx"
52 sal_Bool
ChkChain( SwLinePortion
*pStart
)
54 SwLinePortion
*pPor
= pStart
->GetPortion();
59 ASSERT( nCount
< 200 && pPor
!= pStart
,
60 "ChkChain(): lost in chains" );
61 if( nCount
>= 200 || pPor
== pStart
)
64 pPor
= pStart
->GetPortion();
65 pStart
->SetPortion(0);
67 pStart
->SetPortion( pPor
);
70 pPor
= pPor
->GetPortion();
76 #if OSL_DEBUG_LEVEL > 1
77 const sal_Char
*GetPortionName( const MSHORT nType
);
80 SwLinePortion::~SwLinePortion()
83 pBlink
->Delete( this );
86 SwLinePortion
*SwLinePortion::Compress()
88 return GetLen() || Width() ? this : 0;
91 KSHORT
SwLinePortion::GetViewWidth( const SwTxtSizeInfo
& ) const
96 /*************************************************************************
97 * SwLinePortion::SwLinePortion( )
98 *************************************************************************/
100 SwLinePortion::SwLinePortion( ) :
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
);
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
);
129 SwTxtPaintInfo
aInf( rInf
);
131 const BOOL bBidiPor
= ( rInf
.GetTxtFrm()->IsRightToLeft() ) !=
132 ( 0 != ( TEXT_LAYOUT_BIDI_RTL
& rInf
.GetOut()->GetLayoutMode() ) );
134 USHORT nDir
= bBidiPor
?
136 rInf
.GetFont()->GetOrientation( rInf
.GetTxtFrm()->IsVertical() );
141 nPos
= KSHORT( rInf
.X() );
142 if( nLastWidth
> nHalfView
)
143 nPos
+= nLastWidth
- nHalfView
;
147 nPos
= KSHORT( rInf
.Y() );
148 if( nLastWidth
> nHalfView
)
149 nPos
-= nLastWidth
+ nHalfView
;
153 nPos
= KSHORT( rInf
.X() );
154 if( nLastWidth
> nHalfView
)
155 nPos
-= nLastWidth
+ nHalfView
;
159 nPos
= KSHORT( rInf
.Y() );
160 if( nLastWidth
> nHalfView
)
161 nPos
+= nLastWidth
- nHalfView
;
166 SwLinePortion
*pThis
= (SwLinePortion
*)this;
167 pThis
->Width( nViewWidth
);
172 /*************************************************************************
173 * SwLinePortion::CalcTxtSize()
174 *************************************************************************/
176 void SwLinePortion::CalcTxtSize( const SwTxtSizeInfo
&rInf
)
178 if( GetLen() == rInf
.GetLen() )
179 *((SwPosSize
*)this) = GetTxtSize( rInf
);
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 );
209 /*************************************************************************
210 * virtual SwLinePortion::Insert()
212 * Es wird immer hinter uns eingefuegt.
213 *************************************************************************/
215 SwLinePortion
*SwLinePortion::Insert( SwLinePortion
*pIns
)
217 pIns
->FindLastPortion()->SetPortion( pPortion
);
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() )
236 pPos
= pPos
->GetPortion();
241 /*************************************************************************
242 * virtual SwLinePortion::Append()
243 *************************************************************************/
245 SwLinePortion
*SwLinePortion::Append( SwLinePortion
*pIns
)
247 SwLinePortion
*pPos
= FindLastPortion();
248 pPos
->SetPortion( pIns
);
249 pIns
->SetPortion( 0 );
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);
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 )
280 pPos
= pPos
->GetPortion();
282 ASSERT( pPos
->GetPortion(),
283 "SwLinePortion::FindPrevPortion: blowing in the wind");
287 /*************************************************************************
288 * virtual SwLinePortion::GetCrsrOfst()
289 *************************************************************************/
291 xub_StrLen
SwLinePortion::GetCrsrOfst( const KSHORT nOfst
) const
293 if( nOfst
> ( PrtWidth() / 2 ) )
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" );
312 /*************************************************************************
313 * virtual SwLinePortion::Check()
314 *************************************************************************/
316 sal_Bool
SwLinePortion::Check( SvStream
&, SwTxtSizeInfo
& ) //$ ostream
322 /*************************************************************************
323 * virtual SwLinePortion::Format()
324 *************************************************************************/
326 sal_Bool
SwLinePortion::Format( SwTxtFormatInfo
&rInf
)
328 if( rInf
.X() > rInf
.Width() )
331 rInf
.SetUnderFlow( this );
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() )
344 if( nNewWidth
> rInf
.Width() )
345 PrtWidth( nNewWidth
- rInf
.Width() );
346 rInf
.GetLast()->FormatEOL( rInf
);
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
);
380 rInf
.X( rInf
.X() + nTmp
);
384 if( InFixMargGrp() && !IsMarginPortion() )
389 if( rInf
.IsRotated() )
390 rInf
.Y( rInf
.Y() + ( bB2T
? -PrtWidth() : PrtWidth() ) );
391 else if ( bCounterDir
)
392 rInf
.X( rInf
.X() - PrtWidth() );
394 rInf
.X( rInf
.X() + PrtWidth() );
396 if( IsMultiPortion() && ((SwMultiPortion
*)this)->HasTabulator() )
399 rInf
.SetIdx( rInf
.GetIdx() + GetLen() );
402 /*************************************************************************
403 * virtual SwLinePortion::CalcSpacing()
404 *************************************************************************/
406 long SwLinePortion::CalcSpacing( long , const SwTxtSizeInfo
& ) const
411 /*************************************************************************
412 * virtual SwLinePortion::GetExpTxt()
413 *************************************************************************/
415 sal_Bool
SwLinePortion::GetExpTxt( const SwTxtSizeInfo
&, XubString
& ) const
420 /*************************************************************************
421 * virtual SwLinePortion::HandlePortion()
422 *************************************************************************/
424 void SwLinePortion::HandlePortion( SwPortionHandler
& rPH
) const
427 rPH
.Special( GetLen(), aString
, GetWhichPor() );