diff options
Diffstat (limited to 'sw/source/core/text/frmpaint.cxx')
-rw-r--r-- | sw/source/core/text/frmpaint.cxx | 749 |
1 files changed, 749 insertions, 0 deletions
diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx new file mode 100644 index 000000000000..443900e1942c --- /dev/null +++ b/sw/source/core/text/frmpaint.cxx @@ -0,0 +1,749 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <com/sun/star/text/HoriOrientation.hpp> +#include <hintids.hxx> +#include <vcl/sound.hxx> +#include <tools/shl.hxx> // SW_MOD +#include <editeng/pgrditem.hxx> +#include <editeng/lrspitem.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> +#include <paratr.hxx> + +#ifndef _FMTLINE_HXX +#include <fmtline.hxx> +#endif +#ifndef _LINEINFO_HXX +#include <lineinfo.hxx> +#endif +#include <charfmt.hxx> +#include <pagefrm.hxx> +#include <viewsh.hxx> // ViewShell +#include <viewimp.hxx> // SwViewImp +#include <viewopt.hxx> // SwViewOption +#include <frmtool.hxx> // DrawGraphic +#include <txtcfg.hxx> +#include <txtfrm.hxx> // SwTxtFrm +#include <itrpaint.hxx> // SwTxtPainter +#include <txtpaint.hxx> // SwSaveClip +#include <txtcache.hxx> // SwTxtLineAccess +#include <flyfrm.hxx> // SwFlyFrm +#include <redlnitr.hxx> // SwRedlineItr +#include <swmodule.hxx> // SW_MOD +#include <tabfrm.hxx> // SwTabFrm (Redlining) +#include <SwGrammarMarkUp.hxx> + +// --> FME 2004-06-08 #i12836# enhanced pdf export +#include <EnhancedPDFExportHelper.hxx> +// <-- + +#include <IDocumentStylePoolAccess.hxx> +#include <IDocumentLineNumberAccess.hxx> + +// --> OD 2006-06-27 #b6440955# +// variable moved to class <numfunc:GetDefBulletConfig> +//extern const sal_Char __FAR_DATA sBulletFntName[]; +namespace numfunc +{ + extern const String& GetDefBulletFontname(); + extern bool IsDefBulletFontUserDefined(); +} +// <-- + + +#define REDLINE_DISTANCE 567/4 +#define REDLINE_MINDIST 567/10 + +using namespace ::com::sun::star; + +//////////////////////////////////////////////////////////// + +sal_Bool bInitFont = sal_True; + +class SwExtraPainter +{ + SwSaveClip aClip; + SwRect aRect; + const SwTxtFrm* pTxtFrm; + ViewShell *pSh; + SwFont* pFnt; + const SwLineNumberInfo &rLineInf; + SwTwips nX; + SwTwips nRedX; + ULONG nLineNr; + MSHORT nDivider; + sal_Bool bGoLeft; + sal_Bool bLineNum; + inline sal_Bool IsClipChg() { return aClip.IsChg(); } +public: + SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh, + const SwLineNumberInfo &rLnInf, const SwRect &rRct, + sal_Int16 eHor, sal_Bool bLnNm ); + ~SwExtraPainter() { delete pFnt; } + inline SwFont* GetFont() const { return pFnt; } + inline void IncLineNr() { ++nLineNr; } + inline sal_Bool HasNumber() { return !( nLineNr % rLineInf.GetCountBy() ); } + inline sal_Bool HasDivider() { if( !nDivider ) return sal_False; + return !(nLineNr % rLineInf.GetDividerCountBy()); } + + void PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed ); + void PaintRedline( SwTwips nY, long nMax ); +}; + + +SwExtraPainter::SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh, + const SwLineNumberInfo &rLnInf, const SwRect &rRct, + sal_Int16 eHor, sal_Bool bLnNm ) + : aClip( pVwSh->GetWin() || pFrm->IsUndersized() ? pVwSh->GetOut() : 0 ), + aRect( rRct ), pTxtFrm( pFrm ), pSh( pVwSh ), pFnt( 0 ), rLineInf( rLnInf ), + nLineNr( 1L ), bLineNum( bLnNm ) +{ + if( pFrm->IsUndersized() ) + { + SwTwips nBottom = pFrm->Frm().Bottom(); + if( aRect.Bottom() > nBottom ) + aRect.Bottom( nBottom ); + } + MSHORT nVirtPageNum = 0; + if( bLineNum ) + { /* initialisiert die Member, die bei Zeilennumerierung notwendig sind: + + nDivider, wie oft ist ein Teilerstring gewuenscht, 0 == nie; + nX, X-Position der Zeilennummern; + pFnt, der Font der Zeilennummern; + nLineNr, die erste Zeilennummer; + bLineNum wird ggf.wieder auf sal_False gesetzt, wenn die Numerierung sich + komplett ausserhalb des Paint-Rechtecks aufhaelt. */ + nDivider = rLineInf.GetDivider().Len() ? rLineInf.GetDividerCountBy() : 0; + nX = pFrm->Frm().Left(); + SwCharFmt* pFmt = rLineInf.GetCharFmt( const_cast<IDocumentStylePoolAccess&>(*pFrm->GetNode()->getIDocumentStylePoolAccess()) ); + ASSERT( pFmt, "PaintExtraData without CharFmt" ); + pFnt = new SwFont( &pFmt->GetAttrSet(), pFrm->GetTxtNode()->getIDocumentSettingAccess() ); + pFnt->Invalidate(); + pFnt->ChgPhysFnt( pSh, *pSh->GetOut() ); + pFnt->SetVertical( 0, pFrm->IsVertical() ); + nLineNr += pFrm->GetAllLines() - pFrm->GetThisLines(); + LineNumberPosition ePos = rLineInf.GetPos(); + if( ePos != LINENUMBER_POS_LEFT && ePos != LINENUMBER_POS_RIGHT ) + { + if( pFrm->FindPageFrm()->OnRightPage() ) + { + nVirtPageNum = 1; + ePos = ePos == LINENUMBER_POS_INSIDE ? + LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT; + } + else + { + nVirtPageNum = 2; + ePos = ePos == LINENUMBER_POS_OUTSIDE ? + LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT; + } + } + if( LINENUMBER_POS_LEFT == ePos ) + { + bGoLeft = sal_True; + nX -= rLineInf.GetPosFromLeft(); + if( nX < aRect.Left() ) + bLineNum = sal_False; + } + else + { + bGoLeft = sal_False; + nX += pFrm->Frm().Width() + rLineInf.GetPosFromLeft(); + if( nX > aRect.Right() ) + bLineNum = sal_False; + } + } + if( eHor != text::HoriOrientation::NONE ) + { + if( text::HoriOrientation::INSIDE == eHor || text::HoriOrientation::OUTSIDE == eHor ) + { + if( !nVirtPageNum ) + nVirtPageNum = pFrm->FindPageFrm()->OnRightPage() ? 1 : 2; + if( nVirtPageNum % 2 ) + eHor = eHor == text::HoriOrientation::INSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT; + else + eHor = eHor == text::HoriOrientation::OUTSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT; + } + const SwFrm* pTmpFrm = pFrm->FindTabFrm(); + if( !pTmpFrm ) + pTmpFrm = pFrm; + nRedX = text::HoriOrientation::LEFT == eHor ? pTmpFrm->Frm().Left() - REDLINE_DISTANCE : + pTmpFrm->Frm().Right() + REDLINE_DISTANCE; + } +} + +/************************************************************************* + * SwExtraPainter::PaintExtra() + **************************************************************************/ + +void SwExtraPainter::PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed ) +{ + //Zeilennummer ist staerker als der Teiler + const XubString aTmp( HasNumber() ? rLineInf.GetNumType().GetNumStr( nLineNr ) + : rLineInf.GetDivider() ); + + // get script type of line numbering: + pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmp, 0 ) ); + + SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), 0, aTmp, 0, aTmp.Len() ); + aDrawInf.SetSpace( 0 ); + aDrawInf.SetWrong( NULL ); + aDrawInf.SetGrammarCheck( NULL ); + aDrawInf.SetSmartTags( NULL ); // SMARTTAGS + aDrawInf.SetLeft( 0 ); + aDrawInf.SetRight( LONG_MAX ); + aDrawInf.SetFrm( pTxtFrm ); + aDrawInf.SetFont( pFnt ); + aDrawInf.SetSnapToGrid( sal_False ); + aDrawInf.SetIgnoreFrmRTL( sal_True ); + + sal_Bool bTooBig = pFnt->GetSize( pFnt->GetActual() ).Height() > nMax && + pFnt->GetHeight( pSh, *pSh->GetOut() ) > nMax; + SwFont* pTmpFnt; + if( bTooBig ) + { + pTmpFnt = new SwFont( *GetFont() ); + if( nMax >= 20 ) + { + nMax *= 17; + nMax /= 20; + } + pTmpFnt->SetSize( Size( 0, nMax ), pTmpFnt->GetActual() ); + } + else + pTmpFnt = GetFont(); + Point aTmpPos( nX, nY ); + aTmpPos.Y() += nAsc; + sal_Bool bPaint = sal_True; + if( !IsClipChg() ) + { + Size aSize = pTmpFnt->_GetTxtSize( aDrawInf ); + if( bGoLeft ) + aTmpPos.X() -= aSize.Width(); + // calculate rectangle containing the line number + SwRect aRct( Point( aTmpPos.X(), + aTmpPos.Y() - pTmpFnt->GetAscent( pSh, *pSh->GetOut() ) + ), aSize ); + if( !aRect.IsInside( aRct ) ) + { + if( aRct.Intersection( aRect ).IsEmpty() ) + bPaint = sal_False; + else + aClip.ChgClip( aRect, pTxtFrm ); + } + } + else if( bGoLeft ) + aTmpPos.X() -= pTmpFnt->_GetTxtSize( aDrawInf ).Width(); + aDrawInf.SetPos( aTmpPos ); + if( bPaint ) + pTmpFnt->_DrawText( aDrawInf ); + + if( bTooBig ) + delete pTmpFnt; + if( bRed ) + { + long nDiff = bGoLeft ? nRedX - nX : nX - nRedX; + if( nDiff > REDLINE_MINDIST ) + PaintRedline( nY, nMax ); + } +} + +void SwExtraPainter::PaintRedline( SwTwips nY, long nMax ) +{ + Point aStart( nRedX, nY ); + Point aEnd( nRedX, nY + nMax ); + + if( !IsClipChg() ) + { + SwRect aRct( aStart, aEnd ); + if( !aRect.IsInside( aRct ) ) + { + if( aRct.Intersection( aRect ).IsEmpty() ) + return; + aClip.ChgClip( aRect, pTxtFrm ); + } + } + const Color aOldCol( pSh->GetOut()->GetLineColor() ); + pSh->GetOut()->SetLineColor( SW_MOD()->GetRedlineMarkColor() ); + + if ( pTxtFrm->IsVertical() ) + { + pTxtFrm->SwitchHorizontalToVertical( aStart ); + pTxtFrm->SwitchHorizontalToVertical( aEnd ); + } + + pSh->GetOut()->DrawLine( aStart, aEnd ); + pSh->GetOut()->SetLineColor( aOldCol ); +} + +void SwTxtFrm::PaintExtraData( const SwRect &rRect ) const +{ + if( Frm().Top() > rRect.Bottom() || Frm().Bottom() < rRect.Top() ) + return; + + const SwTxtNode& rTxtNode = *GetTxtNode(); + const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess(); + const SwLineNumberInfo &rLineInf = rTxtNode.getIDocumentLineNumberAccess()->GetLineNumberInfo(); + const SwFmtLineNumber &rLineNum = GetAttrSet()->GetLineNumber(); + sal_Bool bLineNum = !IsInTab() && rLineInf.IsPaintLineNumbers() && + ( !IsInFly() || rLineInf.IsCountInFlys() ) && rLineNum.IsCount(); + sal_Int16 eHor = (sal_Int16)SW_MOD()->GetRedlineMarkPos(); + if( eHor != text::HoriOrientation::NONE && !IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) ) + eHor = text::HoriOrientation::NONE; + sal_Bool bRedLine = eHor != text::HoriOrientation::NONE; + if ( bLineNum || bRedLine ) + { + if( IsLocked() || IsHiddenNow() || !Prt().Height() ) + return; + ViewShell *pSh = GetShell(); + + SWAP_IF_NOT_SWAPPED( this ) + SwRect rOldRect( rRect ); + + if ( IsVertical() ) + SwitchVerticalToHorizontal( (SwRect&)rRect ); + + SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() ); + aLayoutModeModifier.Modify( sal_False ); + + // --> FME 2004-06-24 #i16816# tagged pdf support + SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); + // <-- + + SwExtraPainter aExtra( this, pSh, rLineInf, rRect, eHor, bLineNum ); + + if( HasPara() ) + { + SwTxtFrmLocker aLock((SwTxtFrm*)this); + + SwTxtLineAccess aAccess( (SwTxtFrm*)this ); + aAccess.GetPara(); + + SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect ); + + aLayoutModeModifier.Modify( sal_False ); + + SwTxtPainter aLine( (SwTxtFrm*)this, &aInf ); + sal_Bool bNoDummy = !aLine.GetNext(); // Nur eine Leerzeile! + + while( aLine.Y() + aLine.GetLineHeight() <= rRect.Top() ) + { + if( !aLine.GetCurr()->IsDummy() && + ( rLineInf.IsCountBlankLines() || + aLine.GetCurr()->HasCntnt() ) ) + aExtra.IncLineNr(); + if( !aLine.Next() ) + { + (SwRect&)rRect = rOldRect; + UNDO_SWAP( this ) + return; + } + } + + long nBottom = rRect.Bottom(); + + sal_Bool bNoPrtLine = 0 == GetMinPrtLine(); + if( !bNoPrtLine ) + { + while ( aLine.Y() < GetMinPrtLine() ) + { + if( ( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() ) + && !aLine.GetCurr()->IsDummy() ) + aExtra.IncLineNr(); + if( !aLine.Next() ) + break; + } + bNoPrtLine = aLine.Y() >= GetMinPrtLine(); + } + if( bNoPrtLine ) + { + do + { + if( bNoDummy || !aLine.GetCurr()->IsDummy() ) + { + sal_Bool bRed = bRedLine && aLine.GetCurr()->HasRedline(); + if( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() ) + { + if( bLineNum && + ( aExtra.HasNumber() || aExtra.HasDivider() ) ) + { + KSHORT nTmpHeight, nTmpAscent; + aLine.CalcAscentAndHeight( nTmpAscent, nTmpHeight ); + aExtra.PaintExtra( aLine.Y(), nTmpAscent, + nTmpHeight, bRed ); + bRed = sal_False; + } + aExtra.IncLineNr(); + } + if( bRed ) + aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight() ); + } + } while( aLine.Next() && aLine.Y() <= nBottom ); + } + } + else + { + bRedLine &= ( MSHRT_MAX!= pIDRA->GetRedlinePos(rTxtNode, USHRT_MAX) ); + + if( bLineNum && rLineInf.IsCountBlankLines() && + ( aExtra.HasNumber() || aExtra.HasDivider() ) ) + { + aExtra.PaintExtra( Frm().Top()+Prt().Top(), aExtra.GetFont() + ->GetAscent( pSh, *pSh->GetOut() ), Prt().Height(), bRedLine ); + } + else if( bRedLine ) + aExtra.PaintRedline( Frm().Top()+Prt().Top(), Prt().Height() ); + } + + (SwRect&)rRect = rOldRect; + UNDO_SWAP( this ) + } +} + +/************************************************************************* + * SwTxtFrm::Paint() + *************************************************************************/ + +SwRect SwTxtFrm::Paint() +{ +#if OSL_DEBUG_LEVEL > 1 + const SwTwips nDbgY = Frm().Top(); + (void)nDbgY; +#endif + + // finger layout + ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" ); + + SwRect aRet( Prt() ); + if ( IsEmpty() || !HasPara() ) + aRet += Frm().Pos(); + else + { + // AMA: Wir liefern jetzt mal das richtige Repaintrechteck zurueck, + // d.h. als linken Rand den berechneten PaintOfst! + SwRepaint *pRepaint = GetPara()->GetRepaint(); + long l; + if( pRepaint->GetOfst() ) + pRepaint->Left( pRepaint->GetOfst() ); + + l = pRepaint->GetRightOfst(); + if( l && ( pRepaint->GetOfst() || l > pRepaint->Right() ) ) + pRepaint->Right( l ); + pRepaint->SetOfst( 0 ); + aRet = *pRepaint; + + if ( IsRightToLeft() ) + SwitchLTRtoRTL( aRet ); + + if ( IsVertical() ) + SwitchHorizontalToVertical( aRet ); + } + ResetRepaint(); + + return aRet; +} + +/************************************************************************* + * SwTxtFrm::Paint() + *************************************************************************/ + +sal_Bool SwTxtFrm::PaintEmpty( const SwRect &rRect, sal_Bool bCheck ) const +{ + ViewShell *pSh = GetShell(); + if( pSh && ( pSh->GetViewOptions()->IsParagraph() || bInitFont ) ) + { + bInitFont = sal_False; + SwTxtFly aTxtFly( this ); + aTxtFly.SetTopRule(); + SwRect aRect; + if( bCheck && aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) ) + return sal_False; + else if( pSh->GetWin() ) + { + SwFont *pFnt; + const SwTxtNode& rTxtNode = *GetTxtNode(); + if ( rTxtNode.HasSwAttrSet() ) + { + const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() ); + pFnt = new SwFont( pAttrSet, rTxtNode.getIDocumentSettingAccess() ); + } + else + { + SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh ); + pFnt = new SwFont( *aFontAccess.Get()->GetFont() ); + } + + const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess(); + if( IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) ) + { + MSHORT nRedlPos = pIDRA->GetRedlinePos( rTxtNode, USHRT_MAX ); + if( MSHRT_MAX != nRedlPos ) + { + SwAttrHandler aAttrHandler; + aAttrHandler.Init( rTxtNode.GetSwAttrSet(), + *rTxtNode.getIDocumentSettingAccess(), NULL ); + SwRedlineItr aRedln( rTxtNode, *pFnt, aAttrHandler, nRedlPos, sal_True ); + } + } + + if( pSh->GetViewOptions()->IsParagraph() && Prt().Height() ) + { + if( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet( SW_LATIN ) && + pFnt->GetName( SW_LATIN ) != numfunc::GetDefBulletFontname() ) + { + pFnt->SetFamily( FAMILY_DONTKNOW, SW_LATIN ); + pFnt->SetName( numfunc::GetDefBulletFontname(), SW_LATIN ); + pFnt->SetStyleName( aEmptyStr, SW_LATIN ); + pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, SW_LATIN ); + } + pFnt->SetVertical( 0, IsVertical() ); + SwFrmSwapper aSwapper( this, sal_True ); + SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() ); + aLayoutModeModifier.Modify( IsRightToLeft() ); + + pFnt->Invalidate(); + pFnt->ChgPhysFnt( pSh, *pSh->GetOut() ); + Point aPos = Frm().Pos() + Prt().Pos(); + + const SvxLRSpaceItem &rSpace = + GetTxtNode()->GetSwAttrSet().GetLRSpace(); + + if ( rSpace.GetTxtFirstLineOfst() > 0 ) + aPos.X() += rSpace.GetTxtFirstLineOfst(); + + SwSaveClip *pClip; + if( IsUndersized() ) + { + pClip = new SwSaveClip( pSh->GetOut() ); + pClip->ChgClip( rRect ); + } + else + pClip = NULL; + + aPos.Y() += pFnt->GetAscent( pSh, *pSh->GetOut() ); + + if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() && + IsInDocBody() ) + { + GETGRID( FindPageFrm() ) + if ( pGrid ) + { + // center character in grid line + aPos.Y() += ( pGrid->GetBaseHeight() - + pFnt->GetHeight( pSh, *pSh->GetOut() ) ) / 2; + + if ( ! pGrid->GetRubyTextBelow() ) + aPos.Y() += pGrid->GetRubyHeight(); + } + } + + const XubString aTmp( CH_PAR ); + SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), 0, aTmp, 0, 1 ); + aDrawInf.SetLeft( rRect.Left() ); + aDrawInf.SetRight( rRect.Right() ); + aDrawInf.SetPos( aPos ); + aDrawInf.SetSpace( 0 ); + aDrawInf.SetKanaComp( 0 ); + aDrawInf.SetWrong( NULL ); + aDrawInf.SetGrammarCheck( NULL ); + aDrawInf.SetSmartTags( NULL ); // SMARTTAGS + aDrawInf.SetFrm( this ); + aDrawInf.SetFont( pFnt ); + aDrawInf.SetSnapToGrid( sal_False ); + + pFnt->_DrawText( aDrawInf ); + delete pClip; + } + delete pFnt; + return sal_True; + } + } + else + return sal_True; + return sal_False; +} + +/************************************************************************* + * SwTxtFrm::Paint() + *************************************************************************/ + +void SwTxtFrm::Paint( const SwRect &rRect, const SwPrtOptions * /*pPrintData*/ ) const +{ + ResetRepaint(); + + // --> FME 2004-06-24 #i16816# tagged pdf support + ViewShell *pSh = GetShell(); + + Num_Info aNumInfo( *this ); + SwTaggedPDFHelper aTaggedPDFHelperNumbering( &aNumInfo, 0, 0, *pSh->GetOut() ); + + Frm_Info aFrmInfo( *this ); + SwTaggedPDFHelper aTaggedPDFHelperParagraph( 0, &aFrmInfo, 0, *pSh->GetOut() ); + // <-- + + DBG_LOOP_RESET; + if( !IsEmpty() || !PaintEmpty( rRect, sal_True ) ) + { +#if OSL_DEBUG_LEVEL > 1 + const SwTwips nDbgY = Frm().Top(); + (void)nDbgY; +#endif + +#ifdef DBGTXT + if( IsDbg( this ) ) + DBTXTFRM << "Paint()" << endl; +#endif + if( IsLocked() || IsHiddenNow() || ! Prt().HasArea() ) + return; + + //Kann gut sein, dass mir der IdleCollector mir die gecachten + //Informationen entzogen hat. + if( !HasPara() ) + { + ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" ); + + // --> FME 2004-10-29 #i29062# pass info that we are currently + // painting. + ((SwTxtFrm*)this)->GetFormatted( true ); + // <-- + if( IsEmpty() ) + { + PaintEmpty( rRect, sal_False ); + return; + } + if( !HasPara() ) + { + ASSERT( !this, "+SwTxtFrm::Paint: missing format information" ); + return; + } + } + + // Waehrend wir painten, wollen wir nicht gestoert werden. + // Aber erst hinter dem Format() ! + SwTxtFrmLocker aLock((SwTxtFrm*)this); + + //Hier wird ggf. nur der Teil des TxtFrm ausgegeben, der sich veraendert + //hat und der in dem Bereich liegt, dessen Ausgabe angefordert wurde. + //Man kann jetzt auf die Idee kommen, dass der Bereich rRect ausgegeben + //werden _muss_ obwohl rRepaint gesetzt ist; in der Tat kann dieses + //Problem nicht formal vermieden werden. Gluecklicherweise koennen + //wir davon ausgehen, dass rRepaint immer dann leer ist, wenn der Frm + //komplett gepainted werden muss. + SwTxtLineAccess aAccess( (SwTxtFrm*)this ); + SwParaPortion *pPara = aAccess.GetPara(); + + SwRepaint &rRepaint = *(pPara->GetRepaint()); + + // Das Recycling muss abgeschaltet werden, wenn wir uns im + // FlyCntFrm befinden, weil ein DrawRect fuer die Retusche der + // Zeile aufgerufen wird. + if( rRepaint.GetOfst() ) + { + const SwFlyFrm *pFly = FindFlyFrm(); + if( pFly && pFly->IsFlyInCntFrm() ) + rRepaint.SetOfst( 0 ); + } + + // Hier holen wir uns den String fuer die Ausgabe, besonders + // die Laenge ist immer wieder interessant. + + // Rectangle + ASSERT( ! IsSwapped(), "A frame is swapped before Paint" ); + SwRect aOldRect( rRect ); + + SWAP_IF_NOT_SWAPPED( this ) + + if ( IsVertical() ) + SwitchVerticalToHorizontal( (SwRect&)rRect ); + + if ( IsRightToLeft() ) + SwitchRTLtoLTR( (SwRect&)rRect ); + + SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect ); + aInf.SetWrongList( ( (SwTxtNode*)GetTxtNode() )->GetWrong() ); + aInf.SetGrammarCheckList( ( (SwTxtNode*)GetTxtNode() )->GetGrammarCheck() ); + aInf.SetSmartTags( ( (SwTxtNode*)GetTxtNode() )->GetSmartTags() ); // SMARTTAGS + aInf.GetTxtFly()->SetTopRule(); + + SwTxtPainter aLine( (SwTxtFrm*)this, &aInf ); + // Eine Optimierung, die sich lohnt: wenn kein freifliegender Frame + // in unsere Zeile ragt, schaltet sich der SwTxtFly einfach ab: + aInf.GetTxtFly()->Relax(); + + OutputDevice* pOut = aInf.GetOut(); + const sal_Bool bOnWin = pSh->GetWin() != 0; + + SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : 0 ); + + // Ausgabeschleife: Fuer jede Zeile ... (die noch zu sehen ist) ... + // rRect muss angepasst werden (Top+1, Bottom-1), weil der Iterator + // die Zeilen nahtlos aneinanderfuegt. + aLine.TwipsToLine( rRect.Top() + 1 ); + long nBottom = rRect.Bottom(); + + sal_Bool bNoPrtLine = 0 == GetMinPrtLine(); + if( !bNoPrtLine ) + { + while ( aLine.Y() < GetMinPrtLine() && aLine.Next() ) + ; + bNoPrtLine = aLine.Y() >= GetMinPrtLine(); + } + if( bNoPrtLine ) + { + do + { + //DBG_LOOP; shadows declaration above. + //resolved into: +#if OSL_DEBUG_LEVEL > 1 +#ifdef DBG_UTIL + DbgLoop aDbgLoop2( (const void*) this ); +#endif +#endif + aLine.DrawTextLine( rRect, aClip, IsUndersized() ); + + } while( aLine.Next() && aLine.Y() <= nBottom ); + } + + // Einmal reicht: + if( aLine.IsPaintDrop() ) + aLine.PaintDropPortion(); + + if( rRepaint.HasArea() ) + rRepaint.Clear(); + + UNDO_SWAP( this ) + (SwRect&)rRect = aOldRect; + + ASSERT( ! IsSwapped(), "A frame is swapped after Paint" ); + } +} + |