| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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> |
| |
| #include <fmtline.hxx> |
| #include <lineinfo.hxx> |
| #include <charfmt.hxx> |
| #include "rootfrm.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; |
| sal_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 = getRootFrm()->GetCurrShell(); |
| |
| 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; |
| //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin |
| if ( IsVertLR() ) // mba: the following line was added, but we don't need it for the existing directions; kept for IsVertLR(), but should be checked |
| pRepaint->Chg( ( GetUpper()->Frm() ).Pos() + ( GetUpper()->Prt() ).Pos(), ( GetUpper()->Prt() ).SSize() ); |
| |
| 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 = getRootFrm()->GetCurrShell(); |
| 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(SwRect const& rRect, SwPrintData const*const) const |
| { |
| ResetRepaint(); |
| |
| // --> FME 2004-06-24 #i16816# tagged pdf support |
| ViewShell *pSh = getRootFrm()->GetCurrShell(); |
| |
| 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" ); |
| } |
| } |
| |