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: porrst.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"
33 #include <hintids.hxx>
34 #include <sfx2/printer.hxx>
35 #include <svx/lspcitem.hxx>
36 #include <svx/adjitem.hxx>
37 #include <svx/escpitem.hxx>
38 #include <svx/lrspitem.hxx>
39 #include <svx/pgrditem.hxx>
40 #include <vcl/window.hxx>
41 #include <vcl/svapp.hxx>
42 #include <viewsh.hxx> // ViewShell
43 #include <viewopt.hxx>
44 #include <ndtxt.hxx> // SwTxtNode
45 #include <pagefrm.hxx> // SwPageFrm
47 #include <SwPortionHandler.hxx>
51 #include <txtpaint.hxx> // ClipVout
52 #include <swfntcch.hxx> // SwFontAccess
53 #include <tgrditem.hxx>
54 #include <pagedesc.hxx> // SwPageDesc
56 #include <redlnitr.hxx> // SwRedlineItr
57 #include <porfly.hxx> // SwFlyPortion
58 #include <atrhndl.hxx>
60 #include <IDocumentRedlineAccess.hxx>
61 #include <IDocumentSettingAccess.hxx>
62 #include <IDocumentDeviceAccess.hxx>
66 /*************************************************************************
67 * class SwTmpEndPortion
68 *************************************************************************/
70 SwTmpEndPortion::SwTmpEndPortion( const SwLinePortion
&rPortion
)
72 Height( rPortion
.Height() );
73 SetAscent( rPortion
.GetAscent() );
74 SetWhichPor( POR_TMPEND
);
77 /*************************************************************************
78 * virtual SwTmpEndPortion::Paint()
79 *************************************************************************/
81 void SwTmpEndPortion::Paint( const SwTxtPaintInfo
&rInf
) const
83 if( rInf
.OnWin() && rInf
.GetOpt().IsParagraph() )
85 SwDefFontSave
aSave( rInf
);
86 const XubString
aTmp( CH_PAR
);
87 rInf
.DrawText( aTmp
, *this );
91 /*************************************************************************
92 * class SwBreakPortion
93 *************************************************************************/
94 SwBreakPortion::SwBreakPortion( const SwLinePortion
&rPortion
)
95 : SwLinePortion( rPortion
)
98 SetWhichPor( POR_BRK
);
101 xub_StrLen
SwBreakPortion::GetCrsrOfst( const KSHORT
) const
104 KSHORT
SwBreakPortion::GetViewWidth( const SwTxtSizeInfo
& ) const
107 SwLinePortion
*SwBreakPortion::Compress()
108 { return (GetPortion() && GetPortion()->InTxtGrp() ? 0 : this); }
110 void SwBreakPortion::Paint( const SwTxtPaintInfo
&rInf
) const
112 if( rInf
.OnWin() && rInf
.GetOpt().IsLineBreak() )
113 rInf
.DrawLineBreak( *this );
116 /*************************************************************************
117 * virtual SwBreakPortion::Format()
118 *************************************************************************/
120 sal_Bool
SwBreakPortion::Format( SwTxtFormatInfo
&rInf
)
122 const SwLinePortion
*pRoot
= rInf
.GetRoot();
124 Height( pRoot
->Height() );
125 SetAscent( pRoot
->GetAscent() );
126 if ( rInf
.GetIdx()+1 == rInf
.GetTxt().Len() )
127 rInf
.SetNewLine( sal_True
);
131 /*************************************************************************
132 * virtual SwBreakPortion::HandlePortion()
133 *************************************************************************/
135 void SwBreakPortion::HandlePortion( SwPortionHandler
& rPH
) const
137 rPH
.Text( GetLen(), GetWhichPor() );
141 SwKernPortion::SwKernPortion( SwLinePortion
&rPortion
, short nKrn
,
142 sal_Bool bBG
, sal_Bool bGK
) :
143 nKern( nKrn
), bBackground( bBG
), bGridKern( bGK
)
145 Height( rPortion
.Height() );
146 SetAscent( rPortion
.GetAscent() );
148 SetWhichPor( POR_KERN
);
151 rPortion
.Insert( this );
154 SwKernPortion::SwKernPortion( const SwLinePortion
& rPortion
) :
155 nKern( 0 ), bBackground( sal_False
), bGridKern( sal_True
)
157 Height( rPortion
.Height() );
158 SetAscent( rPortion
.GetAscent() );
161 SetWhichPor( POR_KERN
);
164 void SwKernPortion::Paint( const SwTxtPaintInfo
&rInf
) const
168 // bBackground is set for Kerning Portions between two fields
170 rInf
.DrawViewOpt( *this, POR_FLD
);
172 rInf
.DrawBackBrush( *this );
174 // do we have to repaint a post it portion?
175 if( rInf
.OnWin() && pPortion
&& !pPortion
->Width() )
176 pPortion
->PrePaint( rInf
, this );
178 if( rInf
.GetFont()->IsPaintBlank() )
180 static sal_Char __READONLY_DATA sDoubleSpace
[] = " ";
181 XubString
aTxtDouble( sDoubleSpace
, RTL_TEXTENCODING_MS_1252
);
182 // --> FME 2006-07-12 #b6439097#
184 rInf
.CalcRect( *this, &aClipRect
, 0 );
185 SwSaveClip
aClip( (OutputDevice
*)rInf
.GetOut() );
186 aClip
.ChgClip( aClipRect
, 0 );
188 rInf
.DrawText( aTxtDouble
, *this, 0, 2, sal_True
);
193 void SwKernPortion::FormatEOL( SwTxtFormatInfo
&rInf
)
198 if( rInf
.GetLast() == this )
199 rInf
.SetLast( FindPrevPortion( rInf
.GetRoot() ) );
204 rInf
.GetLast()->FormatEOL( rInf
);
207 SwArrowPortion::SwArrowPortion( const SwLinePortion
&rPortion
) :
210 Height( rPortion
.Height() );
211 SetAscent( rPortion
.GetAscent() );
213 SetWhichPor( POR_ARROW
);
216 SwArrowPortion::SwArrowPortion( const SwTxtPaintInfo
&rInf
)
219 Height( (USHORT
)(rInf
.GetTxtFrm()->Prt().Height()) );
220 aPos
.X() = rInf
.GetTxtFrm()->Frm().Left() +
221 rInf
.GetTxtFrm()->Prt().Right();
222 aPos
.Y() = rInf
.GetTxtFrm()->Frm().Top() +
223 rInf
.GetTxtFrm()->Prt().Bottom();
226 void SwArrowPortion::Paint( const SwTxtPaintInfo
&rInf
) const
228 ((SwArrowPortion
*)this)->aPos
= rInf
.GetPos();
231 SwLinePortion
*SwArrowPortion::Compress() { return this; }
233 SwTwips
SwTxtFrm::EmptyHeight() const
236 ViewShell
*pSh
= GetShell();
237 if ( pSh
->IsA( TYPE(SwCrsrShell
) ) ) {
238 SwCrsrShell
*pCrSh
=(SwCrsrShell
*)pSh
;
239 SwCntntFrm
*pCurrFrm
=pCrSh
->GetCurrFrm();
240 if (pCurrFrm
==(SwCntntFrm
*)this) {
249 ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::EmptyHeight with swapped frame" );
252 const SwTxtNode
& rTxtNode
= *GetTxtNode();
253 const IDocumentSettingAccess
* pIDSA
= rTxtNode
.getIDocumentSettingAccess();
254 ViewShell
*pSh
= GetShell();
255 if ( rTxtNode
.HasSwAttrSet() )
257 const SwAttrSet
*pAttrSet
= &( rTxtNode
.GetSwAttrSet() );
258 pFnt
= new SwFont( pAttrSet
, pIDSA
);
262 SwFontAccess
aFontAccess( &rTxtNode
.GetAnyFmtColl(), pSh
);
263 pFnt
= new SwFont( *aFontAccess
.Get()->GetFont() );
264 pFnt
->ChkMagic( pSh
, pFnt
->GetActual() );
268 pFnt
->SetVertical( 2700 );
270 OutputDevice
* pOut
= pSh
? pSh
->GetOut() : 0;
271 if ( !pOut
|| !pIDSA
->get(IDocumentSettingAccess::BROWSE_MODE
) ||
272 ( pSh
->GetViewOptions()->IsPrtFormat() ) )
274 pOut
= rTxtNode
.getIDocumentDeviceAccess()->getReferenceDevice(true);
277 const IDocumentRedlineAccess
* pIDRA
= rTxtNode
.getIDocumentRedlineAccess();
278 if( IDocumentRedlineAccess::IsShowChanges( pIDRA
->GetRedlineMode() ) )
280 MSHORT nRedlPos
= pIDRA
->GetRedlinePos( rTxtNode
, USHRT_MAX
);
281 if( MSHRT_MAX
!= nRedlPos
)
283 SwAttrHandler aAttrHandler
;
284 aAttrHandler
.Init( GetTxtNode()->GetSwAttrSet(),
285 *GetTxtNode()->getIDocumentSettingAccess(), NULL
);
286 SwRedlineItr
aRedln( rTxtNode
, *pFnt
, aAttrHandler
,
287 nRedlPos
, sal_True
);
293 nRet
= IsVertical() ?
294 Prt().SSize().Width() + 1 :
295 Prt().SSize().Height() + 1;
298 pFnt
->SetFntChg( sal_True
);
299 pFnt
->ChgPhysFnt( pSh
, *pOut
);
300 nRet
= pFnt
->GetHeight( pSh
, *pOut
);
306 /*************************************************************************
307 * SwTxtFrm::FormatEmpty()
308 *************************************************************************/
310 sal_Bool
SwTxtFrm::FormatEmpty()
312 ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::FormatEmpty with swapped frame" );
314 if ( HasFollow() || GetTxtNode()->GetpSwpHints() ||
315 0 != GetTxtNode()->GetNumRule() ||
316 GetTxtNode()->HasHiddenCharAttribute( true ) ||
317 IsInFtn() || ( HasPara() && GetPara()->IsPrepMustFit() ) )
319 const SwAttrSet
& aSet
= GetTxtNode()->GetSwAttrSet();
320 const SvxAdjust nAdjust
= aSet
.GetAdjust().GetAdjust();
321 if( ( ( ! IsRightToLeft() && ( SVX_ADJUST_LEFT
!= nAdjust
) ) ||
322 ( IsRightToLeft() && ( SVX_ADJUST_RIGHT
!= nAdjust
) ) ) ||
323 aSet
.GetRegister().GetValue() )
325 const SvxLineSpacingItem
&rSpacing
= aSet
.GetLineSpacing();
326 if( SVX_LINE_SPACE_MIN
== rSpacing
.GetLineSpaceRule() ||
327 SVX_LINE_SPACE_FIX
== rSpacing
.GetLineSpaceRule() ||
328 aSet
.GetLRSpace().IsAutoFirst() )
332 SwTxtFly
aTxtFly( this );
334 sal_Bool bFirstFlyCheck
= 0 != Prt().Height();
335 if ( bFirstFlyCheck
&&
336 aTxtFly
.IsOn() && aTxtFly
.IsAnyObj( aRect
) )
340 SwTwips nHeight
= EmptyHeight();
342 if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() &&
345 GETGRID( FindPageFrm() )
347 nHeight
= pGrid
->GetBaseHeight() + pGrid
->GetRubyHeight();
351 const SwTwips nChg
= nHeight
- (Prt().*fnRect
->fnGetHeight
)();
354 SetUndersized( sal_False
);
362 SetCacheIdx( MSHRT_MAX
);
365 SetEmpty( sal_True
);
368 if( !bFirstFlyCheck
&&
369 aTxtFly
.IsOn() && aTxtFly
.IsAnyObj( aRect
) )
372 // --> OD 2004-11-17 #i35635# - call method <HideAndShowObjects()>
373 // to assure that objects anchored at the empty paragraph are
374 // correctly visible resp. invisible.
375 HideAndShowObjects();
382 sal_Bool
SwTxtFrm::FillRegister( SwTwips
& rRegStart
, KSHORT
& rRegDiff
)
384 const SwFrm
*pFrm
= this;
386 while( !( ( FRM_BODY
| FRM_FLY
)
387 & pFrm
->GetType() ) && pFrm
->GetUpper() )
388 pFrm
= pFrm
->GetUpper();
389 if( ( FRM_BODY
| FRM_FLY
) & pFrm
->GetType() )
392 rRegStart
= (pFrm
->*fnRect
->fnGetPrtTop
)();
393 pFrm
= pFrm
->FindPageFrm();
394 if( pFrm
->IsPageFrm() )
396 SwPageDesc
* pDesc
= ((SwPageFrm
*)pFrm
)->FindPageDesc();
399 rRegDiff
= pDesc
->GetRegHeight();
402 const SwTxtFmtColl
*pFmt
= pDesc
->GetRegisterFmtColl();
405 const SvxLineSpacingItem
&rSpace
= pFmt
->GetLineSpacing();
406 if( SVX_LINE_SPACE_FIX
== rSpace
.GetLineSpaceRule() )
408 rRegDiff
= rSpace
.GetLineHeight();
409 pDesc
->SetRegHeight( rRegDiff
);
410 pDesc
->SetRegAscent( ( 4 * rRegDiff
) / 5 );
414 ViewShell
*pSh
= GetShell();
415 SwFontAccess
aFontAccess( pFmt
, pSh
);
416 SwFont
aFnt( *aFontAccess
.Get()->GetFont() );
418 OutputDevice
*pOut
= 0;
419 if( !GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) ||
420 (pSh
&& pSh
->GetViewOptions()->IsPrtFormat()) )
421 pOut
= GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
424 pOut
= pSh
->GetWin();
427 pOut
= GetpApp()->GetDefaultDevice();
429 MapMode
aOldMap( pOut
->GetMapMode() );
430 pOut
->SetMapMode( MapMode( MAP_TWIP
) );
432 aFnt
.ChgFnt( pSh
, *pOut
);
433 rRegDiff
= aFnt
.GetHeight( pSh
, *pOut
);
434 KSHORT nNettoHeight
= rRegDiff
;
436 switch( rSpace
.GetLineSpaceRule() )
438 case SVX_LINE_SPACE_AUTO
:
440 case SVX_LINE_SPACE_MIN
:
442 if( rRegDiff
< KSHORT( rSpace
.GetLineHeight() ) )
443 rRegDiff
= rSpace
.GetLineHeight();
447 sal_False
, ": unknown LineSpaceRule" );
449 switch( rSpace
.GetInterLineSpaceRule() )
451 case SVX_INTER_LINE_SPACE_OFF
:
453 case SVX_INTER_LINE_SPACE_PROP
:
455 long nTmp
= rSpace
.GetPropLineSpace();
457 nTmp
= nTmp
? 50 : 100;
462 rRegDiff
= (KSHORT
)nTmp
;
463 nNettoHeight
= rRegDiff
;
466 case SVX_INTER_LINE_SPACE_FIX
:
468 rRegDiff
= rRegDiff
+ rSpace
.GetInterLineSpace();
469 nNettoHeight
= rRegDiff
;
472 default: ASSERT( sal_False
, ": unknown InterLineSpaceRule" );
474 pDesc
->SetRegHeight( rRegDiff
);
475 pDesc
->SetRegAscent( rRegDiff
- nNettoHeight
+
476 aFnt
.GetAscent( pSh
, *pOut
) );
477 pOut
->SetMapMode( aOldMap
);
481 const long nTmpDiff
= pDesc
->GetRegAscent() - rRegDiff
;
483 rRegStart
-= nTmpDiff
;
485 rRegStart
+= nTmpDiff
;
489 return ( 0 != rRegDiff
);
492 /*************************************************************************
493 * virtual SwHiddenTextPortion::Paint()
494 *************************************************************************/
496 void SwHiddenTextPortion::Paint( const SwTxtPaintInfo
& rInf
) const
499 #if OSL_DEBUG_LEVEL > 1
500 OutputDevice
* pOut
= (OutputDevice
*)rInf
.GetOut();
501 Color
aCol( SwViewOption::GetFieldShadingsColor() );
502 Color
aOldColor( pOut
->GetFillColor() );
503 pOut
->SetFillColor( aCol
);
504 Point
aPos( rInf
.GetPos() );
507 SwRect
aRect( aPos
, Size( 100, 200 ) );
508 ((OutputDevice
*)pOut
)->DrawRect( aRect
.SVRect() );
509 pOut
->SetFillColor( aOldColor
);
513 /*************************************************************************
514 * virtual SwHiddenTextPortion::Format()
515 *************************************************************************/
517 sal_Bool
SwHiddenTextPortion::Format( SwTxtFormatInfo
&rInf
)
520 rInf
.GetTxtFrm()->HideFootnotes( rInf
.GetIdx(), rInf
.GetIdx() + GetLen() );
525 /*************************************************************************
526 * virtual SwControlCharPortion::Paint()
527 *************************************************************************/
529 void SwControlCharPortion::Paint( const SwTxtPaintInfo
&rInf
) const
531 if ( Width() ) // is only set during prepaint mode
533 rInf
.DrawViewOpt( *this, POR_CONTROLCHAR
);
535 if ( !rInf
.GetOpt().IsPagePreview() &&
536 !rInf
.GetOpt().IsReadonly() &&
537 SwViewOption::IsFieldShadings() &&
538 CHAR_ZWNBSP
!= mcChar
)
540 SwFont
aTmpFont( *rInf
.GetFont() );
541 aTmpFont
.SetEscapement( CHAR_ZWSP
== mcChar
? DFLT_ESC_AUTO_SUB
: -25 );
542 const USHORT nProp
= 40;
543 aTmpFont
.SetProportion( nProp
); // a smaller font
544 SwFontSave
aFontSave( rInf
, &aTmpFont
);
551 aOutString
= '/'; break;
553 // rTxt = sal_Unicode(0x2514); break;
555 // rTxt = sal_Unicode(0x2518); break;
558 if ( !mnHalfCharWidth
)
559 mnHalfCharWidth
= rInf
.GetTxtSize( aOutString
).Width() / 2;
561 Point aOldPos
= rInf
.GetPos();
562 Point
aNewPos( aOldPos
);
563 aNewPos
.X() = aNewPos
.X() + ( Width() / 2 ) - mnHalfCharWidth
;
564 const_cast< SwTxtPaintInfo
& >( rInf
).SetPos( aNewPos
);
566 rInf
.DrawText( aOutString
, *this );
568 const_cast< SwTxtPaintInfo
& >( rInf
).SetPos( aOldPos
);
573 /*************************************************************************
574 * virtual SwControlCharPortion::Format()
575 *************************************************************************/
577 sal_Bool
SwControlCharPortion::Format( SwTxtFormatInfo
&rInf
)
579 const SwLinePortion
* pRoot
= rInf
.GetRoot();
581 Height( pRoot
->Height() );
582 SetAscent( pRoot
->GetAscent() );
587 /*************************************************************************
588 * virtual SwControlCharPortion::GetViewWidth()
589 *************************************************************************/
591 KSHORT
SwControlCharPortion::GetViewWidth( const SwTxtSizeInfo
& rInf
) const
594 mnViewWidth
= rInf
.GetTxtSize( ' ' ).Width();