update dev300-m58
[ooovba.git] / sw / source / core / text / frmpaint.cxx
blobf93ba6f2f5d74ca29bd3075c425a2c9d47aaa542
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>
42 #include <paratr.hxx>
44 #ifndef _FMTLINE_HXX
45 #include <fmtline.hxx>
46 #endif
47 #ifndef _LINEINFO_HXX
48 #include <lineinfo.hxx>
49 #endif
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
56 #include <txtcfg.hxx>
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>
70 // <--
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[];
78 namespace numfunc
80 extern const String& GetDefBulletFontname();
81 extern bool IsDefBulletFontUserDefined();
83 // <--
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;
95 class SwExtraPainter
97 SwSaveClip aClip;
98 SwRect aRect;
99 const SwTxtFrm* pTxtFrm;
100 ViewShell *pSh;
101 SwFont* pFnt;
102 const SwLineNumberInfo &rLineInf;
103 SwTwips nX;
104 SwTwips nRedX;
105 ULONG nLineNr;
106 MSHORT nDivider;
107 sal_Bool bGoLeft;
108 sal_Bool bLineNum;
109 inline sal_Bool IsClipChg() { return aClip.IsChg(); }
110 public:
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;
140 if( bLineNum )
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() );
154 pFnt->Invalidate();
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() )
163 nVirtPageNum = 1;
164 ePos = ePos == LINENUMBER_POS_INSIDE ?
165 LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
167 else
169 nVirtPageNum = 2;
170 ePos = ePos == LINENUMBER_POS_OUTSIDE ?
171 LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
174 if( LINENUMBER_POS_LEFT == ePos )
176 bGoLeft = sal_True;
177 nX -= rLineInf.GetPosFromLeft();
178 if( nX < aRect.Left() )
179 bLineNum = sal_False;
181 else
183 bGoLeft = 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 )
193 if( !nVirtPageNum )
194 nVirtPageNum = pFrm->FindPageFrm()->OnRightPage() ? 1 : 2;
195 if( nVirtPageNum % 2 )
196 eHor = eHor == text::HoriOrientation::INSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT;
197 else
198 eHor = eHor == text::HoriOrientation::OUTSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT;
200 const SwFrm* pTmpFrm = pFrm->FindTabFrm();
201 if( !pTmpFrm )
202 pTmpFrm = pFrm;
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;
235 SwFont* pTmpFnt;
236 if( bTooBig )
238 pTmpFnt = new SwFont( *GetFont() );
239 if( nMax >= 20 )
241 nMax *= 17;
242 nMax /= 20;
244 pTmpFnt->SetSize( Size( 0, nMax ), pTmpFnt->GetActual() );
246 else
247 pTmpFnt = GetFont();
248 Point aTmpPos( nX, nY );
249 aTmpPos.Y() += nAsc;
250 sal_Bool bPaint = sal_True;
251 if( !IsClipChg() )
253 Size aSize = pTmpFnt->_GetTxtSize( aDrawInf );
254 if( bGoLeft )
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() )
259 ), aSize );
260 if( !aRect.IsInside( aRct ) )
262 if( aRct.Intersection( aRect ).IsEmpty() )
263 bPaint = sal_False;
264 else
265 aClip.ChgClip( aRect, pTxtFrm );
268 else if( bGoLeft )
269 aTmpPos.X() -= pTmpFnt->_GetTxtSize( aDrawInf ).Width();
270 aDrawInf.SetPos( aTmpPos );
271 if( bPaint )
272 pTmpFnt->_DrawText( aDrawInf );
274 if( bTooBig )
275 delete pTmpFnt;
276 if( bRed )
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 );
289 if( !IsClipChg() )
291 SwRect aRct( aStart, aEnd );
292 if( !aRect.IsInside( aRct ) )
294 if( aRct.Intersection( aRect ).IsEmpty() )
295 return;
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() )
315 return;
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() )
330 return;
331 ViewShell *pSh = GetShell();
333 SWAP_IF_NOT_SWAPPED( this )
334 SwRect rOldRect( rRect );
336 if ( IsVertical() )
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() );
344 // <--
346 SwExtraPainter aExtra( this, pSh, rLineInf, rRect, eHor, bLineNum );
348 if( HasPara() )
350 SwTxtFrmLocker aLock((SwTxtFrm*)this);
352 SwTxtLineAccess aAccess( (SwTxtFrm*)this );
353 aAccess.GetPara();
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() ) )
367 aExtra.IncLineNr();
368 if( !aLine.Next() )
370 (SwRect&)rRect = rOldRect;
371 UNDO_SWAP( this )
372 return;
376 long nBottom = rRect.Bottom();
378 sal_Bool bNoPrtLine = 0 == GetMinPrtLine();
379 if( !bNoPrtLine )
381 while ( aLine.Y() < GetMinPrtLine() )
383 if( ( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
384 && !aLine.GetCurr()->IsDummy() )
385 aExtra.IncLineNr();
386 if( !aLine.Next() )
387 break;
389 bNoPrtLine = aLine.Y() >= GetMinPrtLine();
391 if( bNoPrtLine )
395 if( bNoDummy || !aLine.GetCurr()->IsDummy() )
397 sal_Bool bRed = bRedLine && aLine.GetCurr()->HasRedline();
398 if( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
400 if( bLineNum &&
401 ( aExtra.HasNumber() || aExtra.HasDivider() ) )
403 KSHORT nTmpHeight, nTmpAscent;
404 aLine.CalcAscentAndHeight( nTmpAscent, nTmpHeight );
405 aExtra.PaintExtra( aLine.Y(), nTmpAscent,
406 nTmpHeight, bRed );
407 bRed = sal_False;
409 aExtra.IncLineNr();
411 if( bRed )
412 aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight() );
414 } while( aLine.Next() && aLine.Y() <= nBottom );
417 else
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 );
427 else if( bRedLine )
428 aExtra.PaintRedline( Frm().Top()+Prt().Top(), Prt().Height() );
431 (SwRect&)rRect = rOldRect;
432 UNDO_SWAP( this )
436 /*************************************************************************
437 * SwTxtFrm::Paint()
438 *************************************************************************/
440 SwRect SwTxtFrm::Paint()
442 #if OSL_DEBUG_LEVEL > 1
443 const SwTwips nDbgY = Frm().Top();
444 (void)nDbgY;
445 #endif
447 // finger layout
448 ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
450 SwRect aRet( Prt() );
451 if ( IsEmpty() || !HasPara() )
452 aRet += Frm().Pos();
453 else
455 // AMA: Wir liefern jetzt mal das richtige Repaintrechteck zurueck,
456 // d.h. als linken Rand den berechneten PaintOfst!
457 SwRepaint *pRepaint = GetPara()->GetRepaint();
458 long l;
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 );
466 aRet = *pRepaint;
468 if ( IsRightToLeft() )
469 SwitchLTRtoRTL( aRet );
471 if ( IsVertical() )
472 SwitchHorizontalToVertical( aRet );
474 ResetRepaint();
476 return aRet;
479 /*************************************************************************
480 * SwTxtFrm::Paint()
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();
491 SwRect aRect;
492 if( bCheck && aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
493 return sal_False;
494 else if( pSh->GetWin() )
496 SwFont *pFnt;
497 const SwTxtNode& rTxtNode = *GetTxtNode();
498 if ( rTxtNode.HasSwAttrSet() )
500 const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() );
501 pFnt = new SwFont( pAttrSet, rTxtNode.getIDocumentSettingAccess() );
503 else
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() );
537 pFnt->Invalidate();
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();
547 SwSaveClip *pClip;
548 if( IsUndersized() )
550 pClip = new SwSaveClip( pSh->GetOut() );
551 pClip->ChgClip( rRect );
553 else
554 pClip = NULL;
556 aPos.Y() += pFnt->GetAscent( pSh, *pSh->GetOut() );
558 if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() &&
559 IsInDocBody() )
561 GETGRID( FindPageFrm() )
562 if ( pGrid )
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 );
592 delete pClip;
594 delete pFnt;
595 return sal_True;
598 else
599 return sal_True;
600 return sal_False;
603 /*************************************************************************
604 * SwTxtFrm::Paint()
605 *************************************************************************/
607 void SwTxtFrm::Paint( const SwRect &rRect ) const
609 ResetRepaint();
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() );
619 // <--
621 DBG_LOOP_RESET;
622 if( !IsEmpty() || !PaintEmpty( rRect, sal_True ) )
624 #if OSL_DEBUG_LEVEL > 1
625 const SwTwips nDbgY = Frm().Top();
626 (void)nDbgY;
627 #endif
629 #ifdef DBGTXT
630 if( IsDbg( this ) )
631 DBTXTFRM << "Paint()" << endl;
632 #endif
633 if( IsLocked() || IsHiddenNow() || ! Prt().HasArea() )
634 return;
636 //Kann gut sein, dass mir der IdleCollector mir die gecachten
637 //Informationen entzogen hat.
638 if( !HasPara() )
640 ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
642 // --> FME 2004-10-29 #i29062# pass info that we are currently
643 // painting.
644 ((SwTxtFrm*)this)->GetFormatted( true );
645 // <--
646 if( IsEmpty() )
648 PaintEmpty( rRect, sal_False );
649 return;
651 if( !HasPara() )
653 ASSERT( !this, "+SwTxtFrm::Paint: missing format information" );
654 return;
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.
687 // Rectangle
688 ASSERT( ! IsSwapped(), "A frame is swapped before Paint" );
689 SwRect aOldRect( rRect );
691 SWAP_IF_NOT_SWAPPED( this )
693 if ( IsVertical() )
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();
722 if( !bNoPrtLine )
724 while ( aLine.Y() < GetMinPrtLine() && aLine.Next() )
726 bNoPrtLine = aLine.Y() >= GetMinPrtLine();
728 if( bNoPrtLine )
732 //DBG_LOOP; shadows declaration above.
733 //resolved into:
734 #if OSL_DEBUG_LEVEL > 1
735 #ifndef PRODUCT
736 DbgLoop aDbgLoop2( (const void*) this );
737 #endif
738 #endif
739 aLine.DrawTextLine( rRect, aClip, IsUndersized() );
741 } while( aLine.Next() && aLine.Y() <= nBottom );
744 // Einmal reicht:
745 if( aLine.IsPaintDrop() )
746 aLine.PaintDropPortion();
748 if( rRepaint.HasArea() )
749 rRepaint.Clear();
751 UNDO_SWAP( this )
752 (SwRect&)rRect = aOldRect;
754 ASSERT( ! IsSwapped(), "A frame is swapped after Paint" );
758 void SwTxtFrm::CriticalLines( const OutputDevice& rOut, SwStripes &rStripes,
759 long nOffs)
761 ASSERT( ! IsVertical() || ! IsSwapped(),
762 "SwTxtFrm::CriticalLines with swapped frame" );
763 SWRECTFN( this )
764 long nFrmHeight;
766 GetFormatted();
767 if( HasPara() )
769 const long nTopMargin = (this->*fnRect->fnGetTopMargin)();
770 SwStripe aStripe( (Frm().*fnRect->fnGetTop)(), nTopMargin );
771 if ( nTopMargin )
773 rStripes.Insert( aStripe, rStripes.Count() );
774 // OD 06.11.2002 #104171#,#103931# - consider vertical layout
775 if ( bVert )
776 aStripe.Y() -= nTopMargin;
777 else
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;
789 if ( bVert )
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();
795 else
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();
810 } while( pLay );
812 const long nBottomMargin = (this->*fnRect->fnGetBottomMargin)();
813 if( nBottomMargin )
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 ),
822 rStripes.Count() );