1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 #include <com/sun/star/text/HoriOrientation.hpp> 28 #include <hintids.hxx> 29 #include <vcl/sound.hxx> 30 #include <tools/shl.hxx> // SW_MOD 31 #include <editeng/pgrditem.hxx> 32 #include <editeng/lrspitem.hxx> 33 #include <pagedesc.hxx> // SwPageDesc 34 #include <tgrditem.hxx> 35 #include <paratr.hxx> 36 37 #include <fmtline.hxx> 38 #include <lineinfo.hxx> 39 #include <charfmt.hxx> 40 #include "rootfrm.hxx" 41 #include <pagefrm.hxx> 42 #include <viewsh.hxx> // ViewShell 43 #include <viewimp.hxx> // SwViewImp 44 #include <viewopt.hxx> // SwViewOption 45 #include <frmtool.hxx> // DrawGraphic 46 #include <txtcfg.hxx> 47 #include <txtfrm.hxx> // SwTxtFrm 48 #include <itrpaint.hxx> // SwTxtPainter 49 #include <txtpaint.hxx> // SwSaveClip 50 #include <txtcache.hxx> // SwTxtLineAccess 51 #include <flyfrm.hxx> // SwFlyFrm 52 #include <redlnitr.hxx> // SwRedlineItr 53 #include <swmodule.hxx> // SW_MOD 54 #include <tabfrm.hxx> // SwTabFrm (Redlining) 55 #include <SwGrammarMarkUp.hxx> 56 57 // --> FME 2004-06-08 #i12836# enhanced pdf export 58 #include <EnhancedPDFExportHelper.hxx> 59 // <-- 60 61 #include <IDocumentStylePoolAccess.hxx> 62 #include <IDocumentLineNumberAccess.hxx> 63 64 // --> OD 2006-06-27 #b6440955# 65 // variable moved to class <numfunc:GetDefBulletConfig> 66 //extern const sal_Char __FAR_DATA sBulletFntName[]; 67 namespace numfunc 68 { 69 extern const String& GetDefBulletFontname(); 70 extern bool IsDefBulletFontUserDefined(); 71 } 72 // <-- 73 74 75 #define REDLINE_DISTANCE 567/4 76 #define REDLINE_MINDIST 567/10 77 78 using namespace ::com::sun::star; 79 80 //////////////////////////////////////////////////////////// 81 82 sal_Bool bInitFont = sal_True; 83 84 class SwExtraPainter 85 { 86 SwSaveClip aClip; 87 SwRect aRect; 88 const SwTxtFrm* pTxtFrm; 89 ViewShell *pSh; 90 SwFont* pFnt; 91 const SwLineNumberInfo &rLineInf; 92 SwTwips nX; 93 SwTwips nRedX; 94 sal_uLong nLineNr; 95 MSHORT nDivider; 96 sal_Bool bGoLeft; 97 sal_Bool bLineNum; 98 inline sal_Bool IsClipChg() { return aClip.IsChg(); } 99 public: 100 SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh, 101 const SwLineNumberInfo &rLnInf, const SwRect &rRct, 102 sal_Int16 eHor, sal_Bool bLnNm ); 103 ~SwExtraPainter() { delete pFnt; } 104 inline SwFont* GetFont() const { return pFnt; } 105 inline void IncLineNr() { ++nLineNr; } 106 inline sal_Bool HasNumber() { return !( nLineNr % rLineInf.GetCountBy() ); } 107 inline sal_Bool HasDivider() { if( !nDivider ) return sal_False; 108 return !(nLineNr % rLineInf.GetDividerCountBy()); } 109 110 void PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed ); 111 void PaintRedline( SwTwips nY, long nMax ); 112 }; 113 114 115 SwExtraPainter::SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh, 116 const SwLineNumberInfo &rLnInf, const SwRect &rRct, 117 sal_Int16 eHor, sal_Bool bLnNm ) 118 : aClip( pVwSh->GetWin() || pFrm->IsUndersized() ? pVwSh->GetOut() : 0 ), 119 aRect( rRct ), pTxtFrm( pFrm ), pSh( pVwSh ), pFnt( 0 ), rLineInf( rLnInf ), 120 nLineNr( 1L ), bLineNum( bLnNm ) 121 { 122 if( pFrm->IsUndersized() ) 123 { 124 SwTwips nBottom = pFrm->Frm().Bottom(); 125 if( aRect.Bottom() > nBottom ) 126 aRect.Bottom( nBottom ); 127 } 128 MSHORT nVirtPageNum = 0; 129 if( bLineNum ) 130 { /* initialisiert die Member, die bei Zeilennumerierung notwendig sind: 131 132 nDivider, wie oft ist ein Teilerstring gewuenscht, 0 == nie; 133 nX, X-Position der Zeilennummern; 134 pFnt, der Font der Zeilennummern; 135 nLineNr, die erste Zeilennummer; 136 bLineNum wird ggf.wieder auf sal_False gesetzt, wenn die Numerierung sich 137 komplett ausserhalb des Paint-Rechtecks aufhaelt. */ 138 nDivider = rLineInf.GetDivider().Len() ? rLineInf.GetDividerCountBy() : 0; 139 nX = pFrm->Frm().Left(); 140 SwCharFmt* pFmt = rLineInf.GetCharFmt( const_cast<IDocumentStylePoolAccess&>(*pFrm->GetNode()->getIDocumentStylePoolAccess()) ); 141 ASSERT( pFmt, "PaintExtraData without CharFmt" ); 142 pFnt = new SwFont( &pFmt->GetAttrSet(), pFrm->GetTxtNode()->getIDocumentSettingAccess() ); 143 pFnt->Invalidate(); 144 pFnt->ChgPhysFnt( pSh, *pSh->GetOut() ); 145 pFnt->SetVertical( 0, pFrm->IsVertical() ); 146 nLineNr += pFrm->GetAllLines() - pFrm->GetThisLines(); 147 LineNumberPosition ePos = rLineInf.GetPos(); 148 if( ePos != LINENUMBER_POS_LEFT && ePos != LINENUMBER_POS_RIGHT ) 149 { 150 if( pFrm->FindPageFrm()->OnRightPage() ) 151 { 152 nVirtPageNum = 1; 153 ePos = ePos == LINENUMBER_POS_INSIDE ? 154 LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT; 155 } 156 else 157 { 158 nVirtPageNum = 2; 159 ePos = ePos == LINENUMBER_POS_OUTSIDE ? 160 LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT; 161 } 162 } 163 if( LINENUMBER_POS_LEFT == ePos ) 164 { 165 bGoLeft = sal_True; 166 nX -= rLineInf.GetPosFromLeft(); 167 if( nX < aRect.Left() ) 168 bLineNum = sal_False; 169 } 170 else 171 { 172 bGoLeft = sal_False; 173 nX += pFrm->Frm().Width() + rLineInf.GetPosFromLeft(); 174 if( nX > aRect.Right() ) 175 bLineNum = sal_False; 176 } 177 } 178 if( eHor != text::HoriOrientation::NONE ) 179 { 180 if( text::HoriOrientation::INSIDE == eHor || text::HoriOrientation::OUTSIDE == eHor ) 181 { 182 if( !nVirtPageNum ) 183 nVirtPageNum = pFrm->FindPageFrm()->OnRightPage() ? 1 : 2; 184 if( nVirtPageNum % 2 ) 185 eHor = eHor == text::HoriOrientation::INSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT; 186 else 187 eHor = eHor == text::HoriOrientation::OUTSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT; 188 } 189 const SwFrm* pTmpFrm = pFrm->FindTabFrm(); 190 if( !pTmpFrm ) 191 pTmpFrm = pFrm; 192 nRedX = text::HoriOrientation::LEFT == eHor ? pTmpFrm->Frm().Left() - REDLINE_DISTANCE : 193 pTmpFrm->Frm().Right() + REDLINE_DISTANCE; 194 } 195 } 196 197 /************************************************************************* 198 * SwExtraPainter::PaintExtra() 199 **************************************************************************/ 200 201 void SwExtraPainter::PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed ) 202 { 203 //Zeilennummer ist staerker als der Teiler 204 const XubString aTmp( HasNumber() ? rLineInf.GetNumType().GetNumStr( nLineNr ) 205 : rLineInf.GetDivider() ); 206 207 // get script type of line numbering: 208 pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmp, 0 ) ); 209 210 SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), 0, aTmp, 0, aTmp.Len() ); 211 aDrawInf.SetSpace( 0 ); 212 aDrawInf.SetWrong( NULL ); 213 aDrawInf.SetGrammarCheck( NULL ); 214 aDrawInf.SetSmartTags( NULL ); // SMARTTAGS 215 aDrawInf.SetLeft( 0 ); 216 aDrawInf.SetRight( LONG_MAX ); 217 aDrawInf.SetFrm( pTxtFrm ); 218 aDrawInf.SetFont( pFnt ); 219 aDrawInf.SetSnapToGrid( sal_False ); 220 aDrawInf.SetIgnoreFrmRTL( sal_True ); 221 222 sal_Bool bTooBig = pFnt->GetSize( pFnt->GetActual() ).Height() > nMax && 223 pFnt->GetHeight( pSh, *pSh->GetOut() ) > nMax; 224 SwFont* pTmpFnt; 225 if( bTooBig ) 226 { 227 pTmpFnt = new SwFont( *GetFont() ); 228 if( nMax >= 20 ) 229 { 230 nMax *= 17; 231 nMax /= 20; 232 } 233 pTmpFnt->SetSize( Size( 0, nMax ), pTmpFnt->GetActual() ); 234 } 235 else 236 pTmpFnt = GetFont(); 237 Point aTmpPos( nX, nY ); 238 aTmpPos.Y() += nAsc; 239 sal_Bool bPaint = sal_True; 240 if( !IsClipChg() ) 241 { 242 Size aSize = pTmpFnt->_GetTxtSize( aDrawInf ); 243 if( bGoLeft ) 244 aTmpPos.X() -= aSize.Width(); 245 // calculate rectangle containing the line number 246 SwRect aRct( Point( aTmpPos.X(), 247 aTmpPos.Y() - pTmpFnt->GetAscent( pSh, *pSh->GetOut() ) 248 ), aSize ); 249 if( !aRect.IsInside( aRct ) ) 250 { 251 if( aRct.Intersection( aRect ).IsEmpty() ) 252 bPaint = sal_False; 253 else 254 aClip.ChgClip( aRect, pTxtFrm ); 255 } 256 } 257 else if( bGoLeft ) 258 aTmpPos.X() -= pTmpFnt->_GetTxtSize( aDrawInf ).Width(); 259 aDrawInf.SetPos( aTmpPos ); 260 if( bPaint ) 261 pTmpFnt->_DrawText( aDrawInf ); 262 263 if( bTooBig ) 264 delete pTmpFnt; 265 if( bRed ) 266 { 267 long nDiff = bGoLeft ? nRedX - nX : nX - nRedX; 268 if( nDiff > REDLINE_MINDIST ) 269 PaintRedline( nY, nMax ); 270 } 271 } 272 273 void SwExtraPainter::PaintRedline( SwTwips nY, long nMax ) 274 { 275 Point aStart( nRedX, nY ); 276 Point aEnd( nRedX, nY + nMax ); 277 278 if( !IsClipChg() ) 279 { 280 SwRect aRct( aStart, aEnd ); 281 if( !aRect.IsInside( aRct ) ) 282 { 283 if( aRct.Intersection( aRect ).IsEmpty() ) 284 return; 285 aClip.ChgClip( aRect, pTxtFrm ); 286 } 287 } 288 const Color aOldCol( pSh->GetOut()->GetLineColor() ); 289 pSh->GetOut()->SetLineColor( SW_MOD()->GetRedlineMarkColor() ); 290 291 if ( pTxtFrm->IsVertical() ) 292 { 293 pTxtFrm->SwitchHorizontalToVertical( aStart ); 294 pTxtFrm->SwitchHorizontalToVertical( aEnd ); 295 } 296 297 pSh->GetOut()->DrawLine( aStart, aEnd ); 298 pSh->GetOut()->SetLineColor( aOldCol ); 299 } 300 301 void SwTxtFrm::PaintExtraData( const SwRect &rRect ) const 302 { 303 if( Frm().Top() > rRect.Bottom() || Frm().Bottom() < rRect.Top() ) 304 return; 305 306 const SwTxtNode& rTxtNode = *GetTxtNode(); 307 const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess(); 308 const SwLineNumberInfo &rLineInf = rTxtNode.getIDocumentLineNumberAccess()->GetLineNumberInfo(); 309 const SwFmtLineNumber &rLineNum = GetAttrSet()->GetLineNumber(); 310 sal_Bool bLineNum = !IsInTab() && rLineInf.IsPaintLineNumbers() && 311 ( !IsInFly() || rLineInf.IsCountInFlys() ) && rLineNum.IsCount(); 312 sal_Int16 eHor = (sal_Int16)SW_MOD()->GetRedlineMarkPos(); 313 if( eHor != text::HoriOrientation::NONE && !IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) ) 314 eHor = text::HoriOrientation::NONE; 315 sal_Bool bRedLine = eHor != text::HoriOrientation::NONE; 316 if ( bLineNum || bRedLine ) 317 { 318 if( IsLocked() || IsHiddenNow() || !Prt().Height() ) 319 return; 320 ViewShell *pSh = getRootFrm()->GetCurrShell(); 321 322 SWAP_IF_NOT_SWAPPED( this ) 323 SwRect rOldRect( rRect ); 324 325 if ( IsVertical() ) 326 SwitchVerticalToHorizontal( (SwRect&)rRect ); 327 328 SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() ); 329 aLayoutModeModifier.Modify( sal_False ); 330 331 // --> FME 2004-06-24 #i16816# tagged pdf support 332 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); 333 // <-- 334 335 SwExtraPainter aExtra( this, pSh, rLineInf, rRect, eHor, bLineNum ); 336 337 if( HasPara() ) 338 { 339 SwTxtFrmLocker aLock((SwTxtFrm*)this); 340 341 SwTxtLineAccess aAccess( (SwTxtFrm*)this ); 342 aAccess.GetPara(); 343 344 SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect ); 345 346 aLayoutModeModifier.Modify( sal_False ); 347 348 SwTxtPainter aLine( (SwTxtFrm*)this, &aInf ); 349 sal_Bool bNoDummy = !aLine.GetNext(); // Nur eine Leerzeile! 350 351 while( aLine.Y() + aLine.GetLineHeight() <= rRect.Top() ) 352 { 353 if( !aLine.GetCurr()->IsDummy() && 354 ( rLineInf.IsCountBlankLines() || 355 aLine.GetCurr()->HasCntnt() ) ) 356 aExtra.IncLineNr(); 357 if( !aLine.Next() ) 358 { 359 (SwRect&)rRect = rOldRect; 360 UNDO_SWAP( this ) 361 return; 362 } 363 } 364 365 long nBottom = rRect.Bottom(); 366 367 sal_Bool bNoPrtLine = 0 == GetMinPrtLine(); 368 if( !bNoPrtLine ) 369 { 370 while ( aLine.Y() < GetMinPrtLine() ) 371 { 372 if( ( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() ) 373 && !aLine.GetCurr()->IsDummy() ) 374 aExtra.IncLineNr(); 375 if( !aLine.Next() ) 376 break; 377 } 378 bNoPrtLine = aLine.Y() >= GetMinPrtLine(); 379 } 380 if( bNoPrtLine ) 381 { 382 do 383 { 384 if( bNoDummy || !aLine.GetCurr()->IsDummy() ) 385 { 386 sal_Bool bRed = bRedLine && aLine.GetCurr()->HasRedline(); 387 if( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() ) 388 { 389 if( bLineNum && 390 ( aExtra.HasNumber() || aExtra.HasDivider() ) ) 391 { 392 KSHORT nTmpHeight, nTmpAscent; 393 aLine.CalcAscentAndHeight( nTmpAscent, nTmpHeight ); 394 aExtra.PaintExtra( aLine.Y(), nTmpAscent, 395 nTmpHeight, bRed ); 396 bRed = sal_False; 397 } 398 aExtra.IncLineNr(); 399 } 400 if( bRed ) 401 aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight() ); 402 } 403 } while( aLine.Next() && aLine.Y() <= nBottom ); 404 } 405 } 406 else 407 { 408 bRedLine &= ( MSHRT_MAX!= pIDRA->GetRedlinePos(rTxtNode, USHRT_MAX) ); 409 410 if( bLineNum && rLineInf.IsCountBlankLines() && 411 ( aExtra.HasNumber() || aExtra.HasDivider() ) ) 412 { 413 aExtra.PaintExtra( Frm().Top()+Prt().Top(), aExtra.GetFont() 414 ->GetAscent( pSh, *pSh->GetOut() ), Prt().Height(), bRedLine ); 415 } 416 else if( bRedLine ) 417 aExtra.PaintRedline( Frm().Top()+Prt().Top(), Prt().Height() ); 418 } 419 420 (SwRect&)rRect = rOldRect; 421 UNDO_SWAP( this ) 422 } 423 } 424 425 /************************************************************************* 426 * SwTxtFrm::Paint() 427 *************************************************************************/ 428 429 SwRect SwTxtFrm::Paint() 430 { 431 #if OSL_DEBUG_LEVEL > 1 432 const SwTwips nDbgY = Frm().Top(); 433 (void)nDbgY; 434 #endif 435 436 // finger layout 437 ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" ); 438 439 SwRect aRet( Prt() ); 440 if ( IsEmpty() || !HasPara() ) 441 aRet += Frm().Pos(); 442 else 443 { 444 // AMA: Wir liefern jetzt mal das richtige Repaintrechteck zurueck, 445 // d.h. als linken Rand den berechneten PaintOfst! 446 SwRepaint *pRepaint = GetPara()->GetRepaint(); 447 long l; 448 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 449 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 450 pRepaint->Chg( ( GetUpper()->Frm() ).Pos() + ( GetUpper()->Prt() ).Pos(), ( GetUpper()->Prt() ).SSize() ); 451 452 if( pRepaint->GetOfst() ) 453 pRepaint->Left( pRepaint->GetOfst() ); 454 455 l = pRepaint->GetRightOfst(); 456 if( l && ( pRepaint->GetOfst() || l > pRepaint->Right() ) ) 457 pRepaint->Right( l ); 458 pRepaint->SetOfst( 0 ); 459 aRet = *pRepaint; 460 461 if ( IsRightToLeft() ) 462 SwitchLTRtoRTL( aRet ); 463 464 if ( IsVertical() ) 465 SwitchHorizontalToVertical( aRet ); 466 } 467 ResetRepaint(); 468 469 return aRet; 470 } 471 472 /************************************************************************* 473 * SwTxtFrm::Paint() 474 *************************************************************************/ 475 476 sal_Bool SwTxtFrm::PaintEmpty( const SwRect &rRect, sal_Bool bCheck ) const 477 { 478 ViewShell *pSh = getRootFrm()->GetCurrShell(); 479 if( pSh && ( pSh->GetViewOptions()->IsParagraph() || bInitFont ) ) 480 { 481 bInitFont = sal_False; 482 SwTxtFly aTxtFly( this ); 483 aTxtFly.SetTopRule(); 484 SwRect aRect; 485 if( bCheck && aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) ) 486 return sal_False; 487 else if( pSh->GetWin() ) 488 { 489 SwFont *pFnt; 490 const SwTxtNode& rTxtNode = *GetTxtNode(); 491 if ( rTxtNode.HasSwAttrSet() ) 492 { 493 const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() ); 494 pFnt = new SwFont( pAttrSet, rTxtNode.getIDocumentSettingAccess() ); 495 } 496 else 497 { 498 SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh ); 499 pFnt = new SwFont( *aFontAccess.Get()->GetFont() ); 500 } 501 502 const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess(); 503 if( IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) ) 504 { 505 MSHORT nRedlPos = pIDRA->GetRedlinePos( rTxtNode, USHRT_MAX ); 506 if( MSHRT_MAX != nRedlPos ) 507 { 508 SwAttrHandler aAttrHandler; 509 aAttrHandler.Init( rTxtNode.GetSwAttrSet(), 510 *rTxtNode.getIDocumentSettingAccess(), NULL ); 511 SwRedlineItr aRedln( rTxtNode, *pFnt, aAttrHandler, nRedlPos, sal_True ); 512 } 513 } 514 515 if( pSh->GetViewOptions()->IsParagraph() && Prt().Height() ) 516 { 517 if( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet( SW_LATIN ) && 518 pFnt->GetName( SW_LATIN ) != numfunc::GetDefBulletFontname() ) 519 { 520 pFnt->SetFamily( FAMILY_DONTKNOW, SW_LATIN ); 521 pFnt->SetName( numfunc::GetDefBulletFontname(), SW_LATIN ); 522 pFnt->SetStyleName( aEmptyStr, SW_LATIN ); 523 pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, SW_LATIN ); 524 } 525 pFnt->SetVertical( 0, IsVertical() ); 526 SwFrmSwapper aSwapper( this, sal_True ); 527 SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() ); 528 aLayoutModeModifier.Modify( IsRightToLeft() ); 529 530 pFnt->Invalidate(); 531 pFnt->ChgPhysFnt( pSh, *pSh->GetOut() ); 532 Point aPos = Frm().Pos() + Prt().Pos(); 533 534 const SvxLRSpaceItem &rSpace = 535 GetTxtNode()->GetSwAttrSet().GetLRSpace(); 536 537 if ( rSpace.GetTxtFirstLineOfst() > 0 ) 538 aPos.X() += rSpace.GetTxtFirstLineOfst(); 539 540 SwSaveClip *pClip; 541 if( IsUndersized() ) 542 { 543 pClip = new SwSaveClip( pSh->GetOut() ); 544 pClip->ChgClip( rRect ); 545 } 546 else 547 pClip = NULL; 548 549 aPos.Y() += pFnt->GetAscent( pSh, *pSh->GetOut() ); 550 551 if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() && 552 IsInDocBody() ) 553 { 554 GETGRID( FindPageFrm() ) 555 if ( pGrid ) 556 { 557 // center character in grid line 558 aPos.Y() += ( pGrid->GetBaseHeight() - 559 pFnt->GetHeight( pSh, *pSh->GetOut() ) ) / 2; 560 561 if ( ! pGrid->GetRubyTextBelow() ) 562 aPos.Y() += pGrid->GetRubyHeight(); 563 } 564 } 565 566 const XubString aTmp( CH_PAR ); 567 SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), 0, aTmp, 0, 1 ); 568 aDrawInf.SetLeft( rRect.Left() ); 569 aDrawInf.SetRight( rRect.Right() ); 570 aDrawInf.SetPos( aPos ); 571 aDrawInf.SetSpace( 0 ); 572 aDrawInf.SetKanaComp( 0 ); 573 aDrawInf.SetWrong( NULL ); 574 aDrawInf.SetGrammarCheck( NULL ); 575 aDrawInf.SetSmartTags( NULL ); // SMARTTAGS 576 aDrawInf.SetFrm( this ); 577 aDrawInf.SetFont( pFnt ); 578 aDrawInf.SetSnapToGrid( sal_False ); 579 580 pFnt->_DrawText( aDrawInf ); 581 delete pClip; 582 } 583 delete pFnt; 584 return sal_True; 585 } 586 } 587 else 588 return sal_True; 589 return sal_False; 590 } 591 592 /************************************************************************* 593 * SwTxtFrm::Paint() 594 *************************************************************************/ 595 596 void SwTxtFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 597 { 598 ResetRepaint(); 599 600 // --> FME 2004-06-24 #i16816# tagged pdf support 601 ViewShell *pSh = getRootFrm()->GetCurrShell(); 602 603 Num_Info aNumInfo( *this ); 604 SwTaggedPDFHelper aTaggedPDFHelperNumbering( &aNumInfo, 0, 0, *pSh->GetOut() ); 605 606 Frm_Info aFrmInfo( *this ); 607 SwTaggedPDFHelper aTaggedPDFHelperParagraph( 0, &aFrmInfo, 0, *pSh->GetOut() ); 608 // <-- 609 610 DBG_LOOP_RESET; 611 if( !IsEmpty() || !PaintEmpty( rRect, sal_True ) ) 612 { 613 #if OSL_DEBUG_LEVEL > 1 614 const SwTwips nDbgY = Frm().Top(); 615 (void)nDbgY; 616 #endif 617 618 #ifdef DBGTXT 619 if( IsDbg( this ) ) 620 DBTXTFRM << "Paint()" << endl; 621 #endif 622 if( IsLocked() || IsHiddenNow() || ! Prt().HasArea() ) 623 return; 624 625 //Kann gut sein, dass mir der IdleCollector mir die gecachten 626 //Informationen entzogen hat. 627 if( !HasPara() ) 628 { 629 ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" ); 630 631 // --> FME 2004-10-29 #i29062# pass info that we are currently 632 // painting. 633 ((SwTxtFrm*)this)->GetFormatted( true ); 634 // <-- 635 if( IsEmpty() ) 636 { 637 PaintEmpty( rRect, sal_False ); 638 return; 639 } 640 if( !HasPara() ) 641 { 642 ASSERT( !this, "+SwTxtFrm::Paint: missing format information" ); 643 return; 644 } 645 } 646 647 // Waehrend wir painten, wollen wir nicht gestoert werden. 648 // Aber erst hinter dem Format() ! 649 SwTxtFrmLocker aLock((SwTxtFrm*)this); 650 651 //Hier wird ggf. nur der Teil des TxtFrm ausgegeben, der sich veraendert 652 //hat und der in dem Bereich liegt, dessen Ausgabe angefordert wurde. 653 //Man kann jetzt auf die Idee kommen, dass der Bereich rRect ausgegeben 654 //werden _muss_ obwohl rRepaint gesetzt ist; in der Tat kann dieses 655 //Problem nicht formal vermieden werden. Gluecklicherweise koennen 656 //wir davon ausgehen, dass rRepaint immer dann leer ist, wenn der Frm 657 //komplett gepainted werden muss. 658 SwTxtLineAccess aAccess( (SwTxtFrm*)this ); 659 SwParaPortion *pPara = aAccess.GetPara(); 660 661 SwRepaint &rRepaint = *(pPara->GetRepaint()); 662 663 // Das Recycling muss abgeschaltet werden, wenn wir uns im 664 // FlyCntFrm befinden, weil ein DrawRect fuer die Retusche der 665 // Zeile aufgerufen wird. 666 if( rRepaint.GetOfst() ) 667 { 668 const SwFlyFrm *pFly = FindFlyFrm(); 669 if( pFly && pFly->IsFlyInCntFrm() ) 670 rRepaint.SetOfst( 0 ); 671 } 672 673 // Hier holen wir uns den String fuer die Ausgabe, besonders 674 // die Laenge ist immer wieder interessant. 675 676 // Rectangle 677 ASSERT( ! IsSwapped(), "A frame is swapped before Paint" ); 678 SwRect aOldRect( rRect ); 679 680 SWAP_IF_NOT_SWAPPED( this ) 681 682 if ( IsVertical() ) 683 SwitchVerticalToHorizontal( (SwRect&)rRect ); 684 685 if ( IsRightToLeft() ) 686 SwitchRTLtoLTR( (SwRect&)rRect ); 687 688 SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect ); 689 aInf.SetWrongList( ( (SwTxtNode*)GetTxtNode() )->GetWrong() ); 690 aInf.SetGrammarCheckList( ( (SwTxtNode*)GetTxtNode() )->GetGrammarCheck() ); 691 aInf.SetSmartTags( ( (SwTxtNode*)GetTxtNode() )->GetSmartTags() ); // SMARTTAGS 692 aInf.GetTxtFly()->SetTopRule(); 693 694 SwTxtPainter aLine( (SwTxtFrm*)this, &aInf ); 695 // Eine Optimierung, die sich lohnt: wenn kein freifliegender Frame 696 // in unsere Zeile ragt, schaltet sich der SwTxtFly einfach ab: 697 aInf.GetTxtFly()->Relax(); 698 699 OutputDevice* pOut = aInf.GetOut(); 700 const sal_Bool bOnWin = pSh->GetWin() != 0; 701 702 SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : 0 ); 703 704 // Ausgabeschleife: Fuer jede Zeile ... (die noch zu sehen ist) ... 705 // rRect muss angepasst werden (Top+1, Bottom-1), weil der Iterator 706 // die Zeilen nahtlos aneinanderfuegt. 707 aLine.TwipsToLine( rRect.Top() + 1 ); 708 long nBottom = rRect.Bottom(); 709 710 sal_Bool bNoPrtLine = 0 == GetMinPrtLine(); 711 if( !bNoPrtLine ) 712 { 713 while ( aLine.Y() < GetMinPrtLine() && aLine.Next() ) 714 ; 715 bNoPrtLine = aLine.Y() >= GetMinPrtLine(); 716 } 717 if( bNoPrtLine ) 718 { 719 do 720 { 721 //DBG_LOOP; shadows declaration above. 722 //resolved into: 723 #if OSL_DEBUG_LEVEL > 1 724 #ifdef DBG_UTIL 725 DbgLoop aDbgLoop2( (const void*) this ); 726 #endif 727 #endif 728 aLine.DrawTextLine( rRect, aClip, IsUndersized() ); 729 730 } while( aLine.Next() && aLine.Y() <= nBottom ); 731 } 732 733 // Einmal reicht: 734 if( aLine.IsPaintDrop() ) 735 aLine.PaintDropPortion(); 736 737 if( rRepaint.HasArea() ) 738 rRepaint.Clear(); 739 740 UNDO_SWAP( this ) 741 (SwRect&)rRect = aOldRect; 742 743 ASSERT( ! IsSwapped(), "A frame is swapped after Paint" ); 744 } 745 } 746 747