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: porfld.cxx,v $
10 * $Revision: 1.62.110.1 $
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 #include <hintids.hxx>
37 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
38 #include <com/sun/star/i18n/ScriptType.hdl>
41 #ifndef _GRAPH_HXX //autogen
42 #include <vcl/graph.hxx>
44 #include <svx/brshitem.hxx>
45 #ifndef _METRIC_HXX //autogen
46 #include <vcl/metric.hxx>
48 #ifndef _OUTDEV_HXX //autogen
49 #include <vcl/outdev.hxx>
51 #include <viewopt.hxx> // SwViewOptions
53 #include <SwPortionHandler.hxx>
57 #include <blink.hxx> // pBlink
58 #include <frmtool.hxx> // DrawGraphic
64 #include <breakit.hxx>
66 #include <porftn.hxx> // SwFtnPortion
67 #include <accessibilityoptions.hxx>
68 #include <svx/lrspitem.hxx>
70 #include <unicode/ubidi.h>
72 using namespace ::com::sun::star
;
74 /*************************************************************************
76 *************************************************************************/
78 SwLinePortion
*SwFldPortion::Compress()
79 { return (GetLen() || aExpand
.Len() || SwLinePortion::Compress()) ? this : 0; }
81 SwFldPortion
*SwFldPortion::Clone( const XubString
&rExpand
) const
84 if( 0 != ( pNewFnt
= pFnt
) )
85 pNewFnt
= new SwFont( *pFnt
);
86 SwFldPortion
* pClone
= new SwFldPortion( rExpand
, pNewFnt
);
87 pClone
->SetNextOffset( nNextOffset
);
88 pClone
->m_bNoLength
= this->m_bNoLength
;
92 void SwFldPortion::TakeNextOffset( const SwFldPortion
* pFld
)
94 ASSERT( pFld
, "TakeNextOffset: Missing Source" );
95 nNextOffset
= pFld
->GetNextOffset();
96 aExpand
.Erase( 0, nNextOffset
);
100 SwFldPortion::SwFldPortion( const XubString
&rExpand
, SwFont
*pFont
, sal_Bool bPlaceHold
)
101 : aExpand(rExpand
), pFnt(pFont
), nNextOffset(0), nNextScriptChg(STRING_LEN
), nViewWidth(0),
102 bFollow( sal_False
), bHasFollow( sal_False
), bPlaceHolder( bPlaceHold
)
103 , m_bNoLength( sal_False
)
105 SetWhichPor( POR_FLD
);
108 SwFldPortion::SwFldPortion( const SwFldPortion
& rFld
)
109 : SwExpandPortion( rFld
),
110 aExpand( rFld
.GetExp() ),
111 nNextOffset( rFld
.GetNextOffset() ),
112 nNextScriptChg( rFld
.GetNextScriptChg() ),
113 bFollow( rFld
.IsFollow() ),
114 bLeft( rFld
.IsLeft() ),
115 bHide( rFld
.IsHide() ),
116 bCenter( rFld
.IsCenter() ),
117 bHasFollow( rFld
.HasFollow() ),
118 bPlaceHolder( rFld
.bPlaceHolder
)
119 , m_bNoLength( rFld
.m_bNoLength
)
121 if ( rFld
.HasFont() )
122 pFnt
= new SwFont( *rFld
.GetFont() );
126 SetWhichPor( POR_FLD
);
129 SwFldPortion::~SwFldPortion()
133 pBlink
->Delete( this );
136 /*************************************************************************
137 * virtual SwFldPortion::GetViewWidth()
138 *************************************************************************/
140 KSHORT
SwFldPortion::GetViewWidth( const SwTxtSizeInfo
&rInf
) const
142 // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
143 // Moment errechnet werden:
144 SwFldPortion
* pThis
= (SwFldPortion
*)this;
145 if( !Width() && rInf
.OnWin() && !rInf
.GetOpt().IsPagePreview() &&
146 !rInf
.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings() )
149 pThis
->nViewWidth
= rInf
.GetTxtSize( ' ' ).Width();
152 pThis
->nViewWidth
= 0;
156 /*************************************************************************
157 * virtual SwFldPortion::Format()
158 *************************************************************************/
160 // 8653: in keinem Fall nur SetLen(0);
162 /*************************************************************************
163 * Hilfsklasse SwFldSlot
164 **************************************************************************/
168 const XubString
*pOldTxt
;
173 SwTxtFormatInfo
*pInf
;
175 SwFldSlot( const SwTxtFormatInfo
* pNew
, const SwFldPortion
*pPor
);
179 SwFldSlot::SwFldSlot( const SwTxtFormatInfo
* pNew
, const SwFldPortion
*pPor
)
181 bOn
= pPor
->GetExpTxt( *pNew
, aTxt
);
183 // Der Text wird ausgetauscht...
186 pInf
= (SwTxtFormatInfo
*)pNew
;
187 nIdx
= pInf
->GetIdx();
188 nLen
= pInf
->GetLen();
189 pOldTxt
= &(pInf
->GetTxt());
190 pInf
->SetLen( aTxt
.Len() );
191 if( pPor
->IsFollow() )
193 pInf
->SetFakeLineStart( nIdx
> pInf
->GetLineStart() );
198 XubString
aTmp( aTxt
);
200 aTxt
.Erase( nIdx
, 1 );
201 aTxt
.Insert( aTmp
, nIdx
);
203 pInf
->SetTxt( aTxt
);
207 SwFldSlot::~SwFldSlot()
211 pInf
->SetTxt( *pOldTxt
);
212 pInf
->SetIdx( nIdx
);
213 pInf
->SetLen( nLen
);
214 pInf
->SetFakeLineStart( sal_False
);
218 void SwFldPortion::CheckScript( const SwTxtSizeInfo
&rInf
)
221 if( GetExpTxt( rInf
, aTxt
) && aTxt
.Len() && pBreakIt
->GetBreakIter().is() )
223 BYTE nActual
= pFnt
? pFnt
->GetActual() : rInf
.GetFont()->GetActual();
226 nScript
= pBreakIt
->GetBreakIter()->getScriptType( aTxt
, 0 );
228 if( i18n::ScriptType::WEAK
== nScript
)
230 nChg
=(xub_StrLen
)pBreakIt
->GetBreakIter()->endOfScript(aTxt
,0,nScript
);
231 if( nChg
< aTxt
.Len() )
232 nScript
= pBreakIt
->GetBreakIter()->getScriptType( aTxt
, nChg
);
236 // nNextScriptChg will be evaluated during SwFldPortion::Format()
238 if ( nChg
< aTxt
.Len() )
239 nNextScriptChg
= (xub_StrLen
)pBreakIt
->GetBreakIter()->endOfScript( aTxt
, nChg
, nScript
);
241 nNextScriptChg
= aTxt
.Len();
246 case i18n::ScriptType::LATIN
: nTmp
= SW_LATIN
; break;
247 case i18n::ScriptType::ASIAN
: nTmp
= SW_CJK
; break;
248 case i18n::ScriptType::COMPLEX
: nTmp
= SW_CTL
; break;
249 default: nTmp
= nActual
;
252 // #i16354# Change script type for RTL text to CTL.
253 const SwScriptInfo
& rSI
= rInf
.GetParaPortion()->GetScriptInfo();
254 // --> OD 2009-01-29 #i98418#
255 // const BYTE nFldDir = IsNumberPortion() ?
256 const BYTE nFldDir
= ( IsNumberPortion() || IsFtnNumPortion() ) ?
257 rSI
.GetDefaultDir() :
258 rSI
.DirType( IsFollow() ? rInf
.GetIdx() - 1 : rInf
.GetIdx() );
260 if ( UBIDI_RTL
== nFldDir
)
262 UErrorCode nError
= U_ZERO_ERROR
;
263 UBiDi
* pBidi
= ubidi_openSized( aTxt
.Len(), 0, &nError
);
264 ubidi_setPara( pBidi
, reinterpret_cast<const UChar
*>(aTxt
.GetBuffer()), aTxt
.Len(), nFldDir
, NULL
, &nError
);
267 ubidi_getLogicalRun( pBidi
, 0, &nEnd
, &nCurrDir
);
268 ubidi_close( pBidi
);
269 const xub_StrLen nNextDirChg
= (xub_StrLen
)nEnd
;
270 nNextScriptChg
= Min( nNextScriptChg
, nNextDirChg
);
272 // #i89825# change the script type also to CTL
273 // if there is no strong LTR char in the LTR run (numbers)
274 if ( nCurrDir
!= UBIDI_RTL
)
276 nCurrDir
= UBIDI_RTL
;
277 for ( xub_StrLen nCharIdx
= 0; nCharIdx
< nEnd
; ++nCharIdx
)
279 UCharDirection nCharDir
= u_charDirection ( aTxt
.GetChar ( nCharIdx
));
280 if ( nCharDir
== U_LEFT_TO_RIGHT
||
281 nCharDir
== U_LEFT_TO_RIGHT_EMBEDDING
||
282 nCharDir
== U_LEFT_TO_RIGHT_OVERRIDE
)
284 nCurrDir
= UBIDI_LTR
;
290 if ( nCurrDir
== UBIDI_RTL
)
294 // --> OD 2009-01-29 #i98418#
295 // keep determined script type for footnote portions as preferred script type.
296 // For footnote portions a font can not be created directly - see footnote
297 // portion format method.
298 // if( !IsFtnPortion() && nTmp != nActual )
299 if ( IsFtnPortion() )
301 dynamic_cast<SwFtnPortion
*>(this)->SetPreferredScriptType( nTmp
);
303 else if ( nTmp
!= nActual
)
306 pFnt
= new SwFont( *rInf
.GetFont() );
307 pFnt
->SetActual( nTmp
);
313 sal_Bool
SwFldPortion::Format( SwTxtFormatInfo
&rInf
)
315 // Scope wegen aDiffTxt::DTOR!
318 sal_Bool bEOL
= sal_False
;
319 long nTxtRest
= rInf
.GetTxt().Len() - rInf
.GetIdx();
321 SwFldSlot
aDiffTxt( &rInf
, this );
322 SwLayoutModeModifier
aLayoutModeModifier( *rInf
.GetOut() );
323 aLayoutModeModifier
.SetAuto();
325 // Field portion has to be split in several parts if
326 // 1. There are script/direction changes inside the field
327 // 2. There are portion breaks (tab, break) inside the field:
328 const xub_StrLen nOldFullLen
= rInf
.GetLen();
329 xub_StrLen nFullLen
= rInf
.ScanPortionEnd( rInf
.GetIdx(), rInf
.GetIdx() + nOldFullLen
) - rInf
.GetIdx();
330 if ( nNextScriptChg
< nFullLen
)
332 nFullLen
= nNextScriptChg
;
333 rInf
.SetHookChar( 0 );
335 rInf
.SetLen( nFullLen
);
337 if ( STRING_LEN
!= rInf
.GetUnderScorePos() &&
338 rInf
.GetUnderScorePos() > rInf
.GetIdx() )
339 rInf
.SetUnderScorePos( rInf
.GetIdx() );
342 pFnt
->GoMagic( rInf
.GetVsh(), pFnt
->GetActual() );
344 SwFontSave
aSave( rInf
, pFnt
);
346 // 8674: Laenge muss 0 sein, bei bFull nach Format ist die Laenge
347 // gesetzt und wird in nRest uebertragen. Ansonsten bleibt die
348 // Laenge erhalten und wuerde auch in nRest einfliessen!
350 const MSHORT nFollow
= IsFollow() ? 0 : 1;
352 // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
353 // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
354 // sal_False returnen wegen SetFull ...
357 // nicht Init(), weil wir Hoehe und Ascent brauchen
359 bFull
= rInf
.Width() <= rInf
.GetPos().X();
363 xub_StrLen nOldLineStart
= rInf
.GetLineStart();
365 rInf
.SetLineStart( 0 );
366 rInf
.SetNotEOL( nFullLen
== nOldFullLen
&& nTxtRest
> nFollow
);
368 // the height depending on the fields font is set,
369 // this is required for SwTxtGuess::Guess
370 Height( rInf
.GetTxtHeight() );
371 // If a kerning portion is inserted after our field portion,
372 // the ascent and height must be known
373 SetAscent( rInf
.GetAscent() );
374 bFull
= SwTxtPortion::Format( rInf
);
375 rInf
.SetNotEOL( sal_False
);
376 rInf
.SetLineStart( nOldLineStart
);
378 xub_StrLen nTmpLen
= GetLen();
379 bEOL
= !nTmpLen
&& nFollow
&& bFull
;
380 nRest
= nOldFullLen
- nTmpLen
;
382 // Das Zeichen wird in der ersten Portion gehalten.
383 // Unbedingt nach Format!
384 SetLen( (m_bNoLength
) ? 0 : nFollow
);
388 // aExpand ist noch nicht gekuerzt worden, der neue Ofst
389 // ergibt sich durch nRest.
390 xub_StrLen nNextOfst
= aExpand
.Len() - nRest
;
392 if ( IsQuoVadisPortion() )
393 nNextOfst
= nNextOfst
+ ((SwQuoVadisPortion
*)this)->GetContTxt().Len();
395 XubString
aNew( aExpand
, nNextOfst
, STRING_LEN
);
396 aExpand
.Erase( nNextOfst
, STRING_LEN
);
398 // These characters should not be contained in the follow
399 // field portion. They are handled via the HookChar mechanism.
400 switch( aNew
.GetChar( 0 ))
402 case CH_BREAK
: bFull
= sal_True
;
406 case CHAR_HARDHYPHEN
: // non-breaking hyphen
407 case CHAR_SOFTHYPHEN
:
409 // --> FME 2006-01-11 #i59759# Erase additional control
410 // characters from field string, otherwise we get stuck in
425 // Even if there is no more text left for a follow field,
426 // we have to build a follow field portion (without font),
427 // otherwise the HookChar mechanism would not work.
428 SwFldPortion
*pFld
= Clone( aNew
);
429 if( aNew
.Len() && !pFld
->GetFont() )
431 SwFont
*pNewFnt
= new SwFont( *rInf
.GetFont() );
432 pFld
->SetFont( pNewFnt
);
434 pFld
->SetFollow( sal_True
);
435 SetHasFollow( sal_True
);
436 // In nNextOffset steht bei einem neuangelegten Feld zunaechst
437 // der Offset, an dem es selbst im Originalstring beginnt.
438 // Wenn beim Formatieren ein FollowFeld angelegt wird, wird
439 // der Offset dieses FollowFelds in nNextOffset festgehalten.
440 nNextOffset
= nNextOffset
+ nNextOfst
;
441 pFld
->SetNextOffset( nNextOffset
);
442 rInf
.SetRest( pFld
);
446 if( bEOL
&& rInf
.GetLast() && !rInf
.GetUnderFlow() )
447 rInf
.GetLast()->FormatEOL( rInf
);
451 /*************************************************************************
452 * virtual SwFldPortion::Paint()
453 *************************************************************************/
455 void SwFldPortion::Paint( const SwTxtPaintInfo
&rInf
) const
457 SwFontSave
aSave( rInf
, pFnt
);
459 ASSERT( GetLen() <= 1, "SwFldPortion::Paint: rest-portion polution?" );
460 if( Width() && ( !bPlaceHolder
|| rInf
.GetOpt().IsShowPlaceHolderFields() ) )
462 // Dies ist eine freizuegige Auslegung der Hintergrundbelegung ...
463 rInf
.DrawViewOpt( *this, POR_FLD
);
464 SwExpandPortion::Paint( rInf
);
468 /*************************************************************************
469 * virtual SwFldPortion::GetExpTxt()
470 *************************************************************************/
472 sal_Bool
SwFldPortion::GetExpTxt( const SwTxtSizeInfo
&rInf
, XubString
&rTxt
) const
475 if( !rTxt
.Len() && rInf
.OnWin() &&
476 !rInf
.GetOpt().IsPagePreview() && !rInf
.GetOpt().IsReadonly() &&
477 SwViewOption::IsFieldShadings() &&
483 /*************************************************************************
484 * virtual SwFldPortion::HandlePortion()
485 *************************************************************************/
487 void SwFldPortion::HandlePortion( SwPortionHandler
& rPH
) const
489 rPH
.Special( GetLen(), aExpand
, GetWhichPor() );
492 /*************************************************************************
493 * virtual SwFldPortion::GetTxtSize()
494 *************************************************************************/
496 SwPosSize
SwFldPortion::GetTxtSize( const SwTxtSizeInfo
&rInf
) const
498 SwFontSave
aSave( rInf
, pFnt
);
499 SwPosSize
aSize( SwExpandPortion::GetTxtSize( rInf
) );
503 /*************************************************************************
504 * class SwHiddenPortion
505 *************************************************************************/
507 SwFldPortion
*SwHiddenPortion::Clone(const XubString
&rExpand
) const
510 if( 0 != ( pNewFnt
= pFnt
) )
511 pNewFnt
= new SwFont( *pFnt
);
512 return new SwHiddenPortion( rExpand
, pNewFnt
);
515 /*************************************************************************
516 * virtual SwHiddenPortion::Paint()
517 *************************************************************************/
519 void SwHiddenPortion::Paint( const SwTxtPaintInfo
&rInf
) const
523 SwFontSave
aSave( rInf
, pFnt
);
524 rInf
.DrawViewOpt( *this, POR_HIDDEN
);
525 SwExpandPortion::Paint( rInf
);
529 /*************************************************************************
530 * virtual SwHiddenPortion::GetExpTxt()
531 *************************************************************************/
533 sal_Bool
SwHiddenPortion::GetExpTxt( const SwTxtSizeInfo
&rInf
, XubString
&rTxt
) const
535 // Nicht auf IsHidden() abfragen !
536 return SwFldPortion::GetExpTxt( rInf
, rTxt
);
539 /*************************************************************************
540 * class SwNumberPortion
541 *************************************************************************/
543 // --> OD 2008-01-23 #newlistlevelattrs#
544 SwNumberPortion::SwNumberPortion( const XubString
&rExpand
,
547 const sal_Bool bCntr
,
548 const KSHORT nMinDst
,
549 const bool bLabelAlignmentPosAndSpaceModeActive
)
550 : SwFldPortion( rExpand
, pFont
),
553 // --> OD 2008-01-23 #newlistlevelattrs#
554 mbLabelAlignmentPosAndSpaceModeActive( bLabelAlignmentPosAndSpaceModeActive
)
557 SetWhichPor( POR_NUMBER
);
559 SetHide( sal_False
);
563 xub_StrLen
SwNumberPortion::GetCrsrOfst( const MSHORT
) const
568 SwFldPortion
*SwNumberPortion::Clone( const XubString
&rExpand
) const
571 if( 0 != ( pNewFnt
= pFnt
) )
572 pNewFnt
= new SwFont( *pFnt
);
573 // --> OD 2008-01-23 #newlistlevelattrs#
574 return new SwNumberPortion( rExpand
, pNewFnt
, IsLeft(), IsCenter(),
575 nMinDist
, mbLabelAlignmentPosAndSpaceModeActive
);
579 /*************************************************************************
580 * virtual SwNumberPortion::Format()
581 *************************************************************************/
583 // 5010: Wir sind in der Lage, mehrzeilige NumFelder anzulegen!
584 // 3689: Fies ist, wenn man in der Dialogbox soviel Davor-Text
585 // eingibt, bis die Zeile ueberlaeuft.
586 // Man muss die Fly-Ausweichmanoever beachten!
588 sal_Bool
SwNumberPortion::Format( SwTxtFormatInfo
&rInf
)
590 SetHide( sal_False
);
591 const sal_Bool bFull
= SwFldPortion::Format( rInf
);
593 // a numbering portion can be contained in a rotated portion!!!
594 nFixWidth
= rInf
.IsMulti() ? Height() : Width();
595 rInf
.SetNumDone( !rInf
.GetRest() );
596 if( rInf
.IsNumDone() )
598 // SetAscent( rInf.GetAscent() );
599 ASSERT( Height() && nAscent
, "NumberPortions without Height | Ascent" );
602 // --> OD 2008-01-23 #newlistlevelattrs#
603 if ( !mbLabelAlignmentPosAndSpaceModeActive
)
605 if ( !rInf
.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING
) &&
606 // --> FME 2004-08-13 #i32902#
611 + rInf
.GetTxtFrm()->GetTxtNode()->
612 GetSwAttrSet().GetLRSpace().GetTxtFirstLineOfst()
614 + rInf
.ForcedLeftMargin();
618 nDiff
= rInf
.Left() - rInf
.First() + rInf
.ForcedLeftMargin();
622 // Ein Vorschlag von Juergen und Volkmar:
623 // Der Textteil hinter der Numerierung sollte immer
624 // mindestens beim linken Rand beginnen.
627 else if ( nDiff
> rInf
.X() )
632 if( nDiff
< nFixWidth
+ nMinDist
)
633 nDiff
= nFixWidth
+ nMinDist
;
634 // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
635 // fieser Sonderfall: FlyFrm liegt in dem Bereich,
636 // den wir uns gerade unter den Nagel reissen wollen.
637 // Die NumberPortion wird als verborgen markiert.
638 const sal_Bool bFly
= rInf
.GetFly() ||
639 ( rInf
.GetLast() && rInf
.GetLast()->IsFlyPortion() );
640 if( nDiff
> rInf
.Width() )
642 nDiff
= rInf
.Width();
647 // A numbering portion can be inside a SwRotatedPortion. Then the
648 // Height has to be changed
649 if ( rInf
.IsMulti() )
651 if ( Height() < nDiff
)
652 Height( KSHORT( nDiff
) );
654 else if( Width() < nDiff
)
655 Width( KSHORT(nDiff
) );
660 void SwNumberPortion::FormatEOL( SwTxtFormatInfo
& )
662 /* Ein FormatEOL deutet daraufhin, dass der folgende Text
663 * nicht mit auf die Zeile passte. Damit die Numerierung mitwandert,
664 * wird diese NumberPortion verborgen.
667 // This caused trouble with flys anchored as characters.
668 // If one of these is numbered but does not fit to the line,
669 // it calls this function, causing a loop because both the number
670 // portion and the fly portion go to the next line
671 // SetHide( sal_True );
674 /*************************************************************************
675 * virtual SwNumberPortion::Paint()
676 *************************************************************************/
678 void SwNumberPortion::Paint( const SwTxtPaintInfo
&rInf
) const
680 /* Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
681 * Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
684 if ( IsHide() && rInf
.GetParaPortion() && rInf
.GetParaPortion()->GetNext() )
686 SwLinePortion
*pTmp
= GetPortion();
687 while ( pTmp
&& !pTmp
->InTxtGrp() )
688 pTmp
= pTmp
->GetPortion();
693 // calculate the width of the number portion, including follows
694 const KSHORT nOldWidth
= Width();
695 USHORT nSumWidth
= 0;
698 const SwLinePortion
* pTmp
= this;
699 while ( pTmp
&& pTmp
->InNumberGrp() )
701 nSumWidth
= nSumWidth
+ pTmp
->Width();
702 if ( ((SwNumberPortion
*)pTmp
)->HasFollow() )
703 pTmp
= pTmp
->GetPortion();
706 nOffset
= pTmp
->Width() - ((SwNumberPortion
*)pTmp
)->nFixWidth
;
711 // The master portion takes care for painting the background of the
712 // follow field portions
715 SwLinePortion
*pThis
= (SwLinePortion
*)this;
716 pThis
->Width( nSumWidth
);
717 rInf
.DrawViewOpt( *this, POR_NUMBER
);
718 pThis
->Width( nOldWidth
);
723 const SwFont
*pTmpFnt
= rInf
.GetFont();
724 sal_Bool bPaintSpace
= ( UNDERLINE_NONE
!= pTmpFnt
->GetUnderline() ||
725 UNDERLINE_NONE
!= pTmpFnt
->GetOverline() ||
726 STRIKEOUT_NONE
!= pTmpFnt
->GetStrikeout() ) &&
727 !pTmpFnt
->IsWordLineMode();
728 if( bPaintSpace
&& pFnt
)
729 bPaintSpace
= ( UNDERLINE_NONE
!= pFnt
->GetUnderline() ||
730 UNDERLINE_NONE
!= pFnt
->GetOverline() ||
731 STRIKEOUT_NONE
!= pFnt
->GetStrikeout() ) &&
732 !pFnt
->IsWordLineMode();
734 SwFontSave
aSave( rInf
, pFnt
);
736 if( nFixWidth
== Width() && ! HasFollow() )
737 SwExpandPortion::Paint( rInf
);
740 // logisches const: Width wird wieder zurueckgesetzt
741 SwLinePortion
*pThis
= (SwLinePortion
*)this;
742 bPaintSpace
= bPaintSpace
&& nFixWidth
< nOldWidth
;
743 KSHORT nSpaceOffs
= nFixWidth
;
744 pThis
->Width( nFixWidth
);
746 if( ( IsLeft() && ! rInf
.GetTxtFrm()->IsRightToLeft() ) ||
747 ( ! IsLeft() && ! IsCenter() && rInf
.GetTxtFrm()->IsRightToLeft() ) )
748 SwExpandPortion::Paint( rInf
);
751 SwTxtPaintInfo
aInf( rInf
);
752 if( nOffset
< nMinDist
)
758 /* #110778# a / 2 * 2 == a is not a tautology */
759 KSHORT nTmpOffset
= nOffset
;
761 if( nOffset
< nMinDist
)
762 nOffset
= nTmpOffset
- nMinDist
;
765 nOffset
= nOffset
- nMinDist
;
767 aInf
.X( aInf
.X() + nOffset
);
768 SwExpandPortion::Paint( aInf
);
770 nSpaceOffs
= nSpaceOffs
+ nOffset
;
772 if( bPaintSpace
&& nOldWidth
> nSpaceOffs
)
774 SwTxtPaintInfo
aInf( rInf
);
775 static sal_Char __READONLY_DATA sDoubleSpace
[] = " ";
776 aInf
.X( aInf
.X() + nSpaceOffs
);
778 // --> FME 2005-08-12 #i53199# Adjust position of underline:
779 if ( rInf
.GetUnderFnt() )
781 const Point
aNewPos( aInf
.GetPos().X(), rInf
.GetUnderFnt()->GetPos().Y() );
782 rInf
.GetUnderFnt()->SetPos( aNewPos
);
786 pThis
->Width( nOldWidth
- nSpaceOffs
+ 12 );
788 SwTxtSlot
aDiffTxt( &aInf
, this, true, false, sDoubleSpace
);
789 aInf
.DrawText( *this, aInf
.GetLen(), sal_True
);
792 pThis
->Width( nOldWidth
);
798 /*************************************************************************
799 * class SwBulletPortion
800 *************************************************************************/
802 // --> OD 2008-01-23 #newlistlevelattrs#
803 SwBulletPortion::SwBulletPortion( const xub_Unicode cBullet
,
804 const XubString
& rBulletFollowedBy
,
807 const sal_Bool bCntr
,
808 const KSHORT nMinDst
,
809 const bool bLabelAlignmentPosAndSpaceModeActive
)
810 : SwNumberPortion( XubString( rBulletFollowedBy
).Insert( cBullet
, 0 ) ,
811 pFont
, bLft
, bCntr
, nMinDst
,
812 bLabelAlignmentPosAndSpaceModeActive
)
815 SetWhichPor( POR_BULLET
);
818 /*************************************************************************
819 * class SwGrfNumPortion
820 *************************************************************************/
822 #define GRFNUM_SECURE 10
824 // --> OD 2008-01-23 #newlistlevelattrs#
825 SwGrfNumPortion::SwGrfNumPortion(
827 const XubString
& rGraphicFollowedBy
,
828 const SvxBrushItem
* pGrfBrush
,
829 const SwFmtVertOrient
* pGrfOrient
, const Size
& rGrfSize
,
830 const sal_Bool bLft
, const sal_Bool bCntr
, const KSHORT nMinDst
,
831 const bool bLabelAlignmentPosAndSpaceModeActive
) :
832 SwNumberPortion( rGraphicFollowedBy
, NULL
, bLft
, bCntr
, nMinDst
,
833 bLabelAlignmentPosAndSpaceModeActive
),
835 pBrush( new SvxBrushItem(RES_BACKGROUND
) ), nId( 0 )
837 SetWhichPor( POR_GRFNUM
);
838 SetAnimated( sal_False
);
839 bReplace
= sal_False
;
842 *pBrush
= *pGrfBrush
;
843 SwDocShell
*pSh
= pFrm
->GetShell()->GetDoc()->GetDocShell();
844 const Graphic
* pGraph
= pGrfBrush
->GetGraphic( pSh
);
846 SetAnimated( pGraph
->IsAnimated() );
852 nYPos
= pGrfOrient
->GetPos();
853 eOrient
= pGrfOrient
->GetVertOrient();
858 eOrient
= text::VertOrientation::TOP
;
860 Width( static_cast<USHORT
>(rGrfSize
.Width() + 2 * GRFNUM_SECURE
) );
862 nGrfHeight
= rGrfSize
.Height() + 2 * GRFNUM_SECURE
;
863 Height( KSHORT(nGrfHeight
) );
864 bNoPaint
= sal_False
;
867 SwGrfNumPortion::~SwGrfNumPortion()
870 ( (Graphic
*) pBrush
->GetGraphic() )->StopAnimation( 0, nId
);
874 void SwGrfNumPortion::StopAnimation( OutputDevice
* pOut
)
877 ( (Graphic
*) pBrush
->GetGraphic() )->StopAnimation( pOut
, nId
);
880 sal_Bool
SwGrfNumPortion::Format( SwTxtFormatInfo
&rInf
)
882 SetHide( sal_False
);
883 // --> OD 2008-01-29 #newlistlevelattrs#
884 // Width( nFixWidth );
885 KSHORT
nFollowedByWidth( 0 );
886 if ( mbLabelAlignmentPosAndSpaceModeActive
)
888 SwFldPortion::Format( rInf
);
889 nFollowedByWidth
= Width();
892 Width( nFixWidth
+ nFollowedByWidth
);
894 const sal_Bool bFull
= rInf
.Width() < rInf
.X() + Width();
895 const sal_Bool bFly
= rInf
.GetFly() ||
896 ( rInf
.GetLast() && rInf
.GetLast()->IsFlyPortion() );
897 SetAscent( static_cast<USHORT
>(GetRelPos() > 0 ? GetRelPos() : 0) );
898 if( GetAscent() > Height() )
899 Height( GetAscent() );
903 Width( rInf
.Width() - (KSHORT
)rInf
.X() );
907 SetNoPaint( sal_True
);
908 rInf
.SetNumDone( sal_False
);
912 rInf
.SetNumDone( sal_True
);
913 // --> OD 2008-01-23 #newlistlevelattrs#
914 // long nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
915 long nDiff
= mbLabelAlignmentPosAndSpaceModeActive
917 : rInf
.Left() - rInf
.First() + rInf
.ForcedLeftMargin();
919 // Ein Vorschlag von Juergen und Volkmar:
920 // Der Textteil hinter der Numerierung sollte immer
921 // mindestens beim linken Rand beginnen.
924 else if ( nDiff
> rInf
.X() )
926 if( nDiff
< nFixWidth
+ nMinDist
)
927 nDiff
= nFixWidth
+ nMinDist
;
928 // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
929 // fieser Sonderfall: FlyFrm liegt in dem Bereich,
930 // den wir uns gerade unter den Nagel reissen wollen.
931 // Die NumberPortion wird als verborgen markiert.
932 if( nDiff
> rInf
.Width() )
934 nDiff
= rInf
.Width();
939 if( Width() < nDiff
)
940 Width( KSHORT(nDiff
) );
944 void SwGrfNumPortion::Paint( const SwTxtPaintInfo
&rInf
) const
948 /* Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
949 * Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
951 if ( IsHide() && rInf
.GetParaPortion() && rInf
.GetParaPortion()->GetNext() )
953 SwLinePortion
*pTmp
= GetPortion();
954 while ( pTmp
&& !pTmp
->InTxtGrp() )
955 pTmp
= pTmp
->GetPortion();
959 Point
aPos( rInf
.X() + GRFNUM_SECURE
, rInf
.Y() - GetRelPos() + GRFNUM_SECURE
);
960 long nTmpWidth
= Max( (long)0, (long)(nFixWidth
- 2 * GRFNUM_SECURE
) );
961 Size
aSize( nTmpWidth
, GetGrfHeight() - 2 * GRFNUM_SECURE
);
963 // --> OD 2008-02-05 #newlistlevelattrs#
964 const sal_Bool bTmpLeft
= mbLabelAlignmentPosAndSpaceModeActive
||
965 ( IsLeft() && ! rInf
.GetTxtFrm()->IsRightToLeft() ) ||
966 ( ! IsLeft() && ! IsCenter() && rInf
.GetTxtFrm()->IsRightToLeft() );
969 if( nFixWidth
< Width() && !bTmpLeft
)
971 KSHORT nOffset
= Width() - nFixWidth
;
972 if( nOffset
< nMinDist
)
979 if( nOffset
< nMinDist
)
980 nOffset
= Width() - nFixWidth
- nMinDist
;
983 nOffset
= nOffset
- nMinDist
;
990 KSHORT nTmpH
= GetPortion() ? GetPortion()->GetAscent() : 120;
991 aSize
= Size( nTmpH
, nTmpH
);
992 aPos
.Y() = rInf
.Y() - nTmpH
;
994 SwRect
aTmp( aPos
, aSize
);
996 sal_Bool bDraw
= sal_True
;
1000 bDraw
= !rInf
.GetOpt().IsGraphic();
1003 SetId( long( rInf
.GetTxtFrm() ) );
1004 rInf
.GetTxtFrm()->SetAnimation();
1006 if( aTmp
.IsOver( rInf
.GetPaintRect() ) && !bDraw
)
1008 rInf
.NoteAnimation();
1009 const ViewShell
* pViewShell
= rInf
.GetVsh();
1011 // virtual device, not pdf export
1012 if( OUTDEV_VIRDEV
== rInf
.GetOut()->GetOutDevType() &&
1013 pViewShell
&& pViewShell
->GetWin() )
1015 ( (Graphic
*) pBrush
->GetGraphic() )->StopAnimation(0,nId
);
1016 rInf
.GetTxtFrm()->GetShell()->InvalidateWindows( aTmp
);
1020 else if ( pViewShell
&&
1021 !pViewShell
->GetAccessibilityOptions()->IsStopAnimatedGraphics() &&
1022 !pViewShell
->IsPreView() &&
1023 // --> FME 2004-06-21 #i9684# Stop animation during printing/pdf export.
1024 pViewShell
->GetWin() )
1027 ( (Graphic
*) pBrush
->GetGraphic() )->StartAnimation(
1028 (OutputDevice
*)rInf
.GetOut(), aPos
, aSize
, nId
);
1031 // pdf export, printing, preview, stop animations...
1036 ( (Graphic
*) pBrush
->GetGraphic() )->StopAnimation( 0, nId
);
1039 SwRect
aRepaint( rInf
.GetPaintRect() );
1040 const SwTxtFrm
& rFrm
= *rInf
.GetTxtFrm();
1041 if( rFrm
.IsVertical() )
1043 rFrm
.SwitchHorizontalToVertical( aTmp
);
1044 rFrm
.SwitchHorizontalToVertical( aRepaint
);
1047 if( rFrm
.IsRightToLeft() )
1049 rFrm
.SwitchLTRtoRTL( aTmp
);
1050 rFrm
.SwitchLTRtoRTL( aRepaint
);
1053 if( bDraw
&& aTmp
.HasArea() )
1054 DrawGraphic( pBrush
, (OutputDevice
*)rInf
.GetOut(),
1055 aTmp
, aRepaint
, bReplace
? GRFNUM_REPLACE
: GRFNUM_YES
);
1058 void SwGrfNumPortion::SetBase( long nLnAscent
, long nLnDescent
,
1059 long nFlyAsc
, long nFlyDesc
)
1061 if ( GetOrient() != text::VertOrientation::NONE
)
1064 if ( GetOrient() == text::VertOrientation::CENTER
)
1065 SetRelPos( GetGrfHeight() / 2 );
1066 else if ( GetOrient() == text::VertOrientation::TOP
)
1067 SetRelPos( GetGrfHeight() - GRFNUM_SECURE
);
1068 else if ( GetOrient() == text::VertOrientation::BOTTOM
)
1070 else if ( GetOrient() == text::VertOrientation::CHAR_CENTER
)
1071 SetRelPos( ( GetGrfHeight() + nLnAscent
- nLnDescent
) / 2 );
1072 else if ( GetOrient() == text::VertOrientation::CHAR_TOP
)
1073 SetRelPos( nLnAscent
);
1074 else if ( GetOrient() == text::VertOrientation::CHAR_BOTTOM
)
1075 SetRelPos( GetGrfHeight() - nLnDescent
);
1078 if( GetGrfHeight() >= nFlyAsc
+ nFlyDesc
)
1080 // wenn ich genauso gross bin wie die Zeile, brauche ich mich
1081 // nicht an der Zeile nicht weiter ausrichten, ich lasse
1082 // dann auch den max. Ascent der Zeile unveraendert
1084 SetRelPos( nFlyAsc
);
1086 else if ( GetOrient() == text::VertOrientation::LINE_CENTER
)
1087 SetRelPos( ( GetGrfHeight() + nFlyAsc
- nFlyDesc
) / 2 );
1088 else if ( GetOrient() == text::VertOrientation::LINE_TOP
)
1089 SetRelPos( nFlyAsc
);
1090 else if ( GetOrient() == text::VertOrientation::LINE_BOTTOM
)
1091 SetRelPos( GetGrfHeight() - nFlyDesc
);
1096 void SwTxtFrm::StopAnimation( OutputDevice
* pOut
)
1098 ASSERT( HasAnimation(), "SwTxtFrm::StopAnimation: Which Animation?" );
1101 SwLineLayout
*pLine
= GetPara();
1104 SwLinePortion
*pPor
= pLine
->GetPortion();
1107 if( pPor
->IsGrfNumPortion() )
1108 ((SwGrfNumPortion
*)pPor
)->StopAnimation( pOut
);
1109 // Die Numerierungsportion sitzt immer vor dem ersten Zeichen,
1110 // deshalb koennen wir abbrechen, sobald wir eine Portion mit
1111 // einer Laenge > 0 erreicht haben.
1112 pPor
= pPor
->GetLen() ? 0 : pPor
->GetPortion();
1114 pLine
= pLine
->GetLen() ? 0 : pLine
->GetNext();
1119 /*************************************************************************
1120 * SwCombinedPortion::SwCombinedPortion(..)
1121 * initializes the script array and clears the width array
1122 *************************************************************************/
1124 SwCombinedPortion::SwCombinedPortion( const XubString
&rTxt
)
1125 : SwFldPortion( rTxt
)
1128 SetWhichPor( POR_COMBINED
);
1129 if( aExpand
.Len() > 6 )
1131 // Initialization of the scripttype array,
1132 // the arrays of width and position are filled by the format function
1133 if( pBreakIt
->GetBreakIter().is() )
1135 BYTE nScr
= SW_SCRIPTS
;
1136 for( USHORT i
= 0; i
< rTxt
.Len(); ++i
)
1138 USHORT nScript
= pBreakIt
->GetBreakIter()->getScriptType( rTxt
, i
);
1139 switch ( nScript
) {
1140 case i18n::ScriptType::LATIN
: nScr
= SW_LATIN
; break;
1141 case i18n::ScriptType::ASIAN
: nScr
= SW_CJK
; break;
1142 case i18n::ScriptType::COMPLEX
: nScr
= SW_CTL
; break;
1149 for( USHORT i
= 0; i
< 6; aScrType
[i
++] = 0 )
1152 memset( &aWidth
, 0, sizeof(aWidth
) );
1155 /*************************************************************************
1156 * SwCombinedPortion::Paint(..)
1157 *************************************************************************/
1159 void SwCombinedPortion::Paint( const SwTxtPaintInfo
&rInf
) const
1161 ASSERT( GetLen() <= 1, "SwFldPortion::Paint: rest-portion polution?" );
1164 rInf
.DrawBackBrush( *this );
1165 rInf
.DrawViewOpt( *this, POR_FLD
);
1167 // do we have to repaint a post it portion?
1168 if( rInf
.OnWin() && pPortion
&& !pPortion
->Width() )
1169 pPortion
->PrePaint( rInf
, this );
1171 USHORT nCount
= aExpand
.Len();
1174 ASSERT( nCount
< 7, "Too much combined characters" );
1176 // the first character of the second row
1177 USHORT nTop
= ( nCount
+ 1 ) / 2;
1179 SwFont
aTmpFont( *rInf
.GetFont() );
1180 aTmpFont
.SetProportion( nProportion
); // a smaller font
1181 SwFontSave
aFontSave( rInf
, &aTmpFont
);
1184 Point aOldPos
= rInf
.GetPos();
1185 Point
aOutPos( aOldPos
.X(), aOldPos
.Y() - nUpPos
);// Y of the first row
1188 if( i
== nTop
) // change the row
1189 aOutPos
.Y() = aOldPos
.Y() + nLowPos
; // Y of the second row
1190 aOutPos
.X() = aOldPos
.X() + aPos
[i
]; // X position
1191 const BYTE nAct
= aScrType
[i
]; // script type
1192 aTmpFont
.SetActual( nAct
);
1193 // if there're more than 4 characters to display, we choose fonts
1194 // with 2/3 of the original font width.
1195 if( aWidth
[ nAct
] )
1197 Size aTmpSz
= aTmpFont
.GetSize( nAct
);
1198 if( aTmpSz
.Width() != aWidth
[ nAct
] )
1200 aTmpSz
.Width() = aWidth
[ nAct
];
1201 aTmpFont
.SetSize( aTmpSz
, nAct
);
1204 ((SwTxtPaintInfo
&)rInf
).SetPos( aOutPos
);
1205 rInf
.DrawText( aExpand
, *this, i
, 1 );
1208 // rInf is const, so we have to take back our manipulations
1209 ((SwTxtPaintInfo
&)rInf
).SetPos( aOldPos
);
1213 /*************************************************************************
1214 * SwCombinedPortion::Format(..)
1215 *************************************************************************/
1217 sal_Bool
SwCombinedPortion::Format( SwTxtFormatInfo
&rInf
)
1219 USHORT nCount
= aExpand
.Len();
1226 ASSERT( nCount
< 7, "Too much combined characters" );
1227 // If there are leading "weak"-scripttyped characters in this portion,
1228 // they get the actual scripttype.
1230 while( i
< nCount
&& SW_SCRIPTS
== aScrType
[i
] )
1231 aScrType
[i
++] = rInf
.GetFont()->GetActual();
1234 // more than four? Ok, then we need the 2/3 font width
1236 while( i
< aExpand
.Len() )
1238 ASSERT( aScrType
[i
] < SW_SCRIPTS
, "Combined: Script fault" );
1239 if( !aWidth
[ aScrType
[i
] ] )
1241 rInf
.GetOut()->SetFont( rInf
.GetFont()->GetFnt( aScrType
[i
] ) );
1242 aWidth
[ aScrType
[i
] ] =
1243 static_cast<USHORT
>(2 * rInf
.GetOut()->GetFontMetric().GetSize().Width() / 3);
1249 USHORT nTop
= ( nCount
+ 1 ) / 2; // the first character of the second line
1250 ViewShell
*pSh
= rInf
.GetTxtFrm()->GetShell();
1251 SwFont
aTmpFont( *rInf
.GetFont() );
1252 SwFontSave
aFontSave( rInf
, &aTmpFont
);
1254 // In nMainAscent/Descent we store the ascent and descent
1255 // of the original surrounding font
1256 USHORT nMaxDescent
, nMaxAscent
, nMaxWidth
;
1257 USHORT nMainDescent
= rInf
.GetFont()->GetHeight( pSh
, *rInf
.GetOut() );
1258 const USHORT nMainAscent
= rInf
.GetFont()->GetAscent( pSh
, *rInf
.GetOut() );
1259 nMainDescent
= nMainDescent
- nMainAscent
;
1260 // we start with a 50% font, but if we notice that the combined portion
1261 // becomes bigger than the surrounding font, we check 45% and maybe 40%.
1265 aTmpFont
.SetProportion( nProportion
);
1267 memset( &aPos
, 0, sizeof(aPos
) );
1271 nUpPos
= nLowPos
= 0;
1273 // Now we get the width of all characters.
1274 // The ascent and the width of the first line are stored in the
1275 // ascent member of the portion, the descent in nLowPos.
1276 // The ascent, descent and width of the second line are stored in the
1277 // local nMaxAscent, nMaxDescent and nMaxWidth variables.
1280 BYTE nScrp
= aScrType
[i
];
1281 aTmpFont
.SetActual( nScrp
);
1282 if( aWidth
[ nScrp
] )
1284 Size
aFontSize( aTmpFont
.GetSize( nScrp
) );
1285 aFontSize
.Width() = aWidth
[ nScrp
];
1286 aTmpFont
.SetSize( aFontSize
, nScrp
);
1289 SwDrawTextInfo
aDrawInf( pSh
, *rInf
.GetOut(), 0, aExpand
, i
, 1 );
1290 Size aSize
= aTmpFont
._GetTxtSize( aDrawInf
);
1291 USHORT nAsc
= aTmpFont
.GetAscent( pSh
, *rInf
.GetOut() );
1292 aPos
[ i
] = (USHORT
)aSize
.Width();
1293 if( i
== nTop
) // enter the second line
1295 nLowPos
= nMaxDescent
;
1296 Height( nMaxDescent
+ nMaxAscent
);
1298 SetAscent( nMaxAscent
);
1303 nMaxWidth
= nMaxWidth
+ aPos
[ i
++ ];
1304 if( nAsc
> nMaxAscent
)
1306 if( aSize
.Height() - nAsc
> nMaxDescent
)
1307 nMaxDescent
= static_cast<USHORT
>(aSize
.Height() - nAsc
);
1309 // for one or two characters we double the width of the portion
1316 Height( nMaxAscent
+ nMaxDescent
);
1317 nLowPos
= nMaxDescent
;
1320 Height( Height() + nMaxDescent
+ nMaxAscent
);
1321 nUpPos
= nMaxAscent
;
1322 SetAscent( Height() - nMaxDescent
- nLowPos
);
1323 } while( nProportion
> 40 && ( GetAscent() > nMainAscent
||
1324 Height() - GetAscent() > nMainDescent
) );
1325 // if the combined portion is smaller than the surrounding text,
1326 // the portion grows. This looks better, if there's a character background.
1327 if( GetAscent() < nMainAscent
)
1329 Height( Height() + nMainAscent
- GetAscent() );
1330 SetAscent( nMainAscent
);
1332 if( Height() < nMainAscent
+ nMainDescent
)
1333 Height( nMainAscent
+ nMainDescent
);
1335 // We calculate the x positions of the characters in both lines..
1336 USHORT nTopDiff
= 0;
1337 USHORT nBotDiff
= 0;
1338 if( nMaxWidth
> Width() )
1340 nTopDiff
= ( nMaxWidth
- Width() ) / 2;
1344 nBotDiff
= ( Width() - nMaxWidth
) / 2;
1347 case 3: aPos
[1] = aPos
[0] + nTopDiff
; // no break
1348 case 2: aPos
[nTop
-1] = Width() - aPos
[nTop
-1];
1353 case 5: aPos
[4] = aPos
[3] + nBotDiff
; // no break
1354 case 3: aPos
[nTop
] = nBotDiff
; break;
1355 case 6: aPos
[4] = aPos
[3] + nBotDiff
; // no break
1356 case 4: aPos
[nTop
] = 0; // no break
1357 case 2: aPos
[nCount
-1] = Width() - aPos
[nCount
-1];
1360 // Does the combined portion fit the line?
1361 const sal_Bool bFull
= rInf
.Width() < rInf
.X() + Width();
1364 if( rInf
.GetLineStart() == rInf
.GetIdx() && (!rInf
.GetLast()->InFldGrp()
1365 || !((SwFldPortion
*)rInf
.GetLast())->IsFollow() ) )
1366 Width( (USHORT
)( rInf
.Width() - rInf
.X() ) );
1372 if( rInf
.GetLast() )
1373 rInf
.GetLast()->FormatEOL( rInf
);
1379 /*************************************************************************
1380 * SwCombinedPortion::GetViewWidth(..)
1381 *************************************************************************/
1383 KSHORT
SwCombinedPortion::GetViewWidth( const SwTxtSizeInfo
&rInf
) const
1385 if( !GetLen() ) // for the dummy part at the end of the line, where
1386 return 0; // the combined portion doesn't fit.
1387 return SwFldPortion::GetViewWidth( rInf
);