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: frmpaint.cxx,v $
10 * $Revision: 1.60.68.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"
34 #include <com/sun/star/text/HoriOrientation.hpp>
35 #include <hintids.hxx>
36 #include <vcl/sound.hxx>
37 #include <tools/shl.hxx> // SW_MOD
38 #include <svx/pgrditem.hxx>
39 #include <svx/lrspitem.hxx>
40 #include <pagedesc.hxx> // SwPageDesc
41 #include <tgrditem.hxx>
45 #include <fmtline.hxx>
48 #include <lineinfo.hxx>
50 #include <charfmt.hxx>
51 #include <pagefrm.hxx>
52 #include <viewsh.hxx> // ViewShell
53 #include <viewimp.hxx> // SwViewImp
54 #include <viewopt.hxx> // SwViewOption
55 #include <frmtool.hxx> // DrawGraphic
57 #include <txtfrm.hxx> // SwTxtFrm
58 #include <itrpaint.hxx> // SwTxtPainter
59 #include <txtpaint.hxx> // SwSaveClip
60 #include <txtcache.hxx> // SwTxtLineAccess
61 #include <flyfrm.hxx> // SwFlyFrm
62 #include <redlnitr.hxx> // SwRedlineItr
63 #include <swmodule.hxx> // SW_MOD
64 #include <tabfrm.hxx> // SwTabFrm (Redlining)
65 #include <scrrect.hxx>
66 #include <SwGrammarMarkUp.hxx>
68 // --> FME 2004-06-08 #i12836# enhanced pdf export
69 #include <EnhancedPDFExportHelper.hxx>
72 #include <IDocumentStylePoolAccess.hxx>
73 #include <IDocumentLineNumberAccess.hxx>
75 // --> OD 2006-06-27 #b6440955#
76 // variable moved to class <numfunc:GetDefBulletConfig>
77 //extern const sal_Char __FAR_DATA sBulletFntName[];
80 extern const String
& GetDefBulletFontname();
81 extern bool IsDefBulletFontUserDefined();
86 #define REDLINE_DISTANCE 567/4
87 #define REDLINE_MINDIST 567/10
89 using namespace ::com::sun::star
;
91 ////////////////////////////////////////////////////////////
93 sal_Bool bInitFont
= sal_True
;
99 const SwTxtFrm
* pTxtFrm
;
102 const SwLineNumberInfo
&rLineInf
;
109 inline sal_Bool
IsClipChg() { return aClip
.IsChg(); }
111 SwExtraPainter( const SwTxtFrm
*pFrm
, ViewShell
*pVwSh
,
112 const SwLineNumberInfo
&rLnInf
, const SwRect
&rRct
,
113 sal_Int16 eHor
, sal_Bool bLnNm
);
114 ~SwExtraPainter() { delete pFnt
; }
115 inline SwFont
* GetFont() const { return pFnt
; }
116 inline void IncLineNr() { ++nLineNr
; }
117 inline sal_Bool
HasNumber() { return !( nLineNr
% rLineInf
.GetCountBy() ); }
118 inline sal_Bool
HasDivider() { if( !nDivider
) return sal_False
;
119 return !(nLineNr
% rLineInf
.GetDividerCountBy()); }
121 void PaintExtra( SwTwips nY
, long nAsc
, long nMax
, sal_Bool bRed
);
122 void PaintRedline( SwTwips nY
, long nMax
);
126 SwExtraPainter::SwExtraPainter( const SwTxtFrm
*pFrm
, ViewShell
*pVwSh
,
127 const SwLineNumberInfo
&rLnInf
, const SwRect
&rRct
,
128 sal_Int16 eHor
, sal_Bool bLnNm
)
129 : aClip( pVwSh
->GetWin() || pFrm
->IsUndersized() ? pVwSh
->GetOut() : 0 ),
130 aRect( rRct
), pTxtFrm( pFrm
), pSh( pVwSh
), pFnt( 0 ), rLineInf( rLnInf
),
131 nLineNr( 1L ), bLineNum( bLnNm
)
133 if( pFrm
->IsUndersized() )
135 SwTwips nBottom
= pFrm
->Frm().Bottom();
136 if( aRect
.Bottom() > nBottom
)
137 aRect
.Bottom( nBottom
);
139 MSHORT nVirtPageNum
= 0;
141 { /* initialisiert die Member, die bei Zeilennumerierung notwendig sind:
143 nDivider, wie oft ist ein Teilerstring gewuenscht, 0 == nie;
144 nX, X-Position der Zeilennummern;
145 pFnt, der Font der Zeilennummern;
146 nLineNr, die erste Zeilennummer;
147 bLineNum wird ggf.wieder auf sal_False gesetzt, wenn die Numerierung sich
148 komplett ausserhalb des Paint-Rechtecks aufhaelt. */
149 nDivider
= rLineInf
.GetDivider().Len() ? rLineInf
.GetDividerCountBy() : 0;
150 nX
= pFrm
->Frm().Left();
151 SwCharFmt
* pFmt
= rLineInf
.GetCharFmt( const_cast<IDocumentStylePoolAccess
&>(*pFrm
->GetNode()->getIDocumentStylePoolAccess()) );
152 ASSERT( pFmt
, "PaintExtraData without CharFmt" );
153 pFnt
= new SwFont( &pFmt
->GetAttrSet(), pFrm
->GetTxtNode()->getIDocumentSettingAccess() );
155 pFnt
->ChgPhysFnt( pSh
, *pSh
->GetOut() );
156 pFnt
->SetVertical( 0, pFrm
->IsVertical() );
157 nLineNr
+= pFrm
->GetAllLines() - pFrm
->GetThisLines();
158 LineNumberPosition ePos
= rLineInf
.GetPos();
159 if( ePos
!= LINENUMBER_POS_LEFT
&& ePos
!= LINENUMBER_POS_RIGHT
)
161 if( pFrm
->FindPageFrm()->OnRightPage() )
164 ePos
= ePos
== LINENUMBER_POS_INSIDE
?
165 LINENUMBER_POS_LEFT
: LINENUMBER_POS_RIGHT
;
170 ePos
= ePos
== LINENUMBER_POS_OUTSIDE
?
171 LINENUMBER_POS_LEFT
: LINENUMBER_POS_RIGHT
;
174 if( LINENUMBER_POS_LEFT
== ePos
)
177 nX
-= rLineInf
.GetPosFromLeft();
178 if( nX
< aRect
.Left() )
179 bLineNum
= sal_False
;
184 nX
+= pFrm
->Frm().Width() + rLineInf
.GetPosFromLeft();
185 if( nX
> aRect
.Right() )
186 bLineNum
= sal_False
;
189 if( eHor
!= text::HoriOrientation::NONE
)
191 if( text::HoriOrientation::INSIDE
== eHor
|| text::HoriOrientation::OUTSIDE
== eHor
)
194 nVirtPageNum
= pFrm
->FindPageFrm()->OnRightPage() ? 1 : 2;
195 if( nVirtPageNum
% 2 )
196 eHor
= eHor
== text::HoriOrientation::INSIDE
? text::HoriOrientation::LEFT
: text::HoriOrientation::RIGHT
;
198 eHor
= eHor
== text::HoriOrientation::OUTSIDE
? text::HoriOrientation::LEFT
: text::HoriOrientation::RIGHT
;
200 const SwFrm
* pTmpFrm
= pFrm
->FindTabFrm();
203 nRedX
= text::HoriOrientation::LEFT
== eHor
? pTmpFrm
->Frm().Left() - REDLINE_DISTANCE
:
204 pTmpFrm
->Frm().Right() + REDLINE_DISTANCE
;
208 /*************************************************************************
209 * SwExtraPainter::PaintExtra()
210 **************************************************************************/
212 void SwExtraPainter::PaintExtra( SwTwips nY
, long nAsc
, long nMax
, sal_Bool bRed
)
214 //Zeilennummer ist staerker als der Teiler
215 const XubString
aTmp( HasNumber() ? rLineInf
.GetNumType().GetNumStr( nLineNr
)
216 : rLineInf
.GetDivider() );
218 // get script type of line numbering:
219 pFnt
->SetActual( SwScriptInfo::WhichFont( 0, &aTmp
, 0 ) );
221 SwDrawTextInfo
aDrawInf( pSh
, *pSh
->GetOut(), 0, aTmp
, 0, aTmp
.Len() );
222 aDrawInf
.SetSpace( 0 );
223 aDrawInf
.SetWrong( NULL
);
224 aDrawInf
.SetGrammarCheck( NULL
);
225 aDrawInf
.SetSmartTags( NULL
); // SMARTTAGS
226 aDrawInf
.SetLeft( 0 );
227 aDrawInf
.SetRight( LONG_MAX
);
228 aDrawInf
.SetFrm( pTxtFrm
);
229 aDrawInf
.SetFont( pFnt
);
230 aDrawInf
.SetSnapToGrid( sal_False
);
231 aDrawInf
.SetIgnoreFrmRTL( sal_True
);
233 sal_Bool bTooBig
= pFnt
->GetSize( pFnt
->GetActual() ).Height() > nMax
&&
234 pFnt
->GetHeight( pSh
, *pSh
->GetOut() ) > nMax
;
238 pTmpFnt
= new SwFont( *GetFont() );
244 pTmpFnt
->SetSize( Size( 0, nMax
), pTmpFnt
->GetActual() );
248 Point
aTmpPos( nX
, nY
);
250 sal_Bool bPaint
= sal_True
;
253 Size aSize
= pTmpFnt
->_GetTxtSize( aDrawInf
);
255 aTmpPos
.X() -= aSize
.Width();
256 // calculate rectangle containing the line number
257 SwRect
aRct( Point( aTmpPos
.X(),
258 aTmpPos
.Y() - pTmpFnt
->GetAscent( pSh
, *pSh
->GetOut() )
260 if( !aRect
.IsInside( aRct
) )
262 if( aRct
.Intersection( aRect
).IsEmpty() )
265 aClip
.ChgClip( aRect
, pTxtFrm
);
269 aTmpPos
.X() -= pTmpFnt
->_GetTxtSize( aDrawInf
).Width();
270 aDrawInf
.SetPos( aTmpPos
);
272 pTmpFnt
->_DrawText( aDrawInf
);
278 long nDiff
= bGoLeft
? nRedX
- nX
: nX
- nRedX
;
279 if( nDiff
> REDLINE_MINDIST
)
280 PaintRedline( nY
, nMax
);
284 void SwExtraPainter::PaintRedline( SwTwips nY
, long nMax
)
286 Point
aStart( nRedX
, nY
);
287 Point
aEnd( nRedX
, nY
+ nMax
);
291 SwRect
aRct( aStart
, aEnd
);
292 if( !aRect
.IsInside( aRct
) )
294 if( aRct
.Intersection( aRect
).IsEmpty() )
296 aClip
.ChgClip( aRect
, pTxtFrm
);
299 const Color
aOldCol( pSh
->GetOut()->GetLineColor() );
300 pSh
->GetOut()->SetLineColor( SW_MOD()->GetRedlineMarkColor() );
302 if ( pTxtFrm
->IsVertical() )
304 pTxtFrm
->SwitchHorizontalToVertical( aStart
);
305 pTxtFrm
->SwitchHorizontalToVertical( aEnd
);
308 pSh
->GetOut()->DrawLine( aStart
, aEnd
);
309 pSh
->GetOut()->SetLineColor( aOldCol
);
312 void SwTxtFrm::PaintExtraData( const SwRect
&rRect
) const
314 if( Frm().Top() > rRect
.Bottom() || Frm().Bottom() < rRect
.Top() )
317 const SwTxtNode
& rTxtNode
= *GetTxtNode();
318 const IDocumentRedlineAccess
* pIDRA
= rTxtNode
.getIDocumentRedlineAccess();
319 const SwLineNumberInfo
&rLineInf
= rTxtNode
.getIDocumentLineNumberAccess()->GetLineNumberInfo();
320 const SwFmtLineNumber
&rLineNum
= GetAttrSet()->GetLineNumber();
321 sal_Bool bLineNum
= !IsInTab() && rLineInf
.IsPaintLineNumbers() &&
322 ( !IsInFly() || rLineInf
.IsCountInFlys() ) && rLineNum
.IsCount();
323 sal_Int16 eHor
= (sal_Int16
)SW_MOD()->GetRedlineMarkPos();
324 if( eHor
!= text::HoriOrientation::NONE
&& !IDocumentRedlineAccess::IsShowChanges( pIDRA
->GetRedlineMode() ) )
325 eHor
= text::HoriOrientation::NONE
;
326 sal_Bool bRedLine
= eHor
!= text::HoriOrientation::NONE
;
327 if ( bLineNum
|| bRedLine
)
329 if( IsLocked() || IsHiddenNow() || !Prt().Height() )
331 ViewShell
*pSh
= GetShell();
333 SWAP_IF_NOT_SWAPPED( this )
334 SwRect
rOldRect( rRect
);
337 SwitchVerticalToHorizontal( (SwRect
&)rRect
);
339 SwLayoutModeModifier
aLayoutModeModifier( *pSh
->GetOut() );
340 aLayoutModeModifier
.Modify( sal_False
);
342 // --> FME 2004-06-24 #i16816# tagged pdf support
343 SwTaggedPDFHelper
aTaggedPDFHelper( 0, 0, 0, *pSh
->GetOut() );
346 SwExtraPainter
aExtra( this, pSh
, rLineInf
, rRect
, eHor
, bLineNum
);
350 SwTxtFrmLocker
aLock((SwTxtFrm
*)this);
352 SwTxtLineAccess
aAccess( (SwTxtFrm
*)this );
355 SwTxtPaintInfo
aInf( (SwTxtFrm
*)this, rRect
);
357 aLayoutModeModifier
.Modify( sal_False
);
359 SwTxtPainter
aLine( (SwTxtFrm
*)this, &aInf
);
360 sal_Bool bNoDummy
= !aLine
.GetNext(); // Nur eine Leerzeile!
362 while( aLine
.Y() + aLine
.GetLineHeight() <= rRect
.Top() )
364 if( !aLine
.GetCurr()->IsDummy() &&
365 ( rLineInf
.IsCountBlankLines() ||
366 aLine
.GetCurr()->HasCntnt() ) )
370 (SwRect
&)rRect
= rOldRect
;
376 long nBottom
= rRect
.Bottom();
378 sal_Bool bNoPrtLine
= 0 == GetMinPrtLine();
381 while ( aLine
.Y() < GetMinPrtLine() )
383 if( ( rLineInf
.IsCountBlankLines() || aLine
.GetCurr()->HasCntnt() )
384 && !aLine
.GetCurr()->IsDummy() )
389 bNoPrtLine
= aLine
.Y() >= GetMinPrtLine();
395 if( bNoDummy
|| !aLine
.GetCurr()->IsDummy() )
397 sal_Bool bRed
= bRedLine
&& aLine
.GetCurr()->HasRedline();
398 if( rLineInf
.IsCountBlankLines() || aLine
.GetCurr()->HasCntnt() )
401 ( aExtra
.HasNumber() || aExtra
.HasDivider() ) )
403 KSHORT nTmpHeight
, nTmpAscent
;
404 aLine
.CalcAscentAndHeight( nTmpAscent
, nTmpHeight
);
405 aExtra
.PaintExtra( aLine
.Y(), nTmpAscent
,
412 aExtra
.PaintRedline( aLine
.Y(), aLine
.GetLineHeight() );
414 } while( aLine
.Next() && aLine
.Y() <= nBottom
);
419 bRedLine
&= ( MSHRT_MAX
!= pIDRA
->GetRedlinePos(rTxtNode
, USHRT_MAX
) );
421 if( bLineNum
&& rLineInf
.IsCountBlankLines() &&
422 ( aExtra
.HasNumber() || aExtra
.HasDivider() ) )
424 aExtra
.PaintExtra( Frm().Top()+Prt().Top(), aExtra
.GetFont()
425 ->GetAscent( pSh
, *pSh
->GetOut() ), Prt().Height(), bRedLine
);
428 aExtra
.PaintRedline( Frm().Top()+Prt().Top(), Prt().Height() );
431 (SwRect
&)rRect
= rOldRect
;
436 /*************************************************************************
438 *************************************************************************/
440 SwRect
SwTxtFrm::Paint()
442 #if OSL_DEBUG_LEVEL > 1
443 const SwTwips nDbgY
= Frm().Top();
448 ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
450 SwRect
aRet( Prt() );
451 if ( IsEmpty() || !HasPara() )
455 // AMA: Wir liefern jetzt mal das richtige Repaintrechteck zurueck,
456 // d.h. als linken Rand den berechneten PaintOfst!
457 SwRepaint
*pRepaint
= GetPara()->GetRepaint();
459 if( pRepaint
->GetOfst() )
460 pRepaint
->Left( pRepaint
->GetOfst() );
462 l
= pRepaint
->GetRightOfst();
463 if( l
&& ( pRepaint
->GetOfst() || l
> pRepaint
->Right() ) )
464 pRepaint
->Right( l
);
465 pRepaint
->SetOfst( 0 );
468 if ( IsRightToLeft() )
469 SwitchLTRtoRTL( aRet
);
472 SwitchHorizontalToVertical( aRet
);
479 /*************************************************************************
481 *************************************************************************/
483 sal_Bool
SwTxtFrm::PaintEmpty( const SwRect
&rRect
, sal_Bool bCheck
) const
485 ViewShell
*pSh
= GetShell();
486 if( pSh
&& ( pSh
->GetViewOptions()->IsParagraph() || bInitFont
) )
488 bInitFont
= sal_False
;
489 SwTxtFly
aTxtFly( this );
490 aTxtFly
.SetTopRule();
492 if( bCheck
&& aTxtFly
.IsOn() && aTxtFly
.IsAnyObj( aRect
) )
494 else if( pSh
->GetWin() )
497 const SwTxtNode
& rTxtNode
= *GetTxtNode();
498 if ( rTxtNode
.HasSwAttrSet() )
500 const SwAttrSet
*pAttrSet
= &( rTxtNode
.GetSwAttrSet() );
501 pFnt
= new SwFont( pAttrSet
, rTxtNode
.getIDocumentSettingAccess() );
505 SwFontAccess
aFontAccess( &rTxtNode
.GetAnyFmtColl(), pSh
);
506 pFnt
= new SwFont( *aFontAccess
.Get()->GetFont() );
509 const IDocumentRedlineAccess
* pIDRA
= rTxtNode
.getIDocumentRedlineAccess();
510 if( IDocumentRedlineAccess::IsShowChanges( pIDRA
->GetRedlineMode() ) )
512 MSHORT nRedlPos
= pIDRA
->GetRedlinePos( rTxtNode
, USHRT_MAX
);
513 if( MSHRT_MAX
!= nRedlPos
)
515 SwAttrHandler aAttrHandler
;
516 aAttrHandler
.Init( rTxtNode
.GetSwAttrSet(),
517 *rTxtNode
.getIDocumentSettingAccess(), NULL
);
518 SwRedlineItr
aRedln( rTxtNode
, *pFnt
, aAttrHandler
, nRedlPos
, sal_True
);
522 if( pSh
->GetViewOptions()->IsParagraph() && Prt().Height() )
524 if( RTL_TEXTENCODING_SYMBOL
== pFnt
->GetCharSet( SW_LATIN
) &&
525 pFnt
->GetName( SW_LATIN
) != numfunc::GetDefBulletFontname() )
527 pFnt
->SetFamily( FAMILY_DONTKNOW
, SW_LATIN
);
528 pFnt
->SetName( numfunc::GetDefBulletFontname(), SW_LATIN
);
529 pFnt
->SetStyleName( aEmptyStr
, SW_LATIN
);
530 pFnt
->SetCharSet( RTL_TEXTENCODING_SYMBOL
, SW_LATIN
);
532 pFnt
->SetVertical( 0, IsVertical() );
533 SwFrmSwapper
aSwapper( this, sal_True
);
534 SwLayoutModeModifier
aLayoutModeModifier( *pSh
->GetOut() );
535 aLayoutModeModifier
.Modify( IsRightToLeft() );
538 pFnt
->ChgPhysFnt( pSh
, *pSh
->GetOut() );
539 Point aPos
= Frm().Pos() + Prt().Pos();
541 const SvxLRSpaceItem
&rSpace
=
542 GetTxtNode()->GetSwAttrSet().GetLRSpace();
544 if ( rSpace
.GetTxtFirstLineOfst() > 0 )
545 aPos
.X() += rSpace
.GetTxtFirstLineOfst();
550 pClip
= new SwSaveClip( pSh
->GetOut() );
551 pClip
->ChgClip( rRect
);
556 aPos
.Y() += pFnt
->GetAscent( pSh
, *pSh
->GetOut() );
558 if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() &&
561 GETGRID( FindPageFrm() )
564 // center character in grid line
565 aPos
.Y() += ( pGrid
->GetBaseHeight() -
566 pFnt
->GetHeight( pSh
, *pSh
->GetOut() ) ) / 2;
568 if ( ! pGrid
->GetRubyTextBelow() )
569 aPos
.Y() += pGrid
->GetRubyHeight();
573 // Don't show the paragraph mark for collapsed paragraphs, when they are hidden
574 if ( EmptyHeight( ) > 1 )
576 const XubString
aTmp( CH_PAR
);
577 SwDrawTextInfo
aDrawInf( pSh
, *pSh
->GetOut(), 0, aTmp
, 0, 1 );
578 aDrawInf
.SetLeft( rRect
.Left() );
579 aDrawInf
.SetRight( rRect
.Right() );
580 aDrawInf
.SetPos( aPos
);
581 aDrawInf
.SetSpace( 0 );
582 aDrawInf
.SetKanaComp( 0 );
583 aDrawInf
.SetWrong( NULL
);
584 aDrawInf
.SetGrammarCheck( NULL
);
585 aDrawInf
.SetSmartTags( NULL
); // SMARTTAGS
586 aDrawInf
.SetFrm( this );
587 aDrawInf
.SetFont( pFnt
);
588 aDrawInf
.SetSnapToGrid( sal_False
);
590 pFnt
->_DrawText( aDrawInf
);
603 /*************************************************************************
605 *************************************************************************/
607 void SwTxtFrm::Paint( const SwRect
&rRect
) const
611 // --> FME 2004-06-24 #i16816# tagged pdf support
612 ViewShell
*pSh
= GetShell();
614 Num_Info
aNumInfo( *this );
615 SwTaggedPDFHelper
aTaggedPDFHelperNumbering( &aNumInfo
, 0, 0, *pSh
->GetOut() );
617 Frm_Info
aFrmInfo( *this );
618 SwTaggedPDFHelper
aTaggedPDFHelperParagraph( 0, &aFrmInfo
, 0, *pSh
->GetOut() );
622 if( !IsEmpty() || !PaintEmpty( rRect
, sal_True
) )
624 #if OSL_DEBUG_LEVEL > 1
625 const SwTwips nDbgY
= Frm().Top();
631 DBTXTFRM
<< "Paint()" << endl
;
633 if( IsLocked() || IsHiddenNow() || ! Prt().HasArea() )
636 //Kann gut sein, dass mir der IdleCollector mir die gecachten
637 //Informationen entzogen hat.
640 ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
642 // --> FME 2004-10-29 #i29062# pass info that we are currently
644 ((SwTxtFrm
*)this)->GetFormatted( true );
648 PaintEmpty( rRect
, sal_False
);
653 ASSERT( !this, "+SwTxtFrm::Paint: missing format information" );
658 // Waehrend wir painten, wollen wir nicht gestoert werden.
659 // Aber erst hinter dem Format() !
660 SwTxtFrmLocker
aLock((SwTxtFrm
*)this);
662 //Hier wird ggf. nur der Teil des TxtFrm ausgegeben, der sich veraendert
663 //hat und der in dem Bereich liegt, dessen Ausgabe angefordert wurde.
664 //Man kann jetzt auf die Idee kommen, dass der Bereich rRect ausgegeben
665 //werden _muss_ obwohl rRepaint gesetzt ist; in der Tat kann dieses
666 //Problem nicht formal vermieden werden. Gluecklicherweise koennen
667 //wir davon ausgehen, dass rRepaint immer dann leer ist, wenn der Frm
668 //komplett gepainted werden muss.
669 SwTxtLineAccess
aAccess( (SwTxtFrm
*)this );
670 SwParaPortion
*pPara
= aAccess
.GetPara();
672 SwRepaint
&rRepaint
= *(pPara
->GetRepaint());
674 // Das Recycling muss abgeschaltet werden, wenn wir uns im
675 // FlyCntFrm befinden, weil ein DrawRect fuer die Retusche der
676 // Zeile aufgerufen wird.
677 if( rRepaint
.GetOfst() )
679 const SwFlyFrm
*pFly
= FindFlyFrm();
680 if( pFly
&& pFly
->IsFlyInCntFrm() )
681 rRepaint
.SetOfst( 0 );
684 // Hier holen wir uns den String fuer die Ausgabe, besonders
685 // die Laenge ist immer wieder interessant.
688 ASSERT( ! IsSwapped(), "A frame is swapped before Paint" );
689 SwRect
aOldRect( rRect
);
691 SWAP_IF_NOT_SWAPPED( this )
694 SwitchVerticalToHorizontal( (SwRect
&)rRect
);
696 if ( IsRightToLeft() )
697 SwitchRTLtoLTR( (SwRect
&)rRect
);
699 SwTxtPaintInfo
aInf( (SwTxtFrm
*)this, rRect
);
700 aInf
.SetWrongList( ( (SwTxtNode
*)GetTxtNode() )->GetWrong() );
701 aInf
.SetGrammarCheckList( ( (SwTxtNode
*)GetTxtNode() )->GetGrammarCheck() );
702 aInf
.SetSmartTags( ( (SwTxtNode
*)GetTxtNode() )->GetSmartTags() ); // SMARTTAGS
703 aInf
.GetTxtFly()->SetTopRule();
705 SwTxtPainter
aLine( (SwTxtFrm
*)this, &aInf
);
706 // Eine Optimierung, die sich lohnt: wenn kein freifliegender Frame
707 // in unsere Zeile ragt, schaltet sich der SwTxtFly einfach ab:
708 aInf
.GetTxtFly()->Relax();
710 OutputDevice
* pOut
= aInf
.GetOut();
711 const sal_Bool bOnWin
= pSh
->GetWin() != 0;
713 SwSaveClip
aClip( bOnWin
|| IsUndersized() ? pOut
: 0 );
715 // Ausgabeschleife: Fuer jede Zeile ... (die noch zu sehen ist) ...
716 // rRect muss angepasst werden (Top+1, Bottom-1), weil der Iterator
717 // die Zeilen nahtlos aneinanderfuegt.
718 aLine
.TwipsToLine( rRect
.Top() + 1 );
719 long nBottom
= rRect
.Bottom();
721 sal_Bool bNoPrtLine
= 0 == GetMinPrtLine();
724 while ( aLine
.Y() < GetMinPrtLine() && aLine
.Next() )
726 bNoPrtLine
= aLine
.Y() >= GetMinPrtLine();
732 //DBG_LOOP; shadows declaration above.
734 #if OSL_DEBUG_LEVEL > 1
736 DbgLoop
aDbgLoop2( (const void*) this );
739 aLine
.DrawTextLine( rRect
, aClip
, IsUndersized() );
741 } while( aLine
.Next() && aLine
.Y() <= nBottom
);
745 if( aLine
.IsPaintDrop() )
746 aLine
.PaintDropPortion();
748 if( rRepaint
.HasArea() )
752 (SwRect
&)rRect
= aOldRect
;
754 ASSERT( ! IsSwapped(), "A frame is swapped after Paint" );
758 void SwTxtFrm::CriticalLines( const OutputDevice
& rOut
, SwStripes
&rStripes
,
761 ASSERT( ! IsVertical() || ! IsSwapped(),
762 "SwTxtFrm::CriticalLines with swapped frame" );
769 const long nTopMargin
= (this->*fnRect
->fnGetTopMargin
)();
770 SwStripe
aStripe( (Frm().*fnRect
->fnGetTop
)(), nTopMargin
);
773 rStripes
.Insert( aStripe
, rStripes
.Count() );
774 // OD 06.11.2002 #104171#,#103931# - consider vertical layout
776 aStripe
.Y() -= nTopMargin
;
778 // OD 06.11.2002 #104171#,#103931# - *add* top margin to Y.
779 aStripe
.Y() += nTopMargin
;
781 SwLineLayout
* pLay
= GetPara();
784 SwTwips nBase
= aStripe
.GetY() +
785 ( bVert
? -pLay
->GetAscent() : pLay
->GetAscent() );
787 long nLogToPixBase
, nLogToPixSum
, nLogToPixOffs
;
791 nLogToPixBase
= rOut
.LogicToPixel( Point( nBase
, 0 ) ).X();
792 nLogToPixSum
= rOut
.LogicToPixel( Point( nBase
+ nOffs
, 0 ) ).X();
793 nLogToPixOffs
= -rOut
.LogicToPixel( Size( nOffs
, 0 ) ).Width();
797 nLogToPixBase
= rOut
.LogicToPixel( Point( 0, nBase
) ).Y();
798 nLogToPixSum
= rOut
.LogicToPixel( Point( 0, nBase
- nOffs
) ).Y();
799 nLogToPixOffs
= rOut
.LogicToPixel( Size( 0, nOffs
) ).Height();
802 if( nLogToPixBase
!= nLogToPixSum
+ nLogToPixOffs
)
804 aStripe
.Height() = pLay
->GetRealHeight();
805 rStripes
.Insert( aStripe
, rStripes
.Count() );
807 aStripe
.Y() += ( bVert
? -pLay
->GetRealHeight() :
808 pLay
->GetRealHeight() );
809 pLay
= pLay
->GetNext();
812 const long nBottomMargin
= (this->*fnRect
->fnGetBottomMargin
)();
816 aStripe
.Height() = nBottomMargin
;
817 rStripes
.Insert( aStripe
, rStripes
.Count() );
820 else if( 0 != (nFrmHeight
= (Frm().*fnRect
->fnGetHeight
)() ))
821 rStripes
.Insert( SwStripe( (Frm().*fnRect
->fnGetTop
)(), nFrmHeight
),