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