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/poly.hxx> 31 #define _SVSTDARR_LONGS 32 #include <svl/svstdarr.hxx> 33 #include <svx/xoutbmp.hxx> 34 #include <sfx2/progress.hxx> 35 #include <editeng/brshitem.hxx> 36 #include <editeng/opaqitem.hxx> 37 #include <editeng/prntitem.hxx> 38 #include <editeng/boxitem.hxx> 39 #include <editeng/shaditem.hxx> 40 #include <svx/framelink.hxx> 41 #include <vcl/graph.hxx> 42 #include <svx/svdpagv.hxx> 43 #include <hintids.hxx> 44 #include <tgrditem.hxx> 45 #include <switerator.hxx> 46 #include <fmtsrnd.hxx> 47 #include <fmtclds.hxx> 48 #include <tools/shl.hxx> 49 #include <comcore.hrc> 50 #include <swmodule.hxx> 51 #include <rootfrm.hxx> 52 #include <pagefrm.hxx> 53 #include <cntfrm.hxx> 54 #include <viewsh.hxx> 55 #include <section.hxx> 56 #include <sectfrm.hxx> 57 #include <doc.hxx> 58 #include <viewimp.hxx> 59 #include <dflyobj.hxx> 60 #include <flyfrm.hxx> 61 #include <frmtool.hxx> 62 #include <viewopt.hxx> 63 #include <dview.hxx> 64 #include <dcontact.hxx> 65 #include <txtfrm.hxx> 66 #include <ftnfrm.hxx> 67 #include <tabfrm.hxx> 68 #include <rowfrm.hxx> 69 #include <cellfrm.hxx> 70 #include <notxtfrm.hxx> 71 #include <swregion.hxx> 72 #include <layact.hxx> 73 #include <pagedesc.hxx> 74 #include <ptqueue.hxx> 75 #include <noteurl.hxx> 76 #include <virtoutp.hxx> 77 #include <lineinfo.hxx> 78 #include <dbg_lay.hxx> 79 #include <accessibilityoptions.hxx> 80 #include <docsh.hxx> 81 #include <swtable.hxx> 82 #include <svx/svdogrp.hxx> 83 #include <sortedobjs.hxx> 84 #include <EnhancedPDFExportHelper.hxx> 85 // <-- 86 // --> OD #i76669# 87 #include <svx/sdr/contact/viewobjectcontactredirector.hxx> 88 #include <svx/sdr/contact/viewobjectcontact.hxx> 89 #include <svx/sdr/contact/viewcontact.hxx> 90 // <-- 91 92 #include <ndole.hxx> 93 #include <svx/charthelper.hxx> 94 #include <PostItMgr.hxx> 95 #include <tools/color.hxx> 96 #include <vcl/svapp.hxx> 97 98 //UUUU 99 #include <drawinglayer/processor2d/processor2dtools.hxx> 100 101 #define COL_NOTES_SIDEPANE RGB_COLORDATA(230,230,230) 102 #define COL_NOTES_SIDEPANE_BORDER RGB_COLORDATA(200,200,200) 103 #define COL_NOTES_SIDEPANE_SCROLLAREA RGB_COLORDATA(230,230,220) 104 105 using namespace ::com::sun::star; 106 107 #define GETOBJSHELL() ((SfxObjectShell*)rSh.GetDoc()->GetDocShell()) 108 109 //Tabellenhilfslinien an? 110 #define IS_SUBS_TABLE \ 111 (pGlobalShell->GetViewOptions()->IsTable() && \ 112 !pGlobalShell->GetViewOptions()->IsPagePreview()&&\ 113 !pGlobalShell->GetViewOptions()->IsReadonly()&&\ 114 !pGlobalShell->GetViewOptions()->IsFormView() &&\ 115 SwViewOption::IsTableBoundaries()) 116 //sonstige Hilfslinien an? 117 #define IS_SUBS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \ 118 !pGlobalShell->GetViewOptions()->IsReadonly() && \ 119 !pGlobalShell->GetViewOptions()->IsFormView() &&\ 120 SwViewOption::IsDocBoundaries()) 121 //Hilfslinien fuer Bereiche 122 #define IS_SUBS_SECTION (!pGlobalShell->GetViewOptions()->IsPagePreview() && \ 123 !pGlobalShell->GetViewOptions()->IsReadonly()&&\ 124 !pGlobalShell->GetViewOptions()->IsFormView() &&\ 125 SwViewOption::IsSectionBoundaries()) 126 #define IS_SUBS_FLYS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \ 127 !pGlobalShell->GetViewOptions()->IsReadonly()&&\ 128 !pGlobalShell->GetViewOptions()->IsFormView() &&\ 129 SwViewOption::IsObjectBoundaries()) 130 131 #define SW_MAXBORDERCACHE 20 132 133 //Klassendeklarationen. Hier weil sie eben nur in diesem File benoetigt 134 //werden. 135 136 #define SUBCOL_PAGE 0x01 //Helplines of the page 137 #define SUBCOL_BREAK 0x02 //Helpline for a page or column break 138 #define SUBCOL_TAB 0x08 //Helplines inside tables 139 #define SUBCOL_FLY 0x10 //Helplines inside fly frames 140 #define SUBCOL_SECT 0x20 //Helplines inside sections 141 142 //----- Klassen zum Sammeln von Umrandungen und Hilfslinien --- 143 class SwLineRect : public SwRect 144 { 145 const Color *pColor; 146 const SwTabFrm *pTab; 147 sal_uInt8 nSubColor; //Hilfslinien einfaerben 148 sal_Bool bPainted; //schon gepaintet? 149 sal_uInt8 nLock; //Um die Linien zum Hell-Layer abzugrenzen. 150 public: 151 SwLineRect( const SwRect &rRect, const Color *pCol, 152 const SwTabFrm *pT , const sal_uInt8 nSCol ); 153 154 const Color *GetColor() const { return pColor;} 155 const SwTabFrm *GetTab() const { return pTab; } 156 void SetPainted() { bPainted = sal_True; } 157 void Lock( sal_Bool bLock ) { if ( bLock ) 158 ++nLock; 159 else if ( nLock ) 160 --nLock; 161 } 162 sal_Bool IsPainted() const { return bPainted; } 163 sal_Bool IsLocked() const { return nLock != 0; } 164 sal_uInt8 GetSubColor() const { return nSubColor;} 165 166 sal_Bool MakeUnion( const SwRect &rRect ); 167 }; 168 169 SV_DECL_VARARR( SwLRects, SwLineRect, 100, 100 ) 170 171 class SwLineRects : public SwLRects 172 { 173 sal_uInt16 nLastCount; //unuetze Durchlaeufe im PaintLines verhindern. 174 public: 175 SwLineRects() : nLastCount( 0 ) {} 176 void AddLineRect( const SwRect& rRect, const Color *pColor, 177 const SwTabFrm *pTab, const sal_uInt8 nSCol ); 178 void ConnectEdges( OutputDevice *pOut ); 179 void PaintLines ( OutputDevice *pOut ); 180 void LockLines( sal_Bool bLock ); 181 182 /// OD 13.08.2002 - correct type of function 183 sal_uInt16 Free() const { return nFree; } 184 }; 185 186 class SwSubsRects : public SwLineRects 187 { 188 void RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects ); //;-) 189 public: 190 void PaintSubsidiary( OutputDevice *pOut, const SwLineRects *pRects ); 191 192 inline void Ins( const SwRect &rRect, const sal_uInt8 nSCol ); 193 }; 194 195 //----------------- End Klassen Umrandungen ---------------------- 196 197 static ViewShell *pGlobalShell = 0; 198 199 //Wenn durchsichtige FlyInCnts im PaintBackground gepainted werden so soll der 200 //Hintergrund nicht mehr retouchiert werden. 201 //static sal_Bool bLockFlyBackground = sal_False; 202 203 //Wenn vom Fly ein Metafile abgezogen wird, so soll nur der FlyInhalt und vor 204 //nur hintergrund vom FlyInhalt gepaintet werden. 205 static sal_Bool bFlyMetafile = sal_False; 206 static OutputDevice *pFlyMetafileOut = 0; 207 208 //Die Retouche fuer Durchsichtige Flys wird vom Hintergrund der Flys 209 //erledigt. Dabei darf der Fly selbst natuerlich nicht ausgespart werden. 210 //siehe PaintBackground und lcl_SubtractFlys() 211 static SwFlyFrm *pRetoucheFly = 0; 212 static SwFlyFrm *pRetoucheFly2 = 0; 213 214 //Groesse eines Pixel und die Haelfte davon. Wird jeweils bei Eintritt in 215 //SwRootFrm::Paint neu gesetzt. 216 static long nPixelSzW = 0, nPixelSzH = 0; 217 static long nHalfPixelSzW = 0, nHalfPixelSzH = 0; 218 static long nMinDistPixelW = 0, nMinDistPixelH = 0; 219 220 //Aktueller Zoomfaktor 221 static double aScaleX = 1.0; 222 static double aScaleY = 1.0; 223 static double aMinDistScale = 0.73; 224 static double aEdgeScale = 0.5; 225 226 227 //In pLines werden Umrandungen waehrend des Paint gesammelt und soweit 228 //moeglich zusammengefasst. 229 //In pSubsLines werden Hilfslinien gesammelt und zusammengefasst. Diese 230 //werden vor der Ausgabe mit pLines abgeglichen, so dass moeglichst keine 231 //Umrandungen von den Hilfslinen verdeckt werden. 232 //bTablines ist waerend des Paints einer Tabelle sal_True. 233 static SwLineRects *pLines = 0; 234 static SwSubsRects *pSubsLines = 0; 235 // OD 18.11.2002 #99672# - global variable for sub-lines of body, header, footer, 236 // section and footnote frames. 237 static SwSubsRects *pSpecSubsLines = 0; 238 239 static SfxProgress *pProgress = 0; 240 241 static SwFlyFrm *pFlyOnlyDraw = 0; 242 243 //Damit die Flys auch fuer den Hack richtig gepaintet werden koennen. 244 static sal_Bool bTableHack = sal_False; 245 246 //Um das teure Ermitteln der RetoucheColor zu optimieren 247 Color aGlobalRetoucheColor; 248 249 //Statics fuer Umrandungsalignment setzen. 250 // OD 05.05.2003 #107169# - adjustment for 'small' twip-to-pixel relations: 251 // For 'small' twip-to-pixel relations (less then 2:1) 252 // values of <nHalfPixelSzW> and <nHalfPixelSzH> are set to ZERO. 253 void SwCalcPixStatics( OutputDevice *pOut ) 254 { 255 // OD 30.04.2003 #107169# - determine 'small' twip-to-pixel relation 256 sal_Bool bSmallTwipToPxRelW = sal_False; 257 sal_Bool bSmallTwipToPxRelH = sal_False; 258 { 259 Size aCheckTwipToPxRelSz( pOut->PixelToLogic( Size( 100, 100 )) ); 260 if ( (aCheckTwipToPxRelSz.Width()/100.0) < 2.0 ) 261 { 262 bSmallTwipToPxRelW = sal_True; 263 } 264 if ( (aCheckTwipToPxRelSz.Height()/100.0) < 2.0 ) 265 { 266 bSmallTwipToPxRelH = sal_True; 267 } 268 } 269 270 Size aSz( pOut->PixelToLogic( Size( 1,1 )) ); 271 272 nPixelSzW = aSz.Width(); 273 if( !nPixelSzW ) 274 nPixelSzW = 1; 275 nPixelSzH = aSz.Height(); 276 if( !nPixelSzH ) 277 nPixelSzH = 1; 278 279 // OD 06.05.2003 #107169# - consider 'small' twip-to-pixel relations 280 if ( !bSmallTwipToPxRelW ) 281 { 282 nHalfPixelSzW = nPixelSzW / 2 + 1; 283 } 284 else 285 { 286 nHalfPixelSzW = 0; 287 } 288 // OD 06.05.2003 #107169# - consider 'small' twip-to-pixel relations 289 if ( !bSmallTwipToPxRelH ) 290 { 291 nHalfPixelSzH = nPixelSzH / 2 + 1; 292 } 293 else 294 { 295 nHalfPixelSzH = 0; 296 } 297 298 nMinDistPixelW = nPixelSzW * 2 + 1; 299 nMinDistPixelH = nPixelSzH * 2 + 1; 300 301 const MapMode &rMap = pOut->GetMapMode(); 302 aScaleX = rMap.GetScaleX(); 303 aScaleY = rMap.GetScaleY(); 304 } 305 306 //Zum Sichern der statics, damit das Paint (quasi) reentrant wird. 307 class SwSavePaintStatics 308 { 309 sal_Bool bSFlyMetafile, 310 bSPageOnly; 311 ViewShell *pSGlobalShell; 312 OutputDevice *pSFlyMetafileOut; 313 SwFlyFrm *pSRetoucheFly, 314 *pSRetoucheFly2, 315 *pSFlyOnlyDraw; 316 SwLineRects *pSLines; 317 SwSubsRects *pSSubsLines; 318 // --> OD 2005-07-04 #123196# 319 SwSubsRects* pSSpecSubsLines; 320 // <-- 321 SfxProgress *pSProgress; 322 long nSPixelSzW, 323 nSPixelSzH, 324 nSHalfPixelSzW, 325 nSHalfPixelSzH, 326 nSMinDistPixelW, 327 nSMinDistPixelH; 328 Color aSGlobalRetoucheColor; 329 double aSScaleX, 330 aSScaleY; 331 public: 332 SwSavePaintStatics(); 333 ~SwSavePaintStatics(); 334 }; 335 336 SwSavePaintStatics::SwSavePaintStatics() : 337 bSFlyMetafile ( bFlyMetafile ), 338 pSGlobalShell ( pGlobalShell ), 339 pSFlyMetafileOut ( pFlyMetafileOut ), 340 pSRetoucheFly ( pRetoucheFly ), 341 pSRetoucheFly2 ( pRetoucheFly2 ), 342 pSFlyOnlyDraw ( pFlyOnlyDraw ), 343 pSLines ( pLines ), 344 pSSubsLines ( pSubsLines ), 345 // --> OD 2005-07-04 #123196# 346 pSSpecSubsLines ( pSpecSubsLines ), 347 // <-- 348 pSProgress ( pProgress ), 349 nSPixelSzW ( nPixelSzW ), 350 nSPixelSzH ( nPixelSzH ), 351 nSHalfPixelSzW ( nHalfPixelSzW ), 352 nSHalfPixelSzH ( nHalfPixelSzH ), 353 nSMinDistPixelW ( nMinDistPixelW ), 354 nSMinDistPixelH ( nMinDistPixelH ), 355 aSGlobalRetoucheColor( aGlobalRetoucheColor ), 356 aSScaleX ( aScaleX ), 357 aSScaleY ( aScaleY ) 358 { 359 bFlyMetafile = sal_False; 360 pFlyMetafileOut = 0; 361 pRetoucheFly = 0; 362 pRetoucheFly2 = 0; 363 nPixelSzW = nPixelSzH = 364 nHalfPixelSzW = nHalfPixelSzH = 365 nMinDistPixelW = nMinDistPixelH = 0; 366 aScaleX = aScaleY = 1.0; 367 aMinDistScale = 0.73; 368 aEdgeScale = 0.5; 369 pLines = 0; 370 pSubsLines = 0; 371 // --> OD 2005-07-04 #123196# 372 pSpecSubsLines = 0L; 373 // <-- 374 pProgress = 0; 375 } 376 377 SwSavePaintStatics::~SwSavePaintStatics() 378 { 379 pGlobalShell = pSGlobalShell; 380 bFlyMetafile = bSFlyMetafile; 381 pFlyMetafileOut = pSFlyMetafileOut; 382 pRetoucheFly = pSRetoucheFly; 383 pRetoucheFly2 = pSRetoucheFly2; 384 pFlyOnlyDraw = pSFlyOnlyDraw; 385 pLines = pSLines; 386 pSubsLines = pSSubsLines; 387 // --> OD 2005-07-04 #123196# 388 pSpecSubsLines = pSSpecSubsLines; 389 // <-- 390 pProgress = pSProgress; 391 nPixelSzW = nSPixelSzW; 392 nPixelSzH = nSPixelSzH; 393 nHalfPixelSzW = nSHalfPixelSzW; 394 nHalfPixelSzH = nSHalfPixelSzH; 395 nMinDistPixelW = nSMinDistPixelW; 396 nMinDistPixelH = nSMinDistPixelH; 397 aGlobalRetoucheColor = aSGlobalRetoucheColor; 398 aScaleX = aSScaleX; 399 aScaleY = aSScaleY; 400 } 401 402 //----------------- Implementierungen fuer Tabellenumrandung -------------- 403 404 SV_IMPL_VARARR( SwLRects, SwLineRect ); 405 406 407 SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol, 408 const SwTabFrm *pT, const sal_uInt8 nSCol ) : 409 SwRect( rRect ), 410 pColor( pCol ), 411 pTab( pT ), 412 nSubColor( nSCol ), 413 bPainted( sal_False ), 414 nLock( 0 ) 415 { 416 } 417 418 sal_Bool SwLineRect::MakeUnion( const SwRect &rRect ) 419 { 420 //Es wurde bereits ausserhalb geprueft, ob die Rechtecke die gleiche 421 //Ausrichtung (horizontal bzw. vertikal), Farbe usw. besitzen. 422 if ( Height() > Width() ) //Vertikale Linie 423 { 424 if ( Left() == rRect.Left() && Width() == rRect.Width() ) 425 { 426 //Zusammenfassen wenn kein Luecke zwischen den Linien ist. 427 const long nAdd = nPixelSzW + nHalfPixelSzW; 428 if ( Bottom() + nAdd >= rRect.Top() && 429 Top() - nAdd <= rRect.Bottom() ) 430 { 431 Bottom( Max( Bottom(), rRect.Bottom() ) ); 432 Top ( Min( Top(), rRect.Top() ) ); 433 return sal_True; 434 } 435 } 436 } 437 else 438 { 439 if ( Top() == rRect.Top() && Height() == rRect.Height() ) 440 { 441 //Zusammenfassen wenn kein Luecke zwischen den Linien ist. 442 const long nAdd = nPixelSzW + nHalfPixelSzW; 443 if ( Right() + nAdd >= rRect.Left() && 444 Left() - nAdd <= rRect.Right() ) 445 { 446 Right( Max( Right(), rRect.Right() ) ); 447 Left ( Min( Left(), rRect.Left() ) ); 448 return sal_True; 449 } 450 } 451 } 452 return sal_False; 453 } 454 455 void SwLineRects::AddLineRect( const SwRect &rRect, const Color *pCol, 456 const SwTabFrm *pTab, const sal_uInt8 nSCol ) 457 { 458 //Rueckwaerts durch, weil Linien die zusammengefasst werden koennen i.d.R. 459 //im gleichen Kontext gepaintet werden. 460 for ( sal_uInt16 i = Count(); i ; ) 461 { 462 SwLineRect &rLRect = operator[](--i); 463 //Pruefen von Ausrichtung, Farbe, Tabelle. 464 if ( rLRect.GetTab() == pTab && 465 !rLRect.IsPainted() && rLRect.GetSubColor() == nSCol && 466 (rLRect.Height() > rLRect.Width()) == (rRect.Height() > rRect.Width()) && 467 ((!rLRect.GetColor() && !pCol) || 468 (rLRect.GetColor() && pCol && *rLRect.GetColor() == *pCol)) ) 469 { 470 if ( rLRect.MakeUnion( rRect ) ) 471 return; 472 } 473 } 474 Insert( SwLineRect( rRect, pCol, pTab, nSCol ), Count() ); 475 } 476 477 void SwLineRects::ConnectEdges( OutputDevice *pOut ) 478 { 479 if ( pOut->GetOutDevType() != OUTDEV_PRINTER ) 480 { 481 //Fuer einen zu kleinen Zoom arbeite ich nicht. 482 if ( aScaleX < aEdgeScale || aScaleY < aEdgeScale ) 483 return; 484 } 485 486 static const long nAdd = 20; 487 488 SvPtrarr aCheck( 64, 64 ); 489 490 for ( int i = 0; i < (int)Count(); ++i ) 491 { 492 SwLineRect &rL1 = operator[](sal_uInt16(i)); 493 if ( !rL1.GetTab() || rL1.IsPainted() || rL1.IsLocked() ) 494 continue; 495 496 aCheck.Remove( 0, aCheck.Count() ); 497 498 const sal_Bool bVert = rL1.Height() > rL1.Width(); 499 long nL1a, nL1b, nL1c, nL1d; 500 501 if ( bVert ) 502 { 503 nL1a = rL1.Top(); nL1b = rL1.Left(); 504 nL1c = rL1.Right(); nL1d = rL1.Bottom(); 505 } 506 else 507 { 508 nL1a = rL1.Left(); nL1b = rL1.Top(); 509 nL1c = rL1.Bottom(); nL1d = rL1.Right(); 510 } 511 512 //Alle moeglicherweise mit i1 zu verbindenden Linien einsammeln. 513 for ( sal_uInt16 i2 = 0; i2 < Count(); ++i2 ) 514 { 515 SwLineRect &rL2 = operator[](i2); 516 if ( rL2.GetTab() != rL1.GetTab() || 517 rL2.IsPainted() || 518 rL2.IsLocked() || 519 (bVert == (rL2.Height() > rL2.Width())) ) 520 continue; 521 522 long nL2a, nL2b, nL2c, nL2d; 523 if ( bVert ) 524 { 525 nL2a = rL2.Top(); nL2b = rL2.Left(); 526 nL2c = rL2.Right(); nL2d = rL2.Bottom(); 527 } 528 else 529 { 530 nL2a = rL2.Left(); nL2b = rL2.Top(); 531 nL2c = rL2.Bottom(); nL2d = rL2.Right(); 532 } 533 534 if ( (nL1a - nAdd < nL2d && nL1d + nAdd > nL2a) && 535 ((nL1b > nL2b && nL1c < nL2c) || 536 (nL1c >= nL2c && nL1b - nAdd < nL2c) || 537 (nL1b <= nL2b && nL1c + nAdd > nL2b)) ) 538 { 539 SwLineRect *pMSC = &rL2; 540 aCheck.Insert( pMSC, aCheck.Count() ); 541 } 542 } 543 if ( aCheck.Count() < 2 ) 544 continue; 545 546 sal_Bool bRemove = sal_False; 547 548 //Fuer jede Linie jede alle folgenden checken. 549 for ( sal_uInt16 k = 0; !bRemove && k < aCheck.Count(); ++k ) 550 { 551 SwLineRect &rR1 = (SwLineRect&)*(SwLineRect*)aCheck[k]; 552 553 for ( sal_uInt16 k2 = k+1; !bRemove && k2 < aCheck.Count(); ++k2 ) 554 { 555 SwLineRect &rR2 = (SwLineRect&)*(SwLineRect*)aCheck[k2]; 556 if ( bVert ) 557 { 558 SwLineRect *pLA = 0; 559 SwLineRect *pLB = 0; 560 if ( rR1.Top() < rR2.Top() ) 561 { 562 pLA = &rR1; pLB = &rR2; 563 } 564 else if ( rR1.Top() > rR2.Top() ) 565 { 566 pLA = &rR2; pLB = &rR1; 567 } 568 //beschreiben k1 und k2 eine Doppellinie? 569 if ( pLA && pLA->Bottom() + 60 > pLB->Top() ) 570 { 571 if ( rL1.Top() < pLA->Top() ) 572 { 573 if ( rL1.Bottom() == pLA->Bottom() ) 574 continue; //kleiner Irrtum (woher?) 575 576 SwRect aIns( rL1 ); 577 aIns.Bottom( pLA->Bottom() ); 578 if ( !rL1.IsInside( aIns ) ) 579 continue; 580 const sal_uInt16 nTmpFree = Free(); 581 Insert( SwLineRect( aIns, rL1.GetColor(), 582 rL1.GetTab(), SUBCOL_TAB ), Count() ); 583 if ( !nTmpFree ) 584 { 585 --i; 586 k = aCheck.Count(); 587 break; 588 } 589 } 590 591 if ( rL1.Bottom() > pLB->Bottom() ) 592 rL1.Top( pLB->Top() ); //i1 nach oben verlaengern 593 else 594 bRemove = sal_True; //abbrechen, i1 entfernen 595 } 596 } 597 else 598 { 599 SwLineRect *pLA = 0; 600 SwLineRect *pLB = 0; 601 if ( rR1.Left() < rR2.Left() ) 602 { 603 pLA = &rR1; pLB = &rR2; 604 } 605 else if ( rR1.Left() > rR2.Left() ) 606 { 607 pLA = &rR2; pLB = &rR1; 608 } 609 //Liegt eine 'doppellinie' vor? 610 if ( pLA && pLA->Right() + 60 > pLB->Left() ) 611 { 612 if ( rL1.Left() < pLA->Left() ) 613 { 614 if ( rL1.Right() == pLA->Right() ) 615 continue; //kleiner irrtum 616 617 SwRect aIns( rL1 ); 618 aIns.Right( pLA->Right() ); 619 if ( !rL1.IsInside( aIns ) ) 620 continue; 621 const sal_uInt16 nTmpFree = Free(); 622 Insert( SwLineRect( aIns, rL1.GetColor(), 623 rL1.GetTab(), SUBCOL_TAB ), Count() ); 624 if ( !nTmpFree ) 625 { 626 --i; 627 k = aCheck.Count(); 628 break; 629 } 630 } 631 if ( rL1.Right() > pLB->Right() ) 632 rL1.Left( pLB->Left() ); 633 else 634 bRemove = sal_True; 635 } 636 } 637 } 638 } 639 if ( bRemove ) 640 { 641 Remove( static_cast<sal_uInt16>(i), 1 ); 642 --i; //keinen auslassen! 643 } 644 } 645 } 646 647 inline void SwSubsRects::Ins( const SwRect &rRect, const sal_uInt8 nSCol ) 648 { 649 //Linien die kuerzer als die breiteste Linienbreite sind werden 650 //nicht aufgenommen. 651 if ( rRect.Height() > DEF_LINE_WIDTH_4 || rRect.Width() > DEF_LINE_WIDTH_4 ) 652 Insert( SwLineRect( rRect, 0, 0, nSCol ), Count()); 653 } 654 655 void SwSubsRects::RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects ) 656 { 657 //Alle Hilfslinien, die sich mit irgendwelchen Umrandungen decken werden 658 //entfernt bzw. zerstueckelt.. 659 for ( sal_uInt16 i = 0; i < Count(); ++i ) 660 { 661 // OD 18.11.2002 #99672# - get a copy instead of a reference, because 662 // an <insert> may destroy the object due to a necessary array resize. 663 const SwLineRect aSubsLineRect = SwLineRect( operator[](i) ); 664 665 // OD 19.12.2002 #106318# - add condition <aSubsLineRect.IsLocked()> 666 // in order to consider only border lines, which are *not* locked. 667 if ( aSubsLineRect.IsPainted() || 668 aSubsLineRect.IsLocked() ) 669 continue; 670 671 const bool bVerticalSubs = aSubsLineRect.Height() > aSubsLineRect.Width(); 672 SwRect aSubsRect( aSubsLineRect ); 673 if ( bVerticalSubs ) 674 { 675 aSubsRect.Left ( aSubsRect.Left() - (nPixelSzW+nHalfPixelSzW) ); 676 aSubsRect.Right ( aSubsRect.Right() + (nPixelSzW+nHalfPixelSzW) ); 677 } 678 else 679 { 680 aSubsRect.Top ( aSubsRect.Top() - (nPixelSzH+nHalfPixelSzH) ); 681 aSubsRect.Bottom( aSubsRect.Bottom() + (nPixelSzH+nHalfPixelSzH) ); 682 } 683 for ( sal_uInt16 k = 0; k < rRects.Count(); ++k ) 684 { 685 SwLineRect &rLine = rRects[k]; 686 687 // OD 20.12.2002 #106318# - do *not* consider painted or locked 688 // border lines. 689 // OD 20.01.2003 #i1837# - locked border lines have to be considered. 690 if ( rLine.IsLocked () ) 691 continue; 692 693 if ( (!bVerticalSubs == (rLine.Height() > rLine.Width())) ) //gleiche Ausrichtung? 694 continue; 695 696 if ( aSubsRect.IsOver( rLine ) ) 697 { 698 if ( bVerticalSubs ) //Vertikal? 699 { 700 if ( aSubsRect.Left() <= rLine.Right() && 701 aSubsRect.Right() >= rLine.Left() ) 702 { 703 long nTmp = rLine.Top()-(nPixelSzH+1); 704 if ( aSubsLineRect.Top() < nTmp ) 705 { 706 SwRect aNewSubsRect( aSubsLineRect ); 707 aNewSubsRect.Bottom( nTmp ); 708 Insert( SwLineRect( aNewSubsRect, 0, 0, 709 aSubsLineRect.GetSubColor() ), Count()); 710 } 711 nTmp = rLine.Bottom()+nPixelSzH+1; 712 if ( aSubsLineRect.Bottom() > nTmp ) 713 { 714 SwRect aNewSubsRect( aSubsLineRect ); 715 aNewSubsRect.Top( nTmp ); 716 Insert( SwLineRect( aNewSubsRect, 0, 0, 717 aSubsLineRect.GetSubColor() ), Count()); 718 } 719 Remove( i, 1 ); 720 --i; 721 break; 722 } 723 } 724 else //Horizontal 725 { 726 if ( aSubsRect.Top() <= rLine.Bottom() && 727 aSubsRect.Bottom() >= rLine.Top() ) 728 { 729 long nTmp = rLine.Left()-(nPixelSzW+1); 730 if ( aSubsLineRect.Left() < nTmp ) 731 { 732 SwRect aNewSubsRect( aSubsLineRect ); 733 aNewSubsRect.Right( nTmp ); 734 Insert( SwLineRect( aNewSubsRect, 0, 0, 735 aSubsLineRect.GetSubColor() ), Count()); 736 } 737 nTmp = rLine.Right()+nPixelSzW+1; 738 if ( aSubsLineRect.Right() > nTmp ) 739 { 740 SwRect aNewSubsRect( aSubsLineRect ); 741 aNewSubsRect.Left( nTmp ); 742 Insert( SwLineRect( aNewSubsRect, 0, 0, 743 aSubsLineRect.GetSubColor() ), Count()); 744 } 745 Remove( i, 1 ); 746 --i; 747 break; 748 } 749 } 750 } 751 } 752 } 753 } 754 755 void SwLineRects::LockLines( sal_Bool bLock ) 756 { 757 for ( sal_uInt16 i = 0; i < Count(); ++i ) 758 operator[](i).Lock( bLock ); 759 } 760 761 void SwLineRects::PaintLines( OutputDevice *pOut ) 762 { 763 //Painten der Umrandungen. Leider muessen wir zweimal durch. 764 //Einmal fuer die innenliegenden und einmal fuer die Aussenkanten 765 //der Tabellen. 766 if ( Count() != nLastCount ) 767 { 768 // --> FME 2004-06-24 #i16816# tagged pdf support 769 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut ); 770 // <-- 771 772 // OD 2004-04-23 #116347# 773 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 774 pOut->SetLineColor(); 775 ConnectEdges( pOut ); 776 const Color *pLast = 0; 777 778 sal_Bool bPaint2nd = sal_False; 779 sal_uInt16 nMinCount = Count(); 780 sal_uInt16 i; 781 782 for ( i = 0; i < Count(); ++i ) 783 { 784 SwLineRect &rLRect = operator[](i); 785 786 if ( rLRect.IsPainted() ) 787 continue; 788 789 if ( rLRect.IsLocked() ) 790 { 791 nMinCount = Min( nMinCount, i ); 792 continue; 793 } 794 795 //Jetzt malen oder erst in der zweiten Runde? 796 sal_Bool bPaint = sal_True; 797 if ( rLRect.GetTab() ) 798 { 799 if ( rLRect.Height() > rLRect.Width() ) 800 { 801 //Senkrechte Kante, ueberlappt sie mit der TabellenKante? 802 SwTwips nLLeft = rLRect.Left() - 30, 803 nLRight = rLRect.Right() + 30, 804 nTLeft = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Left(), 805 nTRight = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Right(); 806 if ( (nTLeft >= nLLeft && nTLeft <= nLRight) || 807 (nTRight>= nLLeft && nTRight<= nLRight) ) 808 bPaint = sal_False; 809 } 810 else 811 { //Waagerechte Kante, ueberlappt sie mit der Tabellenkante? 812 SwTwips nLTop = rLRect.Top() - 30, 813 nLBottom = rLRect.Bottom() + 30, 814 nTTop = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Top(), 815 nTBottom = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Bottom(); 816 if ( (nTTop >= nLTop && nTTop <= nLBottom) || 817 (nTBottom >= nLTop && nTBottom <= nLBottom) ) 818 bPaint = sal_False; 819 } 820 } 821 if ( bPaint ) 822 { 823 if ( !pLast || *pLast != *rLRect.GetColor() ) 824 { 825 pLast = rLRect.GetColor(); 826 827 sal_uLong nOldDrawMode = pOut->GetDrawMode(); 828 if( pGlobalShell->GetWin() && 829 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 830 pOut->SetDrawMode( 0 ); 831 832 pOut->SetFillColor( *pLast ); 833 pOut->SetDrawMode( nOldDrawMode ); 834 } 835 if( !rLRect.IsEmpty() ) 836 pOut->DrawRect( rLRect.SVRect() ); 837 rLRect.SetPainted(); 838 } 839 else 840 bPaint2nd = sal_True; 841 } 842 if ( bPaint2nd ) 843 for ( i = 0; i < Count(); ++i ) 844 { 845 SwLineRect &rLRect = operator[](i); 846 if ( rLRect.IsPainted() ) 847 continue; 848 849 if ( rLRect.IsLocked() ) 850 { 851 nMinCount = Min( nMinCount, i ); 852 continue; 853 } 854 855 if ( !pLast || *pLast != *rLRect.GetColor() ) 856 { 857 pLast = rLRect.GetColor(); 858 859 sal_uLong nOldDrawMode = pOut->GetDrawMode(); 860 if( pGlobalShell->GetWin() && 861 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 862 { 863 pOut->SetDrawMode( 0 ); 864 } 865 866 pOut->SetFillColor( *pLast ); 867 pOut->SetDrawMode( nOldDrawMode ); 868 } 869 if( !rLRect.IsEmpty() ) 870 pOut->DrawRect( rLRect.SVRect() ); 871 rLRect.SetPainted(); 872 } 873 nLastCount = nMinCount; 874 pOut->Pop(); 875 } 876 } 877 878 void SwSubsRects::PaintSubsidiary( OutputDevice *pOut, 879 const SwLineRects *pRects ) 880 { 881 if ( Count() ) 882 { 883 // --> FME 2004-06-24 #i16816# tagged pdf support 884 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut ); 885 // <-- 886 887 //Alle Hilfslinien, die sich fast decken entfernen (Tabellen) 888 for ( sal_uInt16 i = 0; i < Count(); ++i ) 889 { 890 SwLineRect &rLi = operator[](i); 891 const bool bVerticalSubs = rLi.Height() > rLi.Width(); 892 893 for ( sal_uInt16 k = i+1; k < Count(); ++k ) 894 { 895 SwLineRect &rLk = operator[](k); 896 if ( rLi.SSize() == rLk.SSize() ) 897 { 898 if ( (bVerticalSubs == (rLk.Height() > rLk.Width())) ) 899 { 900 if ( bVerticalSubs ) 901 { 902 long nLi = rLi.Right(); 903 long nLk = rLk.Right(); 904 if ( rLi.Top() == rLk.Top() && 905 ((nLi < rLk.Left() && nLi+21 > rLk.Left()) || 906 (nLk < rLi.Left() && nLk+21 > rLi.Left()))) 907 { 908 Remove( k, 1 ); 909 //Nicht mit der inneren Schleife weiter, weil 910 //das Array schrumpfen koennte! 911 --i; k = Count(); 912 } 913 } 914 else 915 { 916 long nLi = rLi.Bottom(); 917 long nLk = rLk.Bottom(); 918 if ( rLi.Left() == rLk.Left() && 919 ((nLi < rLk.Top() && nLi+21 > rLk.Top()) || 920 (nLk < rLi.Top() && nLk+21 > rLi.Top()))) 921 { 922 Remove( k, 1 ); 923 --i; k = Count(); 924 } 925 } 926 } 927 } 928 } 929 } 930 931 932 if ( pRects && pRects->Count() ) 933 RemoveSuperfluousSubsidiaryLines( *pRects ); 934 935 if ( Count() ) 936 { 937 // OD 2004-04-23 #116347# 938 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 939 pOut->SetLineColor(); 940 941 // OD 14.01.2003 #106660# - reset draw mode in high contrast 942 // mode in order to get fill color set at output device. 943 // Recover draw mode after draw of lines. 944 // Necessary for the subsidiary lines painted by the fly frames. 945 sal_uLong nOldDrawMode = pOut->GetDrawMode(); 946 if( pGlobalShell->GetWin() && 947 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 948 { 949 pOut->SetDrawMode( 0 ); 950 } 951 952 for ( sal_uInt16 i = 0; i < Count(); ++i ) 953 { 954 SwLineRect &rLRect = operator[](i); 955 // OD 19.12.2002 #106318# - add condition <!rLRect.IsLocked()> 956 // to prevent paint of locked subsidiary lines. 957 if ( !rLRect.IsPainted() && 958 !rLRect.IsLocked() ) 959 { 960 const Color *pCol = 0; 961 switch ( rLRect.GetSubColor() ) 962 { 963 case SUBCOL_PAGE: pCol = &SwViewOption::GetDocBoundariesColor(); break; 964 case SUBCOL_FLY: pCol = &SwViewOption::GetObjectBoundariesColor(); break; 965 case SUBCOL_TAB: pCol = &SwViewOption::GetTableBoundariesColor(); break; 966 case SUBCOL_SECT: pCol = &SwViewOption::GetSectionBoundColor(); break; 967 case SUBCOL_BREAK: pCol = &SwViewOption::GetPageBreakColor(); break; 968 } 969 970 if ( pOut->GetFillColor() != *pCol ) 971 pOut->SetFillColor( *pCol ); 972 pOut->DrawRect( rLRect.SVRect() ); 973 974 rLRect.SetPainted(); 975 } 976 } 977 978 // OD 14.01.2003 #106660# - recovering draw mode 979 pOut->SetDrawMode( nOldDrawMode ); 980 981 pOut->Pop(); 982 } 983 } 984 } 985 986 //------------------------------------------------------------------------- 987 //Diverse Functions die in diesem File so verwendet werden. 988 989 // OD 20.02.2003 - Note: function <SwAlignRect(..)> also used outside this file. 990 // OD 29.04.2003 #107169# - correction: adjust rectangle on pixel level in order 991 // to assure, that the border 'leaves its original pixel', if it has to. 992 // No prior adjustments for odd relation between pixel and twip. 993 void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh ) 994 { 995 if( !rRect.HasArea() ) 996 return; 997 998 // OD 03.09.2002 #102450# 999 // Assure that view shell (parameter <pSh>) exists, if the output device 1000 // is taken from this view shell --> no output device, no alignment. 1001 // Output device taken from view shell <pSh>, if <bFlyMetafile> not set. 1002 if ( !bFlyMetafile && !pSh ) 1003 { 1004 return; 1005 } 1006 1007 const OutputDevice *pOut = bFlyMetafile ? 1008 pFlyMetafileOut : pSh->GetOut(); 1009 1010 // OD 28.04.2003 #107169# - hold original rectangle in pixel 1011 const Rectangle aOrgPxRect = pOut->LogicToPixel( rRect.SVRect() ); 1012 // OD 29.04.2003 #107169# - determine pixel-center rectangle in twip 1013 const SwRect aPxCenterRect( pOut->PixelToLogic( aOrgPxRect ) ); 1014 1015 // OD 06.05.2003 #107169# - perform adjustments on pixel level. 1016 SwRect aAlignedPxRect( aOrgPxRect ); 1017 if ( rRect.Top() > aPxCenterRect.Top() ) 1018 { 1019 // 'leave pixel overlapping on top' 1020 aAlignedPxRect.Top( aAlignedPxRect.Top() + 1 ); 1021 } 1022 1023 if ( rRect.Bottom() < aPxCenterRect.Bottom() ) 1024 { 1025 // 'leave pixel overlapping on bottom' 1026 aAlignedPxRect.Bottom( aAlignedPxRect.Bottom() - 1 ); 1027 } 1028 1029 if ( rRect.Left() > aPxCenterRect.Left() ) 1030 { 1031 // 'leave pixel overlapping on left' 1032 aAlignedPxRect.Left( aAlignedPxRect.Left() + 1 ); 1033 } 1034 1035 if ( rRect.Right() < aPxCenterRect.Right() ) 1036 { 1037 // 'leave pixel overlapping on right' 1038 aAlignedPxRect.Right( aAlignedPxRect.Right() - 1 ); 1039 } 1040 1041 // OD 11.10.2002 #103636# - consider negative width/height 1042 // check, if aligned SwRect has negative width/height. 1043 // If Yes, adjust it to width/height = 0 twip. 1044 // NOTE: A SwRect with negative width/height can occur, if the width/height 1045 // of the given SwRect in twip was less than a pixel in twip and that 1046 // the alignment calculates that the aligned SwRect should not contain 1047 // the pixels the width/height is on. 1048 if ( aAlignedPxRect.Width() < 0 ) 1049 { 1050 aAlignedPxRect.Width(0); 1051 } 1052 if ( aAlignedPxRect.Height() < 0 ) 1053 { 1054 aAlignedPxRect.Height(0); 1055 } 1056 // OD 30.04.2003 #107169# - consider zero width/height 1057 // For converting a rectangle from pixel to logic it needs a width/height. 1058 // Thus, set width/height to one, if it's zero and correct this on the twip 1059 // level after the conversion. 1060 sal_Bool bZeroWidth = sal_False; 1061 if ( aAlignedPxRect.Width() == 0 ) 1062 { 1063 aAlignedPxRect.Width(1); 1064 bZeroWidth = sal_True; 1065 } 1066 sal_Bool bZeroHeight = sal_False; 1067 if ( aAlignedPxRect.Height() == 0 ) 1068 { 1069 aAlignedPxRect.Height(1); 1070 bZeroHeight = sal_True; 1071 } 1072 1073 rRect = pOut->PixelToLogic( aAlignedPxRect.SVRect() ); 1074 1075 // OD 30.04.2003 #107169# - consider zero width/height and adjust calculated 1076 // aligned twip rectangle. 1077 // OD 19.05.2003 #109667# - reset width/height to zero; previous negative 1078 // width/height haven't to be considered. 1079 if ( bZeroWidth ) 1080 { 1081 rRect.Width(0); 1082 } 1083 if ( bZeroHeight ) 1084 { 1085 rRect.Height(0); 1086 } 1087 } 1088 1089 /** OD 19.05.2003 #109667# - helper method for twip adjustments on pixel base 1090 1091 method compares the x- or y-pixel position of two twip-point. If the x-/y-pixel 1092 positions are the same, the x-/y-pixel position of the second twip point is 1093 adjusted by a given amount of pixels. 1094 1095 @author OD 1096 */ 1097 void lcl_CompPxPosAndAdjustPos( const OutputDevice& _rOut, 1098 const Point& _rRefPt, 1099 Point& _rCompPt, 1100 const sal_Bool _bChkXPos, 1101 const sal_Int8 _nPxAdjustment ) 1102 { 1103 const Point aRefPxPt = _rOut.LogicToPixel( _rRefPt ); 1104 Point aCompPxPt = _rOut.LogicToPixel( _rCompPt ); 1105 1106 if ( _bChkXPos ) 1107 { 1108 if ( aCompPxPt.X() == aRefPxPt.X() ) 1109 { 1110 aCompPxPt.X() += _nPxAdjustment ; 1111 const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt ); 1112 _rCompPt.X() = aAdjustedCompPt.X(); 1113 } 1114 } 1115 else 1116 { 1117 if ( aCompPxPt.Y() == aRefPxPt.Y() ) 1118 { 1119 aCompPxPt.Y() += _nPxAdjustment ; 1120 const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt ); 1121 _rCompPt.Y() = aAdjustedCompPt.Y(); 1122 } 1123 } 1124 } 1125 1126 /** OD 25.09.2002 #99739# - method to pixel-align rectangle for drawing graphic object 1127 1128 Because for drawing a graphic left-top-corner and size coordinations are 1129 used, these coordinations have to be determined on pixel level. 1130 Thus, convert rectangle to pixel and then convert left-top-corner and 1131 size of pixel rectangle back to logic. 1132 This calculation is necessary, because there exists a different between 1133 the convert from logic to pixel of a normal rectangle with its left-top- 1134 and right-bottom-corner and the same convert of the same rectangle 1135 with left-top-corner and size. 1136 Call this method before each <GraphicObject.Draw(...)> 1137 1138 @author OD 1139 */ 1140 void SwAlignGrfRect( SwRect *pGrfRect, const OutputDevice &rOut ) 1141 { 1142 Rectangle aPxRect = rOut.LogicToPixel( pGrfRect->SVRect() ); 1143 pGrfRect->Pos( rOut.PixelToLogic( aPxRect.TopLeft() ) ); 1144 pGrfRect->SSize( rOut.PixelToLogic( aPxRect.GetSize() ) ); 1145 } 1146 1147 long MA_FASTCALL lcl_AlignWidth( const long nWidth ) 1148 { 1149 if ( nWidth ) 1150 { 1151 const long nW = nWidth % nPixelSzW; 1152 1153 if ( !nW || nW > nHalfPixelSzW ) 1154 return Max(1L, nWidth - nHalfPixelSzW); 1155 } 1156 return nWidth; 1157 } 1158 1159 long MA_FASTCALL lcl_AlignHeight( const long nHeight ) 1160 { 1161 if ( nHeight ) 1162 { 1163 const long nH = nHeight % nPixelSzH; 1164 1165 if ( !nH || nH > nHalfPixelSzH ) 1166 return Max(1L, nHeight - nHalfPixelSzH); 1167 } 1168 return nHeight; 1169 } 1170 1171 long MA_FASTCALL lcl_MinHeightDist( const long nDist ) 1172 { 1173 if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale ) 1174 return nDist; 1175 return ::lcl_AlignHeight( Max( nDist, nMinDistPixelH )); 1176 } 1177 1178 long MA_FASTCALL lcl_MinWidthDist( const long nDist ) 1179 { 1180 if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale ) 1181 return nDist; 1182 return ::lcl_AlignWidth( Max( nDist, nMinDistPixelW )); 1183 } 1184 1185 1186 //Ermittelt PrtArea plus Umrandung plus Schatten. 1187 void MA_FASTCALL lcl_CalcBorderRect( SwRect &rRect, const SwFrm *pFrm, 1188 const SwBorderAttrs &rAttrs, 1189 const sal_Bool bShadow ) 1190 { 1191 // OD 23.01.2003 #106386# - special handling for cell frames. 1192 // The printing area of a cell frame is completely enclosed in the frame area 1193 // and a cell frame has no shadow. Thus, for cell frames the calculated 1194 // area equals the frame area. 1195 // Notes: Borders of cell frames in R2L text direction will switch its side 1196 // - left border is painted on the right; right border on the left. 1197 // See <lcl_PaintLeftLine> and <lcl_PaintRightLine>. 1198 if( pFrm->IsSctFrm() ) 1199 { 1200 rRect = pFrm->Prt(); 1201 rRect.Pos() += pFrm->Frm().Pos(); 1202 } 1203 else if ( pFrm->IsCellFrm() ) 1204 rRect = pFrm->Frm(); 1205 else 1206 { 1207 rRect = pFrm->Prt(); 1208 rRect.Pos() += pFrm->Frm().Pos(); 1209 1210 if ( rAttrs.IsLine() || rAttrs.IsBorderDist() || 1211 (bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE) ) 1212 { 1213 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1214 SwRectFn fnRect = pFrm->IsVertical() ? ( pFrm->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 1215 1216 const SvxBoxItem &rBox = rAttrs.GetBox(); 1217 const sal_Bool bTop = 0 != (pFrm->*fnRect->fnGetTopMargin)(); 1218 if ( bTop ) 1219 { 1220 SwTwips nDiff = rBox.GetTop() ? 1221 rBox.CalcLineSpace( BOX_LINE_TOP ) : 1222 ( rAttrs.IsBorderDist() ? 1223 // OD 23.01.2003 #106386# - increase of distance by 1224 // one twip is incorrect. 1225 rBox.GetDistance( BOX_LINE_TOP ) : 0 ); 1226 if( nDiff ) 1227 (rRect.*fnRect->fnSubTop)( nDiff ); 1228 } 1229 1230 const sal_Bool bBottom = 0 != (pFrm->*fnRect->fnGetBottomMargin)(); 1231 if ( bBottom ) 1232 { 1233 SwTwips nDiff = 0; 1234 // --> collapsing borders FME 2005-05-27 #i29550# 1235 if ( pFrm->IsTabFrm() && 1236 ((SwTabFrm*)pFrm)->IsCollapsingBorders() ) 1237 { 1238 // For collapsing borders, we have to add the height of 1239 // the height of the last line 1240 nDiff = ((SwTabFrm*)pFrm)->GetBottomLineSize(); 1241 } 1242 // <-- collapsing 1243 else 1244 { 1245 nDiff = rBox.GetBottom() ? 1246 rBox.CalcLineSpace( BOX_LINE_BOTTOM ) : 1247 ( rAttrs.IsBorderDist() ? 1248 // OD 23.01.2003 #106386# - increase of distance by 1249 // one twip is incorrect. 1250 rBox.GetDistance( BOX_LINE_BOTTOM ) : 0 ); 1251 } 1252 if( nDiff ) 1253 (rRect.*fnRect->fnAddBottom)( nDiff ); 1254 } 1255 1256 if ( rBox.GetLeft() ) 1257 (rRect.*fnRect->fnSubLeft)( rBox.CalcLineSpace( BOX_LINE_LEFT ) ); 1258 else if ( rAttrs.IsBorderDist() ) 1259 // OD 23.01.2003 #106386# - increase of distance by one twip is incorrect. 1260 (rRect.*fnRect->fnSubLeft)( rBox.GetDistance( BOX_LINE_LEFT ) ); 1261 1262 if ( rBox.GetRight() ) 1263 (rRect.*fnRect->fnAddRight)( rBox.CalcLineSpace( BOX_LINE_RIGHT ) ); 1264 else if ( rAttrs.IsBorderDist() ) 1265 // OD 23.01.2003 #106386# - increase of distance by one twip is incorrect. 1266 (rRect.*fnRect->fnAddRight)( rBox.GetDistance( BOX_LINE_RIGHT ) ); 1267 1268 if ( bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE ) 1269 { 1270 const SvxShadowItem &rShadow = rAttrs.GetShadow(); 1271 if ( bTop ) 1272 (rRect.*fnRect->fnSubTop)(rShadow.CalcShadowSpace(SHADOW_TOP)); 1273 (rRect.*fnRect->fnSubLeft)(rShadow.CalcShadowSpace(SHADOW_LEFT)); 1274 if ( bBottom ) 1275 (rRect.*fnRect->fnAddBottom) 1276 (rShadow.CalcShadowSpace( SHADOW_BOTTOM )); 1277 (rRect.*fnRect->fnAddRight)(rShadow.CalcShadowSpace(SHADOW_RIGHT)); 1278 } 1279 } 1280 } 1281 1282 ::SwAlignRect( rRect, pGlobalShell ); 1283 } 1284 1285 void MA_FASTCALL lcl_ExtendLeftAndRight( SwRect& _rRect, 1286 const SwFrm& _rFrm, 1287 const SwBorderAttrs& _rAttrs, 1288 const SwRectFn& _rRectFn ) 1289 { 1290 // OD 21.05.2003 #108789# - extend left/right border/shadow rectangle to 1291 // bottom of previous frame/to top of next frame, if border/shadow is joined 1292 // with previous/next frame. 1293 if ( _rAttrs.JoinedWithPrev( _rFrm ) ) 1294 { 1295 const SwFrm* pPrevFrm = _rFrm.GetPrev(); 1296 (_rRect.*_rRectFn->fnSetTop)( (pPrevFrm->*_rRectFn->fnGetPrtBottom)() ); 1297 } 1298 if ( _rAttrs.JoinedWithNext( _rFrm ) ) 1299 { 1300 const SwFrm* pNextFrm = _rFrm.GetNext(); 1301 (_rRect.*_rRectFn->fnSetBottom)( (pNextFrm->*_rRectFn->fnGetPrtTop)() ); 1302 } 1303 } 1304 1305 1306 //void MA_FASTCALL lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage, 1307 // const SwRect &rRect, SwRegionRects &rRegion ) 1308 //{ 1309 // const SwSortedObjs& rObjs = *pPage->GetSortedObjs(); 1310 // const SwFlyFrm* pSelfFly = pFrm->IsInFly() ? pFrm->FindFlyFrm() : pRetoucheFly2; 1311 // if ( !pRetoucheFly ) 1312 // pRetoucheFly = pRetoucheFly2; 1313 // 1314 // for ( sal_uInt16 j = 0; (j < rObjs.Count()) && rRegion.Count(); ++j ) 1315 // { 1316 // const SwAnchoredObject* pAnchoredObj = rObjs[j]; 1317 // const SdrObject* pSdrObj = pAnchoredObj->GetDrawObj(); 1318 // 1319 // // OD 2004-01-15 #110582# - do not consider invisible objects 1320 // if ( !pPage->GetFmt()->GetDoc()->IsVisibleLayerId( pSdrObj->GetLayer() ) ) 1321 // continue; 1322 // 1323 // if ( !pAnchoredObj->ISA(SwFlyFrm) ) 1324 // continue; 1325 // 1326 // const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); 1327 // 1328 // if ( pSelfFly == pFly || pRetoucheFly == pFly || !rRect.IsOver( pFly->Frm() ) ) 1329 // continue; 1330 // 1331 // if ( !pFly->GetFmt()->GetPrint().GetValue() && 1332 // (OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() || 1333 // pGlobalShell->IsPreView())) 1334 // continue; 1335 // 1336 // const sal_Bool bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly ) ? 1337 // sal_True : sal_False; 1338 // 1339 // //Bei zeichengebundenem Fly nur diejenigen betrachten, in denen er 1340 // //nicht selbst verankert ist. 1341 // //#33429# Warum nur bei zeichengebundenen? Es macht doch nie Sinn 1342 // //Rahmen abzuziehen in denen er selbst verankert ist oder? 1343 // if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) ) 1344 // continue; 1345 // 1346 // //#57194# Und warum gilt das nicht analog fuer den RetoucheFly? 1347 // if ( pRetoucheFly && pRetoucheFly->IsLowerOf( pFly ) ) 1348 // continue; 1349 // 1350 // 1351 //#ifdef DBG_UTIL 1352 // //Flys, die innerhalb des eigenen verankert sind, muessen eine 1353 // //groessere OrdNum haben oder Zeichengebunden sein. 1354 // if ( pSelfFly && bLowerOfSelf ) 1355 // { 1356 // ASSERT( pFly->IsFlyInCntFrm() || 1357 // pSdrObj->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(), 1358 // "Fly with wrong z-Order" ); 1359 // } 1360 //#endif 1361 // 1362 // sal_Bool bStopOnHell = sal_True; 1363 // if ( pSelfFly ) 1364 // { 1365 // const SdrObject *pTmp = pSelfFly->GetVirtDrawObj(); 1366 // if ( pSdrObj->GetLayer() == pTmp->GetLayer() ) 1367 // { 1368 // if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() ) 1369 // //Im gleichen Layer werden nur obenliegende beachtet. 1370 // continue; 1371 // } 1372 // else 1373 // { 1374 // if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() ) 1375 // //Aus anderem Layer interessieren uns nur nicht transparente 1376 // //oder innenliegende 1377 // continue; 1378 // bStopOnHell = sal_False; 1379 // } 1380 // } 1381 // if ( pRetoucheFly ) 1382 // { 1383 // const SdrObject *pTmp = pRetoucheFly->GetVirtDrawObj(); 1384 // if ( pSdrObj->GetLayer() == pTmp->GetLayer() ) 1385 // { 1386 // if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() ) 1387 // //Im gleichen Layer werden nur obenliegende beachtet. 1388 // continue; 1389 // } 1390 // else 1391 // { 1392 // if ( !pFly->IsLowerOf( pRetoucheFly ) && !pFly->GetFmt()->GetOpaque().GetValue() ) 1393 // //Aus anderem Layer interessieren uns nur nicht transparente 1394 // //oder innenliegende 1395 // continue; 1396 // bStopOnHell = sal_False; 1397 // } 1398 // } 1399 // 1400 // //Wenn der Inhalt des Fly Transparent ist, wird er nicht abgezogen, es sei denn 1401 // //er steht im Hell-Layer (#31941#) 1402 // const IDocumentDrawModelAccess* pIDDMA = pFly->GetFmt()->getIDocumentDrawModelAccess(); 1403 // sal_Bool bHell = pSdrObj->GetLayer() == pIDDMA->GetHellId(); 1404 // if ( (bStopOnHell && bHell) || 1405 // /// OD 05.08.2002 - change internal order of condition 1406 // /// first check "!bHell", then "..->Lower()" and "..->IsNoTxtFrm()" 1407 // /// have not to be performed, if frame is in "Hell" 1408 // ( !bHell && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() && 1409 // ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() || 1410 // ((SwNoTxtFrm*)pFly->Lower())->HasAnimation() || 1411 // pFly->GetFmt()->GetSurround().IsContour() 1412 // ) 1413 // ) 1414 // ) 1415 // continue; 1416 // 1417 // // OD 08.10.2002 #103898# 1418 // // Own if-statements for transparent background/shadow of fly frames 1419 // // (#99657#) in order to handle special conditions. 1420 // if ( pFly->IsBackgroundTransparent() ) 1421 // { 1422 // // Background <pFly> is transparent drawn. Thus normally, its region 1423 // // have not to be substracted from given region. 1424 // // But, if method is called for a fly frame and 1425 // // <pFly> is a direct lower of this fly frame and 1426 // // <pFly> inherites its transparent background brush from its parent, 1427 // // then <pFly> frame area have to be subtracted from given region. 1428 // // NOTE: Because in Status Quo transparent backgrounds can only be 1429 // // assigned to fly frames, the handle of this special case 1430 // // avoids drawing of transparent areas more than once, if 1431 // // a fly frame inherites a transparent background from its 1432 // // parent fly frame. 1433 // if ( pFrm->IsFlyFrm() && 1434 // (pFly->GetAnchorFrm()->FindFlyFrm() == pFrm) && 1435 // static_cast<const SwFlyFrmFmt*>(pFly->GetFmt())->IsBackgroundBrushInherited() 1436 // ) 1437 // { 1438 // SwRect aRect; 1439 // SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly ); 1440 // const SwBorderAttrs &rAttrs = *aAccess.Get(); 1441 // ::lcl_CalcBorderRect( aRect, pFly, rAttrs, sal_True ); 1442 // rRegion -= aRect; 1443 // continue; 1444 // } 1445 // else 1446 // { 1447 // continue; 1448 // } 1449 // } 1450 // if ( pFly->IsShadowTransparent() ) 1451 // { 1452 // continue; 1453 // } 1454 // 1455 // if ( bHell && pFly->GetAnchorFrm()->IsInFly() ) 1456 // { 1457 // //Damit die Umrandung nicht vom Hintergrund des anderen Flys 1458 // //zerlegt wird. 1459 // SwRect aRect; 1460 // SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly ); 1461 // const SwBorderAttrs &rAttrs = *aAccess.Get(); 1462 // ::lcl_CalcBorderRect( aRect, pFly, rAttrs, sal_True ); 1463 // rRegion -= aRect; 1464 // } 1465 // else 1466 // { 1467 // SwRect aRect( pFly->Prt() ); 1468 // aRect += pFly->Frm().Pos(); 1469 // rRegion -= aRect; 1470 // } 1471 // } 1472 // if ( pRetoucheFly == pRetoucheFly2 ) 1473 // pRetoucheFly = 0; 1474 //} 1475 1476 // --> OD 2008-05-16 #i84659# - no longer needed 1477 //inline sal_Bool IsShortCut( const SwRect &rRect, const SwRect &rFrmRect ) 1478 //{ 1479 // //Wenn der Frm vollstaendig rechts neben bzw. unter dem 1480 // //Rect sitzt ist's genug mit Painten. 1481 // return rFrmRect.Top() > rRect.Bottom(); 1482 // // PAGES01 || (rFrmRect.Left() > rRect.Right()) ); 1483 //} 1484 // <-- 1485 1486 //---------------- Ausgabe fuer das BrushItem ---------------- 1487 1488 /** lcl_DrawGraphicBackgrd - local help method to draw a background for a graphic 1489 1490 OD 17.10.2002 #103876# 1491 Under certain circumstances we have to draw a background for a graphic. 1492 This method takes care of the conditions and draws the background with the 1493 corresponding color. 1494 Method introduced for bug fix #103876# in order to optimize drawing tiled 1495 background graphics. Previously, this code was integrated in method 1496 <lcl_DrawGraphic>. 1497 Method implemented as a inline, checking the conditions and calling method 1498 method <lcl_implDrawGraphicBackgrd(..)> for the intrinsic drawing. 1499 1500 @author OD 1501 1502 @param _rBackgrdBrush 1503 background brush contain the color the background has to be drawn. 1504 1505 @param _pOut 1506 output device the background has to be drawn in. 1507 1508 @param _rPaintRect 1509 paint retangle in the output device, which has to be drawn with the background. 1510 rectangle have to be aligned by method ::SwAlignRect 1511 1512 @param _rGraphicObj 1513 graphic object, for which the background has to be drawn. Used for checking 1514 the transparency of its bitmap, its type and if the graphic is drawn transparent 1515 1516 @param _bNumberingGraphic 1517 boolean indicating that graphic is used as a numbering. 1518 1519 @param _bBackgrdAlreadyDrawn 1520 boolean (optional; default: false) indicating, if the background is already drawn. 1521 */ 1522 void lcl_implDrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush, 1523 OutputDevice* _pOut, 1524 const SwRect& _rAlignedPaintRect, 1525 const GraphicObject& _rGraphicObj ) 1526 { 1527 /// determine color of background 1528 /// If color of background brush is not "no fill"/"auto fill" or 1529 /// <bFlyMetafile> is set, use color of background brush, otherwise 1530 /// use global retouche color. 1531 const Color aColor( ( (_rBackgrdBrush.GetColor() != COL_TRANSPARENT) || bFlyMetafile ) 1532 ? _rBackgrdBrush.GetColor() 1533 : aGlobalRetoucheColor ); 1534 1535 /// determine, if background color have to be drawn transparent 1536 /// and calculate transparency percent value 1537 sal_Int8 nTransparencyPercent = 0; 1538 bool bDrawTransparent = false; 1539 if ( aColor.GetTransparency() != 0 ) 1540 /// background color is transparent --> draw transparent. 1541 { 1542 bDrawTransparent = true; 1543 nTransparencyPercent = (aColor.GetTransparency()*100 + 0x7F)/0xFF; 1544 } 1545 else if ( (_rGraphicObj.GetAttr().GetTransparency() != 0) && 1546 (_rBackgrdBrush.GetColor() == COL_TRANSPARENT) ) 1547 /// graphic is drawn transparent and background color is 1548 /// "no fill"/"auto fill" --> draw transparent 1549 { 1550 bDrawTransparent = true; 1551 nTransparencyPercent = (_rGraphicObj.GetAttr().GetTransparency()*100 + 0x7F)/0xFF; 1552 } 1553 1554 if ( bDrawTransparent ) 1555 { 1556 /// draw background transparent 1557 if( _pOut->GetFillColor() != aColor.GetRGBColor() ) 1558 _pOut->SetFillColor( aColor.GetRGBColor() ); 1559 PolyPolygon aPoly( _rAlignedPaintRect.SVRect() ); 1560 _pOut->DrawTransparent( aPoly, nTransparencyPercent ); 1561 } 1562 else 1563 { 1564 /// draw background opaque 1565 if ( _pOut->GetFillColor() != aColor ) 1566 _pOut->SetFillColor( aColor ); 1567 _pOut->DrawRect( _rAlignedPaintRect.SVRect() ); 1568 } 1569 } 1570 1571 inline void lcl_DrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush, 1572 OutputDevice* _pOut, 1573 const SwRect& _rAlignedPaintRect, 1574 const GraphicObject& _rGraphicObj, 1575 bool _bNumberingGraphic, 1576 bool _bBackgrdAlreadyDrawn = false ) 1577 { 1578 /// draw background with background color, if 1579 /// (1) graphic is not used as a numbering AND 1580 /// (2) background is not already drawn AND 1581 /// (3) intrinsic graphic is transparent OR intrinsic graphic doesn't exists 1582 if ( !_bNumberingGraphic && 1583 !_bBackgrdAlreadyDrawn && 1584 ( _rGraphicObj.IsTransparent() || _rGraphicObj.GetType() == GRAPHIC_NONE ) 1585 ) 1586 { 1587 lcl_implDrawGraphicBackgrd( _rBackgrdBrush, _pOut, _rAlignedPaintRect, _rGraphicObj ); 1588 } 1589 } 1590 1591 /// OD 06.08.2002 #99657# - Note: the transparency of the background graphic 1592 /// is saved in SvxBrushItem.GetGraphicObject(<shell>).GetAttr().Set/GetTransparency() 1593 /// and is considered in the drawing of the graphic. 1594 /// Thus, to provide transparent background graphic for text frames nothing 1595 /// has to be coded. 1596 /// OD 25.09.2002 #99739# - use align rectangle for drawing graphic 1597 /// OD 25.09.2002 #99739# - pixel-align coordinations for drawing graphic. 1598 /// OD 17.10.2002 #103876# - outsource code for drawing background of the graphic 1599 /// with a background color in method <lcl_DrawGraphicBackgrd> 1600 /// Also, change type of <bGrfNum> and <bClip> from <sal_Bool> to <bool>. 1601 void lcl_DrawGraphic( const SvxBrushItem& rBrush, OutputDevice *pOut, 1602 ViewShell &rSh, const SwRect &rGrf, const SwRect &rOut, 1603 bool bClip, bool bGrfNum, 1604 bool bBackgrdAlreadyDrawn = false ) 1605 /// OD 02.09.2002 #99657# 1606 /// add parameter <bBackgrdAlreadyDrawn> to indicate 1607 /// that the background is already drawn. 1608 { 1609 /// OD 25.09.2002 #99739# - calculate align rectangle from parameter <rGrf> 1610 /// and use aligned rectangle <aAlignedGrfRect> in the following code 1611 SwRect aAlignedGrfRect = rGrf; 1612 ::SwAlignRect( aAlignedGrfRect, &rSh ); 1613 1614 /// OD 17.10.2002 #103876# - change type from <sal_Bool> to <bool>. 1615 const bool bNotInside = bClip && !rOut.IsInside( aAlignedGrfRect ); 1616 if ( bNotInside ) 1617 { 1618 pOut->Push( PUSH_CLIPREGION ); 1619 pOut->IntersectClipRegion( rOut.SVRect() ); 1620 } 1621 1622 //Hier kein Link, wir wollen die Grafik synchron laden! 1623 ((SvxBrushItem&)rBrush).SetDoneLink( Link() ); 1624 GraphicObject *pGrf = (GraphicObject*)rBrush.GetGraphicObject(); 1625 1626 /// OD 17.10.2002 #103876# - outsourcing drawing of background with a background color. 1627 ::lcl_DrawGraphicBackgrd( rBrush, pOut, aAlignedGrfRect, *pGrf, bGrfNum, bBackgrdAlreadyDrawn ); 1628 1629 /// OD 25.09.2002 #99739# - 1630 /// Because for drawing a graphic left-top-corner and size coordinations are 1631 /// used, these coordinations have to be determined on pixel level. 1632 ::SwAlignGrfRect( &aAlignedGrfRect, *pOut ); 1633 pGrf->DrawWithPDFHandling( *pOut, aAlignedGrfRect.Pos(), aAlignedGrfRect.SSize() ); 1634 1635 if ( bNotInside ) 1636 pOut->Pop(); 1637 } // end of method <lcl_DrawGraphic> 1638 1639 bool MA_FASTCALL DrawFillAttributes( 1640 const FillAttributesPtr& rFillAttributes, 1641 const SwRect& rOriginalLayoutRect, 1642 const SwRect& rPaintRect, 1643 OutputDevice& rOut) 1644 { 1645 static bool bUseNew(true); 1646 static bool bReturnWhenNew(true); 1647 1648 if(bUseNew && rFillAttributes.get() && rFillAttributes->isUsed()) 1649 { 1650 const basegfx::B2DRange aPaintRange( 1651 rPaintRect.Left(), 1652 rPaintRect.Top(), 1653 rPaintRect.Right(), 1654 rPaintRect.Bottom()); 1655 1656 if(!aPaintRange.isEmpty() && 1657 !basegfx::fTools::equalZero(aPaintRange.getWidth()) && 1658 !basegfx::fTools::equalZero(aPaintRange.getHeight())) 1659 { 1660 const basegfx::B2DRange aDefineRange( 1661 rOriginalLayoutRect.Left(), 1662 rOriginalLayoutRect.Top(), 1663 rOriginalLayoutRect.Right(), 1664 rOriginalLayoutRect.Bottom()); 1665 1666 const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rFillAttributes->getPrimitive2DSequence( 1667 aPaintRange, 1668 aDefineRange); 1669 1670 if(rSequence.getLength()) 1671 { 1672 const drawinglayer::geometry::ViewInformation2D aViewInformation2D( 1673 basegfx::B2DHomMatrix(), 1674 rOut.GetViewTransformation(), 1675 aPaintRange, 1676 0, 1677 0.0, 1678 uno::Sequence< beans::PropertyValue >()); 1679 drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice( 1680 rOut, 1681 aViewInformation2D); 1682 1683 if(pProcessor) 1684 { 1685 pProcessor->process(rSequence); 1686 1687 delete pProcessor; 1688 1689 if(bReturnWhenNew) 1690 { 1691 return true; 1692 } 1693 } 1694 } 1695 } 1696 } 1697 1698 return false; 1699 } 1700 1701 void MA_FASTCALL DrawGraphic( 1702 const SvxBrushItem *pBrush, 1703 OutputDevice *pOutDev, 1704 const SwRect &rOrg, 1705 const SwRect &rOut, 1706 const sal_uInt8 nGrfNum, 1707 const sal_Bool bConsiderBackgroundTransparency ) 1708 /// OD 05.08.2002 #99657# - add 6th parameter to indicate that method should 1709 /// consider background transparency, saved in the color of the brush item 1710 { 1711 ViewShell &rSh = *pGlobalShell; 1712 /// OD 17.10.2002 #103876# - change type from <sal_Bool> to <bool> 1713 bool bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum; 1714 bool bGrfNum = GRFNUM_NO != nGrfNum; 1715 Size aGrfSize; 1716 SvxGraphicPosition ePos = GPOS_NONE; 1717 if( pBrush && !bReplaceGrfNum ) 1718 { 1719 if( rSh.GetViewOptions()->IsGraphic() ) 1720 { 1721 //#125488#: load graphic directly in PDF import 1722 // --> OD 2006-08-25 #i68953# - also during print load graphic directly. 1723 if ( (rSh).GetViewOptions()->IsPDFExport() || 1724 rSh.GetOut()->GetOutDevType() == OUTDEV_PRINTER ) 1725 // <-- 1726 { 1727 ((SvxBrushItem*)pBrush)->PurgeMedium(); 1728 ((SvxBrushItem*)pBrush)->SetDoneLink( Link() ); 1729 } 1730 else 1731 ((SvxBrushItem*)pBrush)->SetDoneLink( STATIC_LINK( 1732 rSh.GetDoc(), SwDoc, BackgroundDone ) ); 1733 //SfxObjectShell &rObjSh = *GETOBJSHELL(); 1734 const Graphic* pGrf = pBrush->GetGraphic(); 1735 if( pGrf && GRAPHIC_NONE != pGrf->GetType() ) 1736 { 1737 ePos = pBrush->GetGraphicPos(); 1738 if( pGrf->IsSupportedGraphic() ) 1739 // don't the use the specific output device! Bug 94802 1740 aGrfSize = ::GetGraphicSizeTwip( *pGrf, 0 ); 1741 } 1742 } 1743 else 1744 bReplaceGrfNum = bGrfNum; 1745 } 1746 1747 SwRect aGrf; 1748 aGrf.SSize( aGrfSize ); 1749 sal_Bool bDraw = sal_True; 1750 sal_Bool bRetouche = sal_True; 1751 switch ( ePos ) 1752 { 1753 case GPOS_LT: 1754 aGrf.Pos() = rOrg.Pos(); 1755 break; 1756 1757 case GPOS_MT: 1758 aGrf.Pos().Y() = rOrg.Top(); 1759 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2; 1760 break; 1761 1762 case GPOS_RT: 1763 aGrf.Pos().Y() = rOrg.Top(); 1764 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width(); 1765 break; 1766 1767 case GPOS_LM: 1768 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2; 1769 aGrf.Pos().X() = rOrg.Left(); 1770 break; 1771 1772 case GPOS_MM: 1773 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2; 1774 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2; 1775 break; 1776 1777 case GPOS_RM: 1778 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2; 1779 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width(); 1780 break; 1781 1782 case GPOS_LB: 1783 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height(); 1784 aGrf.Pos().X() = rOrg.Left(); 1785 break; 1786 1787 case GPOS_MB: 1788 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height(); 1789 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2; 1790 break; 1791 1792 case GPOS_RB: 1793 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height(); 1794 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width(); 1795 break; 1796 1797 case GPOS_AREA: 1798 aGrf = rOrg; 1799 /// OD 05.09.2002 #102912# 1800 /// In spite the fact that the background graphic have to fill the complete 1801 /// area, it has been checked, if the graphic will completely fill out 1802 /// the region to be painted <rOut> and thus, nothing has to be retouched. 1803 /// For example, this is the case for a fly frame without a background 1804 /// brush positioned on the border of the page and inherited the 1805 /// background brush from the page. 1806 bRetouche = !rOut.IsInside( aGrf ); 1807 break; 1808 1809 case GPOS_TILED: 1810 { 1811 // OD 17.10.2002 #103876# - draw background of tiled graphic 1812 // before drawing tiled graphic in loop 1813 // determine graphic object 1814 GraphicObject* pGraphicObj = const_cast< GraphicObject* >(pBrush->GetGraphicObject()); 1815 // calculate aligned paint rectangle 1816 SwRect aAlignedPaintRect = rOut; 1817 ::SwAlignRect( aAlignedPaintRect, &rSh ); 1818 // OD 25.10.2002 #103876# - draw background color for aligned paint rectangle 1819 lcl_DrawGraphicBackgrd( *pBrush, pOutDev, aAlignedPaintRect, *pGraphicObj, bGrfNum ); 1820 1821 // set left-top-corner of background graphic to left-top-corner of the 1822 // area, from which the background brush is determined. 1823 aGrf.Pos() = rOrg.Pos(); 1824 // setup clipping at output device 1825 pOutDev->Push( PUSH_CLIPREGION ); 1826 pOutDev->IntersectClipRegion( rOut.SVRect() ); 1827 // OD 28.10.2002 #103876# - use new method <GraphicObject::DrawTiled(::)> 1828 { 1829 // calculate paint offset 1830 Point aPaintOffset( aAlignedPaintRect.Pos() - aGrf.Pos() ); 1831 // draw background graphic tiled for aligned paint rectangle 1832 // --> OD 2005-02-15 #i42643# - apply fix #104004# for Calc 1833 // also for Writer - see /sc/source/view/printfun.cxx 1834 // For PDF export, every draw operation for bitmaps takes a 1835 // noticeable amount of place (~50 characters). Thus, optimize 1836 // between tile bitmap size and number of drawing operations here. 1837 // 1838 // A_out 1839 // n_chars = k1 * ---------- + k2 * A_bitmap 1840 // A_bitmap 1841 // 1842 // minimum n_chars is obtained for (derive for A_bitmap, 1843 // set to 0, take positive solution): 1844 // k1 1845 // A_bitmap = Sqrt( ---- A_out ) 1846 // k2 1847 // 1848 // where k1 is the number of chars per draw operation, and 1849 // k2 is the number of chars per bitmap pixel. 1850 // This is approximately 50 and 7 for current PDF writer, respectively. 1851 // 1852 const double k1( 50 ); 1853 const double k2( 7 ); 1854 const Size aSize( aAlignedPaintRect.SSize() ); 1855 const double Abitmap( k1/k2 * static_cast<double>(aSize.Width())*aSize.Height() ); 1856 1857 pGraphicObj->DrawTiled( pOutDev, 1858 aAlignedPaintRect.SVRect(), 1859 aGrf.SSize(), 1860 Size( aPaintOffset.X(), aPaintOffset.Y() ), 1861 NULL, GRFMGR_DRAW_STANDARD, 1862 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) ); 1863 // <-- 1864 } 1865 // reset clipping at output device 1866 pOutDev->Pop(); 1867 // set <bDraw> and <bRetouche> to false, indicating that background 1868 // graphic and background are already drawn. 1869 bDraw = bRetouche = sal_False; 1870 } 1871 break; 1872 1873 case GPOS_NONE: 1874 bDraw = sal_False; 1875 break; 1876 1877 default: ASSERT( !pOutDev, "new Graphic position?" ); 1878 } 1879 1880 /// OD 02.09.2002 #99657# 1881 /// init variable <bGrfBackgrdAlreadDrawn> to indicate, if background of 1882 /// graphic is already drawn or not. 1883 bool bGrfBackgrdAlreadyDrawn = false; 1884 if ( bRetouche ) 1885 { 1886 // OD 2004-04-23 #116347# 1887 pOutDev->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 1888 pOutDev->SetLineColor(); 1889 1890 // OD 07.08.2002 #99657# #GetTransChg# 1891 // check, if a existing background graphic (not filling the complete 1892 // background) is transparent drawn and the background color is 1893 // "no fill" respectively "auto fill", if background transparency 1894 // has to be considered. 1895 // If YES, memorise transparency of background graphic. 1896 // check also, if background graphic bitmap is transparent. 1897 bool bTransparentGrfWithNoFillBackgrd = false; 1898 sal_Int32 nGrfTransparency = 0; 1899 bool bGrfIsTransparent = false; 1900 if ( (ePos != GPOS_NONE) && 1901 (ePos != GPOS_TILED) && (ePos != GPOS_AREA) 1902 ) 1903 { 1904 GraphicObject *pGrf = (GraphicObject*)pBrush->GetGraphicObject(); 1905 if ( bConsiderBackgroundTransparency ) 1906 { 1907 GraphicAttr pGrfAttr = pGrf->GetAttr(); 1908 if ( (pGrfAttr.GetTransparency() != 0) && 1909 ( pBrush && (pBrush->GetColor() == COL_TRANSPARENT) ) 1910 ) 1911 { 1912 bTransparentGrfWithNoFillBackgrd = true; 1913 nGrfTransparency = pGrfAttr.GetTransparency(); 1914 } 1915 } 1916 if ( pGrf->IsTransparent() ) 1917 { 1918 bGrfIsTransparent = true; 1919 } 1920 } 1921 1922 /// OD 06.08.2002 #99657# #GetTransChg# - to get color of brush, 1923 /// check background color against COL_TRANSPARENT ("no fill"/"auto fill") 1924 /// instead of checking, if transparency is not set. 1925 const Color aColor( pBrush && 1926 ( !(pBrush->GetColor() == COL_TRANSPARENT) || 1927 bFlyMetafile ) 1928 ? pBrush->GetColor() 1929 : aGlobalRetoucheColor ); 1930 1931 /// OD 08.08.2002 #99657# - determine, if background region have to be 1932 /// drawn transparent. 1933 /// background region has to be drawn transparent, if 1934 /// background transparency have to be considered 1935 /// AND 1936 /// ( background color is transparent OR 1937 /// background graphic is transparent and background color is "no fill" 1938 /// ) 1939 sal_Bool bDrawTransparent = bConsiderBackgroundTransparency && 1940 ( ( aColor.GetTransparency() != 0) || 1941 bTransparentGrfWithNoFillBackgrd ); 1942 1943 // --> OD 2008-06-02 #i75614# 1944 // reset draw mode in high contrast mode in order to get fill color set 1945 const sal_uLong nOldDrawMode = pOutDev->GetDrawMode(); 1946 if ( pGlobalShell->GetWin() && 1947 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 1948 { 1949 pOutDev->SetDrawMode( 0 ); 1950 } 1951 // <-- 1952 1953 /// OD 06.08.2002 #99657# - if background region have to be drawn 1954 /// transparent, set only the RGB values of the background color as 1955 /// the fill color for the output device. 1956 if ( bDrawTransparent ) 1957 { 1958 if( pOutDev->GetFillColor() != aColor.GetRGBColor() ) 1959 pOutDev->SetFillColor( aColor.GetRGBColor() ); 1960 } 1961 else 1962 { 1963 if( pOutDev->GetFillColor() != aColor ) 1964 pOutDev->SetFillColor( aColor ); 1965 } 1966 1967 // --> OD 2008-06-02 #i75614# 1968 // restore draw mode 1969 pOutDev->SetDrawMode( nOldDrawMode ); 1970 // <-- 1971 1972 /// OD 02.09.2002 #99657# 1973 if ( bDrawTransparent ) 1974 { 1975 /// background region have to be drawn transparent. 1976 /// Thus, create a poly-polygon from the region and draw it with 1977 /// the corresponding transparency precent. 1978 PolyPolygon aDrawPoly( rOut.SVRect() ); 1979 if ( aGrf.HasArea() ) 1980 { 1981 if ( !bGrfIsTransparent ) 1982 { 1983 /// substract area of background graphic from draw area 1984 /// OD 08.10.2002 #103898# - consider only that part of the 1985 /// graphic area that is overlapping with draw area. 1986 SwRect aTmpGrf = aGrf; 1987 aTmpGrf.Intersection( rOut ); 1988 if ( aTmpGrf.HasArea() ) 1989 { 1990 Polygon aGrfPoly( aTmpGrf.SVRect() ); 1991 aDrawPoly.Insert( aGrfPoly ); 1992 } 1993 } 1994 else 1995 bGrfBackgrdAlreadyDrawn = true; 1996 } 1997 /// calculate transparency percent: 1998 /// ( <transparency value[0x01..0xFF]>*100 + 0x7F ) / 0xFF 1999 /// If there is a background graphic with a background color "no fill"/"auto fill", 2000 /// the transparency value is taken from the background graphic, 2001 /// otherwise take the transparency value from the color. 2002 sal_Int8 nTransparencyPercent = static_cast<sal_Int8>( 2003 (( bTransparentGrfWithNoFillBackgrd ? nGrfTransparency : aColor.GetTransparency() 2004 )*100 + 0x7F)/0xFF); 2005 /// draw poly-polygon transparent 2006 pOutDev->DrawTransparent( aDrawPoly, nTransparencyPercent ); 2007 } 2008 else 2009 { 2010 SwRegionRects aRegion( rOut, 4 ); 2011 if ( !bGrfIsTransparent ) 2012 aRegion -= aGrf; 2013 else 2014 bGrfBackgrdAlreadyDrawn = true; 2015 /// loop rectangles of background region, which has to be drawn 2016 for( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 2017 { 2018 pOutDev->DrawRect( aRegion[i].SVRect() ); 2019 } 2020 } 2021 pOutDev ->Pop(); 2022 } 2023 2024 if( bDraw && aGrf.IsOver( rOut ) ) 2025 /// OD 02.09.2002 #99657# 2026 /// add parameter <bGrfBackgrdAlreadyDrawn> 2027 lcl_DrawGraphic( *pBrush, pOutDev, rSh, aGrf, rOut, true, bGrfNum, 2028 bGrfBackgrdAlreadyDrawn ); 2029 2030 if( bReplaceGrfNum ) 2031 { 2032 const BitmapEx& rBmp = ViewShell::GetReplacementBitmap( false ); 2033 Font aTmp( pOutDev->GetFont() ); 2034 Graphic::DrawEx( pOutDev, aEmptyStr, aTmp, rBmp, rOrg.Pos(), rOrg.SSize() ); 2035 } 2036 } 2037 2038 //------------------------------------------------------------------------ 2039 2040 /** local help method for SwRootFrm::Paint(..) - Adjust given rectangle to pixel size 2041 2042 By OD at 27.09.2002 for #103636# 2043 In order to avoid paint errors caused by multiple alignments - e.g. method 2044 ::SwAlignRect(..) - and other changes to the rectangle to be painted, 2045 this method is called for the rectangle to be painted in order to 2046 adjust it to the pixel it is overlapping. 2047 2048 @author OD 2049 */ 2050 void lcl_AdjustRectToPixelSize( SwRect& io_aSwRect, const OutputDevice &aOut ) 2051 { 2052 /// local constant object of class <Size> to determine number of Twips 2053 /// representing a pixel. 2054 const Size aTwipToPxSize( aOut.PixelToLogic( Size( 1,1 )) ); 2055 2056 /// local object of class <Rectangle> in Twip coordinates 2057 /// calculated from given rectangle aligned to pixel centers. 2058 const Rectangle aPxCenterRect = aOut.PixelToLogic( 2059 aOut.LogicToPixel( io_aSwRect.SVRect() ) ); 2060 2061 /// local constant object of class <Rectangle> representing given rectangle 2062 /// in pixel. 2063 const Rectangle aOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() ); 2064 2065 /// calculate adjusted rectangle from pixel centered rectangle. 2066 /// Due to rounding differences <aPxCenterRect> doesn't exactly represents 2067 /// the Twip-centers. Thus, adjust borders by half of pixel width/height plus 1. 2068 /// Afterwards, adjust calculated Twip-positions of the all borders. 2069 Rectangle aSizedRect = aPxCenterRect; 2070 aSizedRect.Left() -= (aTwipToPxSize.Width()/2 + 1); 2071 aSizedRect.Right() += (aTwipToPxSize.Width()/2 + 1); 2072 aSizedRect.Top() -= (aTwipToPxSize.Height()/2 + 1); 2073 aSizedRect.Bottom() += (aTwipToPxSize.Height()/2 + 1); 2074 2075 /// adjust left() 2076 while ( (aOut.LogicToPixel(aSizedRect)).Left() < aOrgPxRect.Left() ) 2077 { 2078 ++aSizedRect.Left(); 2079 } 2080 /// adjust right() 2081 while ( (aOut.LogicToPixel(aSizedRect)).Right() > aOrgPxRect.Right() ) 2082 { 2083 --aSizedRect.Right(); 2084 } 2085 /// adjust top() 2086 while ( (aOut.LogicToPixel(aSizedRect)).Top() < aOrgPxRect.Top() ) 2087 { 2088 ++aSizedRect.Top(); 2089 } 2090 /// adjust bottom() 2091 while ( (aOut.LogicToPixel(aSizedRect)).Bottom() > aOrgPxRect.Bottom() ) 2092 { 2093 --aSizedRect.Bottom(); 2094 } 2095 2096 io_aSwRect = SwRect( aSizedRect ); 2097 2098 #ifdef DBG_UTIL 2099 Rectangle aTestOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() ); 2100 Rectangle aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2101 ASSERT( aTestOrgPxRect == aTestNewPxRect, 2102 "Error in lcl_AlignRectToPixelSize(..): Adjusted rectangle has incorrect position or size"); 2103 #if OSL_DEBUG_LEVEL > 1 2104 Rectangle aTestNewRect( aSizedRect ); 2105 /// check Left() 2106 --aSizedRect.Left(); 2107 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2108 ASSERT( aTestOrgPxRect.Left() >= (aTestNewPxRect.Left()+1), 2109 "Error in lcl_AlignRectToPixelSize(..): Left() not correct adjusted"); 2110 ++aSizedRect.Left(); 2111 /// check Right() 2112 ++aSizedRect.Right(); 2113 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2114 ASSERT( aTestOrgPxRect.Right() <= (aTestNewPxRect.Right()-1), 2115 "Error in lcl_AlignRectToPixelSize(..): Right() not correct adjusted"); 2116 --aSizedRect.Right(); 2117 /// check Top() 2118 --aSizedRect.Top(); 2119 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2120 ASSERT( aTestOrgPxRect.Top() >= (aTestNewPxRect.Top()+1), 2121 "Error in lcl_AlignRectToPixelSize(..): Top() not correct adjusted"); 2122 ++aSizedRect.Top(); 2123 /// check Bottom() 2124 ++aSizedRect.Bottom(); 2125 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2126 ASSERT( aTestOrgPxRect.Bottom() <= (aTestNewPxRect.Bottom()-1), 2127 "Error in lcl_AlignRectToPixelSize(..): Bottom() not correct adjusted"); 2128 --aSizedRect.Bottom(); 2129 #endif 2130 #endif 2131 } 2132 2133 2134 // 2135 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES START 2136 // 2137 2138 struct SwLineEntry 2139 { 2140 SwTwips mnKey; 2141 SwTwips mnStartPos; 2142 SwTwips mnEndPos; 2143 2144 svx::frame::Style maAttribute; 2145 2146 enum OverlapType { NO_OVERLAP, OVERLAP1, OVERLAP2, OVERLAP3 }; 2147 2148 public: 2149 SwLineEntry( SwTwips nKey, 2150 SwTwips nStartPos, 2151 SwTwips nEndPos, 2152 const svx::frame::Style& rAttribute ); 2153 2154 OverlapType Overlaps( const SwLineEntry& rComp ) const; 2155 }; 2156 2157 SwLineEntry::SwLineEntry( SwTwips nKey, 2158 SwTwips nStartPos, 2159 SwTwips nEndPos, 2160 const svx::frame::Style& rAttribute ) 2161 : mnKey( nKey ), 2162 mnStartPos( nStartPos ), 2163 mnEndPos( nEndPos ), 2164 maAttribute( rAttribute ) 2165 { 2166 } 2167 2168 /* 2169 2170 1. ---------- rOld 2171 ---------- rNew 2172 2173 2. ---------- rOld 2174 ------------- rNew 2175 2176 3. ------- rOld 2177 ------------- rNew 2178 2179 4. ------------- rOld 2180 ---------- rNew 2181 2182 5. ---------- rOld 2183 ---- rNew 2184 2185 6. ---------- rOld 2186 ---------- rNew 2187 2188 7. ------------- rOld 2189 ---------- rNew 2190 2191 8. ---------- rOld 2192 ------------- rNew 2193 2194 9. ---------- rOld 2195 ---------- rNew 2196 */ 2197 2198 SwLineEntry::OverlapType SwLineEntry::Overlaps( const SwLineEntry& rNew ) const 2199 { 2200 SwLineEntry::OverlapType eRet = OVERLAP3; 2201 2202 if ( mnStartPos >= rNew.mnEndPos || mnEndPos <= rNew.mnStartPos ) 2203 eRet = NO_OVERLAP; 2204 2205 // 1, 2, 3 2206 else if ( mnEndPos < rNew.mnEndPos ) 2207 eRet = OVERLAP1; 2208 2209 // 4, 5, 6, 7 2210 else if ( mnStartPos <= rNew.mnStartPos && mnEndPos >= rNew.mnEndPos ) 2211 eRet = OVERLAP2; 2212 2213 // 8, 9 2214 return eRet; 2215 } 2216 2217 struct lt_SwLineEntry 2218 { 2219 bool operator()( const SwLineEntry& e1, const SwLineEntry& e2 ) const 2220 { 2221 return e1.mnStartPos < e2.mnStartPos; 2222 } 2223 }; 2224 2225 typedef std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet; 2226 typedef std::set< SwLineEntry, lt_SwLineEntry >::iterator SwLineEntrySetIter; 2227 typedef std::set< SwLineEntry, lt_SwLineEntry >::const_iterator SwLineEntrySetConstIter; 2228 typedef std::map< SwTwips, SwLineEntrySet > SwLineEntryMap; 2229 typedef std::map< SwTwips, SwLineEntrySet >::iterator SwLineEntryMapIter; 2230 typedef std::map< SwTwips, SwLineEntrySet >::const_iterator SwLineEntryMapConstIter; 2231 2232 class SwTabFrmPainter 2233 { 2234 SwLineEntryMap maVertLines; 2235 SwLineEntryMap maHoriLines; 2236 const SwTabFrm& mrTabFrm; 2237 2238 void Insert( SwLineEntry&, bool bHori ); 2239 void Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem ); 2240 void HandleFrame( const SwLayoutFrm& rFrm ); 2241 void FindStylesForLine( const Point&, 2242 const Point&, 2243 svx::frame::Style*, 2244 bool bHori ) const; 2245 2246 public: 2247 SwTabFrmPainter( const SwTabFrm& rTabFrm ); 2248 2249 void PaintLines( OutputDevice& rDev, const SwRect& rRect ) const; 2250 }; 2251 2252 SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm ) 2253 : mrTabFrm( rTabFrm ) 2254 { 2255 HandleFrame( rTabFrm ); 2256 } 2257 2258 void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm ) 2259 { 2260 // Add border lines of cell frames. Skip covered cells. Skip cells 2261 // in special row span row, which do not have a negative row span: 2262 if ( rLayoutFrm.IsCellFrm() && !rLayoutFrm.IsCoveredCell() ) 2263 { 2264 const SwCellFrm* pThisCell = static_cast<const SwCellFrm*>(&rLayoutFrm); 2265 const SwRowFrm* pRowFrm = static_cast<const SwRowFrm*>(pThisCell->GetUpper()); 2266 const long nRowSpan = pThisCell->GetTabBox()->getRowSpan(); 2267 if ( !pRowFrm->IsRowSpanLine() || nRowSpan > 1 || nRowSpan < -1 ) 2268 { 2269 SwBorderAttrAccess aAccess( SwFrm::GetCache(), &rLayoutFrm ); 2270 const SwBorderAttrs& rAttrs = *aAccess.Get(); 2271 const SvxBoxItem& rBox = rAttrs.GetBox(); 2272 Insert( rLayoutFrm, rBox ); 2273 } 2274 } 2275 2276 // Recurse into lower layout frames, but do not recurse into lower tabframes. 2277 const SwFrm* pLower = rLayoutFrm.Lower(); 2278 while ( pLower ) 2279 { 2280 const SwLayoutFrm* pLowerLayFrm = dynamic_cast<const SwLayoutFrm*>(pLower); 2281 if ( pLowerLayFrm && !pLowerLayFrm->IsTabFrm() ) 2282 HandleFrame( *pLowerLayFrm ); 2283 2284 pLower = pLower->GetNext(); 2285 } 2286 } 2287 2288 void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) const 2289 { 2290 // --> FME 2004-06-24 #i16816# tagged pdf support 2291 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev ); 2292 // <-- 2293 2294 const SwFrm* pTmpFrm = &mrTabFrm; 2295 const bool bVert = pTmpFrm->IsVertical(); 2296 2297 SwLineEntryMapConstIter aIter = maHoriLines.begin(); 2298 bool bHori = true; 2299 2300 // color for subsidiary lines: 2301 const Color& rCol( SwViewOption::GetTableBoundariesColor() ); 2302 2303 // high contrast mode: 2304 // overrides the color of non-subsidiary lines. 2305 const Color* pHCColor = 0; 2306 sal_uLong nOldDrawMode = rDev.GetDrawMode(); 2307 if( pGlobalShell->GetWin() && 2308 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 2309 { 2310 pHCColor = &SwViewOption::GetFontColor(); 2311 rDev.SetDrawMode( 0 ); 2312 } 2313 2314 // set clip region: 2315 rDev.Push( PUSH_CLIPREGION ); 2316 Size aSize( rRect.SSize() ); 2317 // Hack! Necessary, because the layout is not pixel aligned! 2318 aSize.Width() += nPixelSzW; aSize.Height() += nPixelSzH; 2319 rDev.SetClipRegion( Rectangle( rRect.Pos(), aSize ) ); 2320 2321 // The following stuff if necessary to have the new table borders fit 2322 // into a ::SwAlignRect adjusted world. 2323 const SwTwips nTwipXCorr = bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-) 2324 const SwTwips nTwipYCorr = !bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-) 2325 const SwFrm* pUpper = mrTabFrm.GetUpper(); 2326 SwRect aUpper( pUpper->Prt() ); 2327 aUpper.Pos() += pUpper->Frm().Pos(); 2328 SwRect aUpperAligned( aUpper ); 2329 ::SwAlignRect( aUpperAligned, pGlobalShell ); 2330 2331 while ( true ) 2332 { 2333 if ( bHori && aIter == maHoriLines.end() ) 2334 { 2335 aIter = maVertLines.begin(); 2336 bHori = false; 2337 } 2338 2339 if ( !bHori && aIter == maVertLines.end() ) 2340 break; 2341 2342 const SwLineEntrySet& rEntrySet = (*aIter).second; 2343 SwLineEntrySetConstIter aSetIter = rEntrySet.begin(); 2344 while ( aSetIter != rEntrySet.end() ) 2345 { 2346 const SwLineEntry& rEntry = *aSetIter; 2347 const svx::frame::Style& rEntryStyle( (*aSetIter).maAttribute ); 2348 2349 Point aStart, aEnd; 2350 if ( bHori ) 2351 { 2352 aStart.X() = rEntry.mnStartPos; 2353 aStart.Y() = rEntry.mnKey; 2354 aEnd.X() = rEntry.mnEndPos; 2355 aEnd.Y() = rEntry.mnKey; 2356 } 2357 else 2358 { 2359 aStart.X() = rEntry.mnKey; 2360 aStart.Y() = rEntry.mnStartPos; 2361 aEnd.X() = rEntry.mnKey; 2362 aEnd.Y() = rEntry.mnEndPos; 2363 } 2364 2365 SwRect aRepaintRect( aStart, aEnd ); 2366 2367 // the repaint rectangle has to be moved a bit for the centered lines: 2368 SwTwips nRepaintRectSize = !rEntryStyle.GetWidth() ? 1 : rEntryStyle.GetWidth(); 2369 if ( bHori ) 2370 { 2371 aRepaintRect.Height( 2 * nRepaintRectSize ); 2372 aRepaintRect.Pos().Y() -= nRepaintRectSize; 2373 } 2374 else 2375 { 2376 aRepaintRect.Width( 2 * nRepaintRectSize ); 2377 aRepaintRect.Pos().X() -= nRepaintRectSize; 2378 } 2379 2380 if ( rRect.IsOver( aRepaintRect ) ) 2381 { 2382 svx::frame::Style aStyles[ 7 ]; 2383 aStyles[ 0 ] = rEntryStyle; 2384 FindStylesForLine( aStart, aEnd, aStyles, bHori ); 2385 2386 // subsidiary lines 2387 const Color* pTmpColor = 0; 2388 if ( 0 == aStyles[ 0 ].GetWidth() ) 2389 { 2390 if ( IS_SUBS_TABLE && pGlobalShell->GetWin() ) 2391 aStyles[ 0 ].Set( rCol, 1, 0, 0 ); 2392 } 2393 else 2394 pTmpColor = pHCColor; 2395 2396 // The line sizes stored in the line style have to be adjusted as well. 2397 // This will guarantee that lines with the same twip size will have the 2398 // same pixel size. 2399 for ( int i = 0; i < 7; ++i ) 2400 { 2401 sal_uInt16 nPrim = aStyles[ i ].Prim(); 2402 sal_uInt16 nDist = aStyles[ i ].Dist(); 2403 sal_uInt16 nSecn = aStyles[ i ].Secn(); 2404 2405 if ( nPrim > 0 ) 2406 nPrim = (sal_uInt16)( Max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) ); 2407 if ( nDist > 0 ) 2408 nDist = (sal_uInt16)( Max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) ); 2409 if ( nSecn > 0 ) 2410 nSecn = (sal_uInt16)( Max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) ); 2411 2412 aStyles[ i ].Set( nPrim, nDist, nSecn ); 2413 } 2414 2415 // The (twip) positions will be adjusted to meet these requirements: 2416 // 1. The y coordinates are located in the middle of the pixel grid 2417 // 2. The x coordinated are located at the beginning of the pixel grid 2418 // This is done, because the horizontal lines are painted "at beginning", 2419 // whereas the vertical lines are painted "centered". By making the line 2420 // sizes a multiple of one pixel size, we can assure, that all lines having 2421 // the same twip size have the same pixel size, independent of their position 2422 // on the screen. 2423 Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel( aStart ) ); 2424 Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel( aEnd ) ); 2425 2426 if( pGlobalShell->GetWin() ) 2427 { 2428 // The table borders do not use SwAlignRect, but all the other frames do. 2429 // Therefore we tweak the outer borders a bit to achieve that the outer 2430 // borders match the subsidiary lines of the upper: 2431 if ( aStart.X() == aUpper.Left() ) 2432 aPaintStart.X() = aUpperAligned.Left(); 2433 else if ( aStart.X() == aUpper._Right() ) 2434 aPaintStart.X() = aUpperAligned._Right(); 2435 if ( aStart.Y() == aUpper.Top() ) 2436 aPaintStart.Y() = aUpperAligned.Top(); 2437 else if ( aStart.Y() == aUpper._Bottom() ) 2438 aPaintStart.Y() = aUpperAligned._Bottom(); 2439 2440 if ( aEnd.X() == aUpper.Left() ) 2441 aPaintEnd.X() = aUpperAligned.Left(); 2442 else if ( aEnd.X() == aUpper._Right() ) 2443 aPaintEnd.X() = aUpperAligned._Right(); 2444 if ( aEnd.Y() == aUpper.Top() ) 2445 aPaintEnd.Y() = aUpperAligned.Top(); 2446 else if ( aEnd.Y() == aUpper._Bottom() ) 2447 aPaintEnd.Y() = aUpperAligned._Bottom(); 2448 } 2449 2450 aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel 2451 aPaintEnd.X() -= nTwipXCorr; 2452 aPaintStart.Y() -= nTwipYCorr; 2453 aPaintEnd.Y() -= nTwipYCorr; 2454 2455 // Here comes the painting stuff: Thank you, DR, great job!!! 2456 if ( bHori ) 2457 { 2458 svx::frame::DrawHorFrameBorder 2459 ( 2460 rDev, 2461 aPaintStart, 2462 aPaintEnd, 2463 aStyles[ 0 ], // current style 2464 aStyles[ 1 ], // aLFromT 2465 aStyles[ 2 ], // aLFromL 2466 aStyles[ 3 ], // aLFromB 2467 aStyles[ 4 ], // aRFromT 2468 aStyles[ 5 ], // aRFromR 2469 aStyles[ 6 ], // aRFromB 2470 pTmpColor 2471 ); 2472 } 2473 else 2474 { 2475 svx::frame::DrawVerFrameBorder 2476 ( 2477 rDev, 2478 aPaintStart, 2479 aPaintEnd, 2480 aStyles[ 0 ], // current style 2481 aStyles[ 1 ], // aTFromL 2482 aStyles[ 2 ], // aTFromT 2483 aStyles[ 3 ], // aTFromR 2484 aStyles[ 4 ], // aBFromL 2485 aStyles[ 5 ], // aBFromB 2486 aStyles[ 6 ], // aBFromR 2487 pTmpColor 2488 ); 2489 } 2490 } 2491 2492 ++aSetIter; 2493 } 2494 2495 ++aIter; 2496 } 2497 2498 // restore output device: 2499 rDev.Pop(); 2500 rDev.SetDrawMode( nOldDrawMode ); 2501 } 2502 2503 // Finds the lines that join the line defined by (StartPoint, EndPoint) in either 2504 // StartPoint or Endpoint. The styles of these lines are required for DR's magic 2505 // line painting functions. 2506 void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint, 2507 const Point& rEndPoint, 2508 svx::frame::Style* pStyles, 2509 bool bHori ) const 2510 { 2511 // pStyles[ 1 ] = bHori ? aLFromT : TFromL 2512 // pStyles[ 2 ] = bHori ? aLFromL : TFromT, 2513 // pStyles[ 3 ] = bHori ? aLFromB : TFromR, 2514 // pStyles[ 4 ] = bHori ? aRFromT : BFromL, 2515 // pStyles[ 5 ] = bHori ? aRFromR : BFromB, 2516 // pStyles[ 6 ] = bHori ? aRFromB : BFromR, 2517 2518 SwLineEntryMapConstIter aMapIter = maVertLines.find( rStartPoint.X() ); 2519 ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" ) 2520 const SwLineEntrySet& rVertSet = (*aMapIter).second; 2521 SwLineEntrySetConstIter aIter = rVertSet.begin(); 2522 2523 while ( aIter != rVertSet.end() ) 2524 { 2525 const SwLineEntry& rEntry = *aIter; 2526 if ( bHori ) 2527 { 2528 if ( rStartPoint.Y() == rEntry.mnStartPos ) 2529 pStyles[ 3 ] = rEntry.maAttribute; 2530 else if ( rStartPoint.Y() == rEntry.mnEndPos ) 2531 pStyles[ 1 ] = rEntry.maAttribute; 2532 } 2533 else 2534 { 2535 if ( rStartPoint.Y() == rEntry.mnEndPos ) 2536 pStyles[ 2 ] = rEntry.maAttribute; 2537 else if ( rEndPoint.Y() == rEntry.mnStartPos ) 2538 pStyles[ 5 ] = rEntry.maAttribute; 2539 } 2540 ++aIter; 2541 } 2542 2543 aMapIter = maHoriLines.find( rStartPoint.Y() ); 2544 ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" ) 2545 const SwLineEntrySet& rHoriSet = (*aMapIter).second; 2546 aIter = rHoriSet.begin(); 2547 2548 while ( aIter != rHoriSet.end() ) 2549 { 2550 const SwLineEntry& rEntry = *aIter; 2551 if ( bHori ) 2552 { 2553 if ( rStartPoint.X() == rEntry.mnEndPos ) 2554 pStyles[ 2 ] = rEntry.maAttribute; 2555 else if ( rEndPoint.X() == rEntry.mnStartPos ) 2556 pStyles[ 5 ] = rEntry.maAttribute; 2557 } 2558 else 2559 { 2560 if ( rStartPoint.X() == rEntry.mnEndPos ) 2561 pStyles[ 1 ] = rEntry.maAttribute; 2562 else if ( rStartPoint.X() == rEntry.mnStartPos ) 2563 pStyles[ 3 ] = rEntry.maAttribute; 2564 } 2565 ++aIter; 2566 } 2567 2568 if ( bHori ) 2569 { 2570 aMapIter = maVertLines.find( rEndPoint.X() ); 2571 ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" ) 2572 const SwLineEntrySet& rVertSet2 = (*aMapIter).second; 2573 aIter = rVertSet2.begin(); 2574 2575 while ( aIter != rVertSet2.end() ) 2576 { 2577 const SwLineEntry& rEntry = *aIter; 2578 if ( rEndPoint.Y() == rEntry.mnStartPos ) 2579 pStyles[ 6 ] = rEntry.maAttribute; 2580 else if ( rEndPoint.Y() == rEntry.mnEndPos ) 2581 pStyles[ 4 ] = rEntry.maAttribute; 2582 ++aIter; 2583 } 2584 } 2585 else 2586 { 2587 aMapIter = maHoriLines.find( rEndPoint.Y() ); 2588 ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" ) 2589 const SwLineEntrySet& rHoriSet2 = (*aMapIter).second; 2590 aIter = rHoriSet2.begin(); 2591 2592 while ( aIter != rHoriSet2.end() ) 2593 { 2594 const SwLineEntry& rEntry = *aIter; 2595 if ( rEndPoint.X() == rEntry.mnEndPos ) 2596 pStyles[ 4 ] = rEntry.maAttribute; 2597 else if ( rEndPoint.X() == rEntry.mnStartPos ) 2598 pStyles[ 6 ] = rEntry.maAttribute; 2599 ++aIter; 2600 } 2601 } 2602 } 2603 2604 void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem ) 2605 { 2606 std::vector< const SwFrm* > aTestVec; 2607 aTestVec.push_back( &rFrm ); 2608 aTestVec.push_back( &rFrm ); 2609 aTestVec.push_back( &rFrm ); 2610 2611 // build 4 line entries for the 4 borders: 2612 SwRect aBorderRect = rFrm.Frm(); 2613 if ( rFrm.IsTabFrm() ) 2614 { 2615 aBorderRect = rFrm.Prt(); 2616 aBorderRect.Pos() += rFrm.Frm().Pos(); 2617 } 2618 2619 const SwTwips nLeft = aBorderRect._Left(); 2620 const SwTwips nRight = aBorderRect._Right(); 2621 const SwTwips nTop = aBorderRect._Top(); 2622 const SwTwips nBottom = aBorderRect._Bottom(); 2623 2624 svx::frame::Style aL( rBoxItem.GetLeft() ); 2625 svx::frame::Style aR( rBoxItem.GetRight() ); 2626 svx::frame::Style aT( rBoxItem.GetTop() ); 2627 svx::frame::Style aB( rBoxItem.GetBottom() ); 2628 2629 aR.MirrorSelf(); 2630 aB.MirrorSelf(); 2631 2632 bool bVert = mrTabFrm.IsVertical(); 2633 bool bR2L = mrTabFrm.IsRightToLeft(); 2634 2635 aL.SetRefMode( svx::frame::REFMODE_CENTERED ); 2636 aR.SetRefMode( svx::frame::REFMODE_CENTERED ); 2637 aT.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END ); 2638 aB.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END ); 2639 2640 SwLineEntry aLeft ( nLeft, nTop, nBottom, bVert ? aB : ( bR2L ? aR : aL ) ); 2641 SwLineEntry aRight ( nRight, nTop, nBottom, bVert ? aT : ( bR2L ? aL : aR ) ); 2642 SwLineEntry aTop ( nTop, nLeft, nRight, bVert ? aL : aT ); 2643 SwLineEntry aBottom( nBottom, nLeft, nRight, bVert ? aR : aB ); 2644 2645 Insert( aLeft, false ); 2646 Insert( aRight, false ); 2647 Insert( aTop, true ); 2648 Insert( aBottom, true ); 2649 2650 const SwRowFrm* pThisRowFrm = dynamic_cast<const SwRowFrm*>(rFrm.GetUpper()); 2651 2652 // special case: #i9860# 2653 // first line in follow table without repeated headlines 2654 if ( pThisRowFrm && 2655 pThisRowFrm->GetUpper() == &mrTabFrm && 2656 mrTabFrm.IsFollow() && 2657 !mrTabFrm.GetTable()->GetRowsToRepeat() && 2658 (!pThisRowFrm->GetPrev() || static_cast<const SwRowFrm*>(pThisRowFrm->GetPrev())->IsRowSpanLine()) && 2659 !rBoxItem.GetTop() && 2660 rBoxItem.GetBottom() ) 2661 { 2662 SwLineEntry aFollowTop( !bVert ? nTop : nRight, !bVert ? nLeft : nTop, !bVert ? nRight : nBottom, aB ); 2663 Insert( aFollowTop, !bVert ); 2664 } 2665 } 2666 2667 void SwTabFrmPainter::Insert( SwLineEntry& rNew, bool bHori ) 2668 { 2669 // get all lines from structure, that have key entry of pLE 2670 SwLineEntryMap* pLine2 = bHori ? &maHoriLines : &maVertLines; 2671 const SwTwips nKey = rNew.mnKey; 2672 SwLineEntryMapIter aMapIter = pLine2->find( nKey ); 2673 2674 SwLineEntrySet* pLineSet = aMapIter != pLine2->end() ? &((*aMapIter).second) : 0; 2675 if ( !pLineSet ) 2676 { 2677 SwLineEntrySet aNewSet; 2678 (*pLine2)[ nKey ] = aNewSet; 2679 pLineSet = &(*pLine2)[ nKey ]; 2680 } 2681 SwLineEntrySetIter aIter = pLineSet->begin(); 2682 2683 while ( pLineSet && aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos ) 2684 { 2685 const SwLineEntry& rOld = *aIter; 2686 const SwLineEntry::OverlapType nOverlapType = rOld.Overlaps( rNew ); 2687 2688 const svx::frame::Style& rOldAttr = rOld.maAttribute; 2689 const svx::frame::Style& rNewAttr = rNew.maAttribute; 2690 const svx::frame::Style& rCmpAttr = rNewAttr > rOldAttr ? rNewAttr : rOldAttr; 2691 2692 if ( SwLineEntry::OVERLAP1 == nOverlapType ) 2693 { 2694 ASSERT( rNew.mnStartPos >= rOld.mnStartPos, "Overlap type 3? How this?" ) 2695 2696 // new left segment 2697 const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr ); 2698 2699 // new middle segment 2700 const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rOld.mnEndPos, rCmpAttr ); 2701 2702 // new right segment 2703 rNew.mnStartPos = rOld.mnEndPos; 2704 2705 // update current lines set 2706 pLineSet->erase( aIter ); 2707 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft ); 2708 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle ); 2709 2710 aIter = pLineSet->begin(); 2711 2712 continue; // start over 2713 } 2714 else if ( SwLineEntry::OVERLAP2 == nOverlapType ) 2715 { 2716 // new left segment 2717 const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr ); 2718 2719 // new middle segment 2720 const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rNew.mnEndPos, rCmpAttr ); 2721 2722 // new right segment 2723 const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr ); 2724 2725 // update current lines set 2726 pLineSet->erase( aIter ); 2727 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft ); 2728 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle ); 2729 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight ); 2730 2731 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted! 2732 2733 break; // we are finished 2734 } 2735 else if ( SwLineEntry::OVERLAP3 == nOverlapType ) 2736 { 2737 // new left segment 2738 const SwLineEntry aLeft( nKey, rNew.mnStartPos, rOld.mnStartPos, rNewAttr ); 2739 2740 // new middle segment 2741 const SwLineEntry aMiddle( nKey, rOld.mnStartPos, rNew.mnEndPos, rCmpAttr ); 2742 2743 // new right segment 2744 const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr ); 2745 2746 // update current lines set 2747 pLineSet->erase( aIter ); 2748 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft ); 2749 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle ); 2750 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight ); 2751 2752 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted! 2753 2754 break; // we are finished 2755 } 2756 2757 ++aIter; 2758 } 2759 2760 if ( rNew.mnStartPos < rNew.mnEndPos ) // insert rest 2761 pLineSet->insert( rNew ); 2762 } 2763 2764 // 2765 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES END 2766 // 2767 2768 // --> OD #i76669# 2769 namespace 2770 { 2771 class SwViewObjectContactRedirector : public ::sdr::contact::ViewObjectContactRedirector 2772 { 2773 private: 2774 const ViewShell& mrViewShell; 2775 2776 public: 2777 SwViewObjectContactRedirector( const ViewShell& rSh ) 2778 : mrViewShell( rSh ) 2779 {}; 2780 2781 virtual ~SwViewObjectContactRedirector() 2782 {} 2783 2784 virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence( 2785 const sdr::contact::ViewObjectContact& rOriginal, 2786 const sdr::contact::DisplayInfo& rDisplayInfo) 2787 { 2788 sal_Bool bPaint( sal_True ); 2789 2790 SdrObject* pObj = rOriginal.GetViewContact().TryToGetSdrObject(); 2791 if ( pObj ) 2792 { 2793 bPaint = SwFlyFrm::IsPaint( pObj, &mrViewShell ); 2794 } 2795 2796 if ( !bPaint ) 2797 { 2798 return drawinglayer::primitive2d::Primitive2DSequence(); 2799 } 2800 2801 return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( 2802 rOriginal, rDisplayInfo ); 2803 } 2804 }; 2805 2806 } // end of anonymous namespace 2807 // <-- 2808 2809 /************************************************************************* 2810 |* 2811 |* SwRootFrm::Paint() 2812 |* 2813 |* Beschreibung 2814 |* Fuer jede sichtbare Seite, die von Rect ber?hrt wird einmal Painten. 2815 |* 1. Umrandungen und Hintergruende Painten. 2816 |* 2. Den Draw Layer (Ramen und Zeichenobjekte) der unter dem Dokument 2817 |* liegt painten (Hoelle). 2818 |* 3. Den Dokumentinhalt (Text) Painten. 2819 |* 4. Den Drawlayer der ueber dem Dokuemnt liegt painten. 2820 |* 2821 |* Ersterstellung MA 01. Jun. 92 2822 |* Letzte Aenderung MA 10. Oct. 97 2823 |* 2824 |*************************************************************************/ 2825 2826 void 2827 SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const 2828 { 2829 ASSERT( Lower() && Lower()->IsPageFrm(), "Lower der Root keine Seite." ); 2830 2831 PROTOCOL( this, PROT_FILE_INIT, 0, 0) 2832 2833 sal_Bool bResetRootPaint = sal_False; 2834 ViewShell *pSh = pCurrShell; 2835 2836 if ( pSh->GetWin() ) 2837 { 2838 if ( pSh->GetOut() == pSh->GetWin() && !pSh->GetWin()->IsVisible() ) 2839 { 2840 return; 2841 } 2842 if ( SwRootFrm::bInPaint ) 2843 { 2844 SwPaintQueue::Add( pSh, rRect ); 2845 return; 2846 } 2847 } 2848 else 2849 SwRootFrm::bInPaint = bResetRootPaint = sal_True; 2850 2851 SwSavePaintStatics *pStatics = 0; 2852 if ( pGlobalShell ) 2853 pStatics = new SwSavePaintStatics(); 2854 pGlobalShell = pSh; 2855 2856 if( !pSh->GetWin() ) 2857 pProgress = SfxProgress::GetActiveProgress( (SfxObjectShell*) pSh->GetDoc()->GetDocShell() ); 2858 2859 ::SwCalcPixStatics( pSh->GetOut() ); 2860 aGlobalRetoucheColor = pSh->Imp()->GetRetoucheColor(); 2861 2862 //Ggf. eine Action ausloesen um klare Verhaeltnisse zu schaffen. 2863 //Durch diesen Kunstgriff kann in allen Paints davon ausgegangen werden, 2864 //das alle Werte gueltigt sind - keine Probleme, keine Sonderbehandlung(en). 2865 // --> OD 2008-10-07 #i92745# 2866 // Extend check on certain states of the 'current' <ViewShell> instance to 2867 // all existing <ViewShell> instances. 2868 bool bPerformLayoutAction( true ); 2869 { 2870 ViewShell* pTmpViewShell = pSh; 2871 do { 2872 if ( pTmpViewShell->IsInEndAction() || 2873 pTmpViewShell->IsPaintInProgress() || 2874 ( pTmpViewShell->Imp()->IsAction() && 2875 pTmpViewShell->Imp()->GetLayAction().IsActionInProgress() ) ) 2876 { 2877 bPerformLayoutAction = false; 2878 } 2879 2880 pTmpViewShell = static_cast<ViewShell*>(pTmpViewShell->GetNext()); 2881 } while ( bPerformLayoutAction && pTmpViewShell != pSh ); 2882 } 2883 if ( bPerformLayoutAction ) 2884 // <-- 2885 { 2886 ((SwRootFrm*)this)->ResetTurbo(); 2887 SwLayAction aAction( (SwRootFrm*)this, pSh->Imp() ); 2888 aAction.SetPaint( sal_False ); 2889 aAction.SetComplete( sal_False ); 2890 aAction.SetReschedule( pProgress ? sal_True : sal_False ); 2891 aAction.Action(); 2892 ((SwRootFrm*)this)->ResetTurboFlag(); 2893 if ( !pSh->ActionPend() ) 2894 pSh->Imp()->DelRegion(); 2895 } 2896 2897 SwRect aRect( rRect ); 2898 aRect.Intersection( pSh->VisArea() ); 2899 2900 const sal_Bool bExtraData = ::IsExtraData( GetFmt()->GetDoc() ); 2901 2902 pLines = new SwLineRects; //Sammler fuer Umrandungen. 2903 2904 // #104289#. During painting, something (OLE) can 2905 // load the linguistic, which in turn can cause a reformat 2906 // of the document. Dangerous! We better set this flag to 2907 // avoid the reformat. 2908 const sal_Bool bOldAction = IsCallbackActionEnabled(); 2909 ((SwRootFrm*)this)->SetCallbackActionEnabled( sal_False ); 2910 2911 const SwPageFrm *pPage = pSh->Imp()->GetFirstVisPage(); 2912 2913 const bool bBookMode = pGlobalShell->GetViewOptions()->IsViewLayoutBookMode(); 2914 if ( bBookMode && pPage->GetPrev() && static_cast<const SwPageFrm*>(pPage->GetPrev())->IsEmptyPage() ) 2915 pPage = static_cast<const SwPageFrm*>(pPage->GetPrev()); 2916 2917 const bool bLTR = IsLeftToRightViewLayout(); 2918 2919 // #i68597# 2920 const bool bGridPainting(pSh->GetWin() && pSh->Imp()->HasDrawView() && pSh->Imp()->GetDrawView()->IsGridVisible()); 2921 2922 // --> OD #i76669# 2923 SwViewObjectContactRedirector aSwRedirector( *pSh ); 2924 // <-- 2925 2926 while ( pPage ) 2927 { 2928 const bool bPaintRightShadow = !bBookMode || (pPage == Lower()) || (!bLTR && !pPage->OnRightPage()) || (bLTR && pPage->OnRightPage()); 2929 const bool bRightSidebar = pPage->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT; 2930 2931 if ( !pPage->IsEmptyPage() ) 2932 { 2933 SwRect aPaintRect; 2934 SwPageFrm::GetBorderAndShadowBoundRect( pPage->Frm(), pSh, aPaintRect, bRightSidebar ); 2935 2936 if ( aRect.IsOver( aPaintRect ) ) 2937 { 2938 if ( pSh->GetWin() ) 2939 { 2940 pSubsLines = new SwSubsRects; 2941 pSpecSubsLines = new SwSubsRects; 2942 } 2943 2944 aPaintRect._Intersection( aRect ); 2945 2946 // --> OD 2007-11-14 #i82616# 2947 // Invalidate area for extra data (line numbers or change tracking 2948 // marks), if painting on a window and the paint is trigger by an 2949 // end action. The inefficient and simple enlargement of the 2950 // paint area is replaced by this invalidation. 2951 if ( bExtraData && 2952 pSh->GetWin() && pSh->IsInEndAction() ) 2953 { 2954 // enlarge paint rectangle to complete page width, subtract 2955 // current paint area and invalidate the resulting region. 2956 SWRECTFN( pPage ) 2957 SwRect aPageRectTemp( aPaintRect ); 2958 (aPageRectTemp.*fnRect->fnSetLeftAndWidth)( 2959 (pPage->Frm().*fnRect->fnGetLeft)(), 2960 (pPage->Frm().*fnRect->fnGetWidth)() ); 2961 aPageRectTemp._Intersection( pSh->VisArea() ); 2962 Region aPageRectRegion( aPageRectTemp.SVRect() ); 2963 aPageRectRegion.Exclude( aPaintRect.SVRect() ); 2964 pSh->GetWin()->Invalidate( aPageRectRegion, INVALIDATE_CHILDREN ); 2965 } 2966 // <-- 2967 2968 // --> OD 2007-08-20 #i80793# 2969 // enlarge paint rectangle for objects overlapping the same pixel 2970 // in all cases and before the DrawingLayer overlay is initialized. 2971 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) ); 2972 // <-- 2973 2974 // #i68597# 2975 // moved paint pre-process for DrawingLayer overlay here since the above 2976 // code dependent from bExtraData may expand the PaintRect 2977 { 2978 // #i75172# if called from ViewShell::ImplEndAction it sould no longer 2979 // really be used but handled by ViewShell::ImplEndAction already 2980 const Region aDLRegion(aPaintRect.SVRect()); 2981 pSh->DLPrePaint2(aDLRegion); 2982 } 2983 2984 if(OUTDEV_WINDOW == pGlobalShell->GetOut()->GetOutDevType()) 2985 { 2986 /// OD 27.09.2002 #103636# - changed method SwLayVout::Enter(..) 2987 /// 2nd parameter is no longer <const> and will be set to the 2988 /// rectangle the virtual output device is calculated from <aPaintRect>, 2989 /// if the virtual output is used. 2990 pVout->Enter( pSh, aPaintRect, !bNoVirDev ); 2991 2992 /// OD 27.09.2002 #103636# - adjust paint rectangle to pixel size 2993 /// Thus, all objects overlapping on pixel level with the unadjusted 2994 /// paint rectangle will be considered in the paint. 2995 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) ); 2996 } 2997 2998 // maybe this can be put in the above scope. Since we are not sure, just leave it ATM 2999 pVout->SetOrgRect( aPaintRect ); 3000 3001 /// OD 29.08.2002 #102450# 3002 /// determine background color of page for <PaintLayer> method 3003 /// calls, paint <hell> or <heaven> 3004 const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor(); 3005 3006 pPage->PaintBaBo( aPaintRect, pPage, sal_True ); 3007 3008 if ( pSh->Imp()->HasDrawView() ) 3009 { 3010 pLines->LockLines( sal_True ); 3011 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 3012 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 3013 pPrintData, 3014 aPaintRect, 3015 &aPageBackgrdColor, 3016 (pPage->IsRightToLeft() ? true : false), 3017 &aSwRedirector ); 3018 pLines->PaintLines( pSh->GetOut() ); 3019 pLines->LockLines( sal_False ); 3020 } 3021 3022 if( pSh->GetWin() ) 3023 { 3024 // collect sub-lines 3025 pPage->RefreshSubsidiary( aPaintRect ); 3026 // paint special sub-lines 3027 pSpecSubsLines->PaintSubsidiary( pSh->GetOut(), NULL ); 3028 } 3029 3030 pPage->Paint( aPaintRect ); 3031 3032 // no paint of page border and shadow, if writer is in place mode. 3033 if( pSh->GetWin() && pSh->GetDoc()->GetDocShell() && 3034 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() ) 3035 { 3036 SwPageFrm::PaintBorderAndShadow( pPage->Frm(), pSh, bPaintRightShadow, bRightSidebar ); 3037 SwPageFrm::PaintNotesSidebar( pPage->Frm(), pSh, pPage->GetPhyPageNum(), bRightSidebar); 3038 } 3039 3040 pLines->PaintLines( pSh->GetOut() ); 3041 3042 if ( pSh->Imp()->HasDrawView() ) 3043 { 3044 /// OD 29.08.2002 #102450# - add 3rd parameter 3045 // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction. 3046 pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(), 3047 pPrintData, 3048 aPaintRect, 3049 &aPageBackgrdColor, 3050 (pPage->IsRightToLeft() ? true : false), 3051 &aSwRedirector ); 3052 } 3053 3054 if ( bExtraData ) 3055 pPage->RefreshExtraData( aPaintRect ); 3056 3057 if ( pSh->GetWin() ) 3058 { 3059 pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines ); 3060 DELETEZ( pSubsLines ); 3061 DELETEZ( pSpecSubsLines ); 3062 } 3063 pVout->Leave(); 3064 3065 // #i68597# 3066 // needed to move grid painting inside Begin/EndDrawLayer bounds and to change 3067 // output rect for it accordingly 3068 if(bGridPainting) 3069 { 3070 SdrPaintView* pPaintView = pSh->Imp()->GetDrawView(); 3071 SdrPageView* pPageView = pPaintView->GetSdrPageView(); 3072 pPageView->DrawPageViewGrid(*pSh->GetOut(), aPaintRect.SVRect(), SwViewOption::GetTextGridColor() ); 3073 } 3074 3075 // #i68597# 3076 // moved paint post-process for DrawingLayer overlay here, see above 3077 { 3078 pSh->DLPostPaint2(true); 3079 } 3080 } 3081 } 3082 else if ( bBookMode && pSh->GetWin() && !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() ) 3083 { 3084 // paint empty page 3085 SwRect aPaintRect; 3086 SwRect aEmptyPageRect( pPage->Frm() ); 3087 3088 // code from vprint.cxx 3089 const SwPageFrm& rFormatPage = pPage->GetFormatPage(); 3090 aEmptyPageRect.SSize() = rFormatPage.Frm().SSize(); 3091 3092 SwPageFrm::GetBorderAndShadowBoundRect( aEmptyPageRect, pSh, aPaintRect, bRightSidebar ); 3093 aPaintRect._Intersection( aRect ); 3094 3095 if ( aRect.IsOver( aEmptyPageRect ) ) 3096 { 3097 // #i75172# if called from ViewShell::ImplEndAction it sould no longer 3098 // really be used but handled by ViewShell::ImplEndAction already 3099 { 3100 const Region aDLRegion(aPaintRect.SVRect()); 3101 pSh->DLPrePaint2(aDLRegion); 3102 } 3103 3104 if( pSh->GetOut()->GetFillColor() != aGlobalRetoucheColor ) 3105 pSh->GetOut()->SetFillColor( aGlobalRetoucheColor ); 3106 3107 pSh->GetOut()->SetLineColor(); // OD 20.02.2003 #107369# - no line color 3108 // OD 20.02.2003 #107369# - use aligned page rectangle 3109 { 3110 SwRect aTmpPageRect( aEmptyPageRect ); 3111 ::SwAlignRect( aTmpPageRect, pSh ); 3112 aEmptyPageRect = aTmpPageRect; 3113 } 3114 3115 pSh->GetOut()->DrawRect( aEmptyPageRect.SVRect() ); 3116 3117 // paint empty page text 3118 const Font& rEmptyPageFont = SwPageFrm::GetEmptyPageFont(); 3119 const Font aOldFont( pSh->GetOut()->GetFont() ); 3120 3121 pSh->GetOut()->SetFont( rEmptyPageFont ); 3122 pSh->GetOut()->DrawText( aEmptyPageRect.SVRect(), SW_RESSTR( STR_EMPTYPAGE ), 3123 TEXT_DRAW_VCENTER | 3124 TEXT_DRAW_CENTER | 3125 TEXT_DRAW_CLIP ); 3126 3127 pSh->GetOut()->SetFont( aOldFont ); 3128 // paint shadow and border for empty page 3129 // OD 19.02.2003 #107369# - use new method to paint page border and 3130 // shadow 3131 SwPageFrm::PaintBorderAndShadow( aEmptyPageRect, pSh, bPaintRightShadow, bRightSidebar ); 3132 SwPageFrm::PaintNotesSidebar( aEmptyPageRect, pSh, pPage->GetPhyPageNum(), bRightSidebar); 3133 3134 { 3135 pSh->DLPostPaint2(true); 3136 } 3137 } 3138 } 3139 3140 ASSERT( !pPage->GetNext() || pPage->GetNext()->IsPageFrm(), 3141 "Nachbar von Seite keine Seite." ); 3142 pPage = (SwPageFrm*)pPage->GetNext(); 3143 } 3144 3145 DELETEZ( pLines ); 3146 3147 #ifdef FRANK_TEST 3148 if ( pSh->GetWin() ) 3149 { 3150 Rectangle aRect( aFrm.SVRect() ); 3151 pSh->GetWin()->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 3152 pSh->GetWin()->SetFillColor(); 3153 pSh->GetWin()->SetLineColor( COL_LIGHTRED ); 3154 pSh->GetWin()->DrawRect( aRect ); 3155 pSh->GetWin()->Pop(); 3156 } 3157 #endif 3158 3159 if ( bResetRootPaint ) 3160 SwRootFrm::bInPaint = sal_False; 3161 if ( pStatics ) 3162 delete pStatics; 3163 else 3164 { 3165 pProgress = 0; 3166 pGlobalShell = 0; 3167 } 3168 3169 ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction ); 3170 } 3171 3172 #ifdef LONG_TABLE_HACK 3173 3174 /************************************************************************* 3175 |* 3176 |* SwRootFrm::HackPrepareLongTblPaint() 3177 |* 3178 |* Ersterstellung MA 27. Sep. 96 3179 |* Letzte Aenderung MA 18. Nov. 97 3180 |* 3181 |*************************************************************************/ 3182 3183 void SwRootFrm::HackPrepareLongTblPaint( int nMode ) 3184 { 3185 switch ( nMode ) 3186 { 3187 case HACK_TABLEMODE_INIT : ASSERT( !pLines, "HackPrepare: already prepared" ); 3188 pLines = new SwLineRects; 3189 ASSERT( !pGlobalShell, "old GlobalShell lost" ); 3190 pGlobalShell = GetCurrShell(); 3191 bTableHack = sal_True; 3192 break; 3193 case HACK_TABLEMODE_LOCKLINES : pLines->LockLines( sal_True ); break; 3194 case HACK_TABLEMODE_PAINTLINES : pLines->PaintLines( GetShell()->GetOut() ); 3195 break; 3196 case HACK_TABLEMODE_UNLOCKLINES: pLines->LockLines( sal_False ); break; 3197 case HACK_TABLEMODE_EXIT : pLines->PaintLines( GetCurrShell()->GetOut() ); 3198 DELETEZ( pLines ); 3199 pGlobalShell = 0; 3200 bTableHack = sal_False; 3201 break; 3202 } 3203 } 3204 3205 #endif 3206 3207 3208 /************************************************************************* 3209 |* 3210 |* SwLayoutFrm::Paint() 3211 |* 3212 |* Ersterstellung MA 19. May. 92 3213 |* Letzte Aenderung MA 19. Apr. 95 3214 |* 3215 |*************************************************************************/ 3216 3217 void MA_FASTCALL lcl_EmergencyFormatFtnCont( SwFtnContFrm *pCont ) 3218 { 3219 //Es kann sein, dass der Cont vernichtet wird. 3220 SwCntntFrm *pCnt = pCont->ContainsCntnt(); 3221 while ( pCnt && pCnt->IsInFtn() ) 3222 { 3223 pCnt->Calc(); 3224 pCnt = pCnt->GetNextCntntFrm(); 3225 } 3226 } 3227 3228 class SwShortCut 3229 { 3230 SwRectDist fnCheck; 3231 long nLimit; 3232 public: 3233 SwShortCut( const SwFrm& rFrm, const SwRect& rRect ); 3234 sal_Bool Stop( const SwRect& rRect ) const 3235 { return (rRect.*fnCheck)( nLimit ) > 0; } 3236 }; 3237 3238 SwShortCut::SwShortCut( const SwFrm& rFrm, const SwRect& rRect ) 3239 { 3240 sal_Bool bVert = rFrm.IsVertical(); 3241 sal_Bool bR2L = rFrm.IsRightToLeft(); 3242 if( rFrm.IsNeighbourFrm() && bVert == bR2L ) 3243 { 3244 if( bVert ) 3245 { 3246 fnCheck = &SwRect::GetBottomDistance; 3247 nLimit = rRect.Top(); 3248 } 3249 else 3250 { 3251 fnCheck = &SwRect::GetLeftDistance; 3252 nLimit = rRect.Left() + rRect.Width(); 3253 } 3254 } 3255 else if( bVert == rFrm.IsNeighbourFrm() ) 3256 { 3257 fnCheck = &SwRect::GetTopDistance; 3258 nLimit = rRect.Top() + rRect.Height(); 3259 } 3260 else 3261 { 3262 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 3263 if ( rFrm.IsVertLR() ) 3264 { 3265 fnCheck = &SwRect::GetLeftDistance; 3266 nLimit = rRect.Right(); 3267 } 3268 else 3269 { 3270 fnCheck = &SwRect::GetRightDistance; 3271 nLimit = rRect.Left(); 3272 } 3273 } 3274 } 3275 3276 void SwLayoutFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3277 { 3278 ViewShell *pSh = getRootFrm()->GetCurrShell(); 3279 3280 // --> FME 2004-06-24 #i16816# tagged pdf support 3281 Frm_Info aFrmInfo( *this ); 3282 SwTaggedPDFHelper aTaggedPDFHelper( 0, &aFrmInfo, 0, *pSh->GetOut() ); 3283 // <-- 3284 3285 const SwFrm *pFrm = Lower(); 3286 if ( !pFrm ) 3287 return; 3288 3289 SwShortCut aShortCut( *pFrm, rRect ); 3290 sal_Bool bCnt; 3291 if ( sal_True == (bCnt = pFrm->IsCntntFrm()) ) 3292 pFrm->Calc(); 3293 3294 if ( pFrm->IsFtnContFrm() ) 3295 { 3296 ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm ); 3297 pFrm = Lower(); 3298 } 3299 3300 const SwPageFrm *pPage = 0; 3301 const sal_Bool bWin = pGlobalShell->GetWin() ? sal_True : sal_False; 3302 3303 while ( IsAnLower( pFrm ) ) 3304 { 3305 SwRect aPaintRect( pFrm->PaintArea() ); 3306 if( aShortCut.Stop( aPaintRect ) ) 3307 break; 3308 if ( bCnt && pProgress ) 3309 pProgress->Reschedule(); 3310 3311 //Wenn ein Frm es explizit will muss retouchiert werden. 3312 //Erst die Retouche, denn selbige koennte die aligned'en Raender 3313 //plaetten. 3314 if ( pFrm->IsRetouche() ) 3315 { 3316 if ( pFrm->IsRetoucheFrm() && bWin && !pFrm->GetNext() ) 3317 { if ( !pPage ) 3318 pPage = FindPageFrm(); 3319 pFrm->Retouche( pPage, rRect ); 3320 } 3321 pFrm->ResetRetouche(); 3322 } 3323 3324 if ( rRect.IsOver( aPaintRect ) ) 3325 { 3326 if ( bCnt && pFrm->IsCompletePaint() && 3327 !rRect.IsInside( aPaintRect ) && GetpApp()->AnyInput( INPUT_KEYBOARD ) ) 3328 { 3329 //fix(8104): Es kann vorkommen, dass die Verarbeitung nicht 3330 //vollstaendig war, aber trotzdem Teile des Absatzes gepaintet 3331 //werden. In der Folge werden dann evtl. wiederum andere Teile 3332 //des Absatzes garnicht mehr gepaintet. Einziger Ausweg scheint 3333 //hier ein Invalidieren der Windows zu sein. 3334 //Um es nicht alzu Heftig werden zu lassen versuche ich hier 3335 //das Rechteck zu begrenzen indem der gewuenschte Teil gepaintet 3336 //und nur die uebrigen Absatzanteile invalidiert werden. 3337 if ( aPaintRect.Left() == rRect.Left() && 3338 aPaintRect.Right() == rRect.Right() ) 3339 { 3340 aPaintRect.Bottom( rRect.Top() - 1 ); 3341 if ( aPaintRect.Height() > 0 ) 3342 pGlobalShell->InvalidateWindows(aPaintRect); 3343 aPaintRect.Top( rRect.Bottom() + 1 ); 3344 aPaintRect.Bottom( pFrm->Frm().Bottom() ); 3345 if ( aPaintRect.Height() > 0 ) 3346 pGlobalShell->InvalidateWindows(aPaintRect); 3347 aPaintRect.Top( pFrm->Frm().Top() ); 3348 aPaintRect.Bottom( pFrm->Frm().Bottom() ); 3349 } 3350 else 3351 { 3352 pGlobalShell->InvalidateWindows( aPaintRect ); 3353 pFrm = pFrm->GetNext(); 3354 if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) ) 3355 pFrm->Calc(); 3356 continue; 3357 } 3358 } 3359 pFrm->ResetCompletePaint(); 3360 aPaintRect._Intersection( rRect ); 3361 3362 pFrm->Paint( aPaintRect ); 3363 3364 if ( Lower() && Lower()->IsColumnFrm() ) 3365 { 3366 //Ggf. die Spaltentrennlinien malen. Fuer den Seitenbody ist 3367 //nicht der Upper sondern die Seite Zustaendig. 3368 const SwFrmFmt *pFmt = GetUpper() && GetUpper()->IsPageFrm() 3369 ? GetUpper()->GetFmt() 3370 : GetFmt(); 3371 const SwFmtCol &rCol = pFmt->GetCol(); 3372 if ( rCol.GetLineAdj() != COLADJ_NONE ) 3373 { 3374 if ( !pPage ) 3375 pPage = pFrm->FindPageFrm(); 3376 3377 PaintColLines( aPaintRect, rCol, pPage ); 3378 } 3379 } 3380 } 3381 if ( !bCnt && pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() ) 3382 ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm->GetNext() ); 3383 3384 pFrm = pFrm->GetNext(); 3385 if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) ) 3386 pFrm->Calc(); 3387 } 3388 } 3389 3390 3391 /** FlyFrm::IsBackgroundTransparent - for feature #99657# 3392 3393 OD 12.08.2002 3394 determines, if background of fly frame has to be drawn transparent 3395 declaration found in /core/inc/flyfrm.cxx 3396 OD 08.10.2002 #103898# - If the background of the fly frame itself is not 3397 transparent and the background is inherited from its parent/grandparent, 3398 the background brush, used for drawing, has to be investigated for transparency. 3399 3400 @author OD 3401 3402 @return true, if background is transparent drawn. 3403 */ 3404 sal_Bool SwFlyFrm::IsBackgroundTransparent() const 3405 { 3406 sal_Bool bBackgroundTransparent = GetFmt()->IsBackgroundTransparent(); 3407 if ( !bBackgroundTransparent && 3408 static_cast<const SwFlyFrmFmt*>(GetFmt())->IsBackgroundBrushInherited() ) 3409 { 3410 const SvxBrushItem* pBackgrdBrush = 0; 3411 const Color* pSectionTOXColor = 0; 3412 SwRect aDummyRect; 3413 3414 //UUUU 3415 FillAttributesPtr aFillAttributes; 3416 3417 if ( GetBackgroundBrush( aFillAttributes, pBackgrdBrush, pSectionTOXColor, aDummyRect, false) ) 3418 { 3419 if ( pSectionTOXColor && 3420 (pSectionTOXColor->GetTransparency() != 0) && 3421 (pSectionTOXColor->GetColor() != COL_TRANSPARENT) ) 3422 { 3423 bBackgroundTransparent = sal_True; 3424 } 3425 else if(aFillAttributes.get() && aFillAttributes->isUsed()) //UUUU 3426 { 3427 bBackgroundTransparent = aFillAttributes->isTransparent(); 3428 } 3429 else if ( pBackgrdBrush ) 3430 { 3431 if ( (pBackgrdBrush->GetColor().GetTransparency() != 0) && 3432 (pBackgrdBrush->GetColor() != COL_TRANSPARENT) ) 3433 { 3434 bBackgroundTransparent = sal_True; 3435 } 3436 else 3437 { 3438 const GraphicObject *pTmpGrf = 3439 static_cast<const GraphicObject*>(pBackgrdBrush->GetGraphicObject()); 3440 if ( (pTmpGrf) && 3441 (pTmpGrf->GetAttr().GetTransparency() != 0) 3442 ) 3443 { 3444 bBackgroundTransparent = sal_True; 3445 } 3446 } 3447 } 3448 } 3449 } 3450 3451 return bBackgroundTransparent; 3452 }; 3453 3454 /** FlyFrm::IsShadowTransparent - for feature #99657# 3455 3456 OD 13.08.2002 3457 determine, if shadow color of fly frame has to be drawn transparent 3458 declaration found in /core/inc/flyfrm.cxx 3459 3460 @author OD 3461 3462 @return true, if shadow color is transparent. 3463 */ 3464 sal_Bool SwFlyFrm::IsShadowTransparent() const 3465 { 3466 return GetFmt()->IsShadowTransparent(); 3467 }; 3468 3469 /************************************************************************* 3470 |* 3471 |* SwFlyFrm::IsPaint() 3472 |* 3473 |* Ersterstellung MA 16. Jan. 97 3474 |* Letzte Aenderung MA 16. Jan. 97 3475 |* 3476 |*************************************************************************/ 3477 3478 sal_Bool SwFlyFrm::IsPaint( SdrObject *pObj, const ViewShell *pSh ) 3479 { 3480 SdrObjUserCall *pUserCall; 3481 3482 if ( 0 == ( pUserCall = GetUserCall(pObj) ) ) 3483 return sal_True; 3484 3485 //Attributabhaengig nicht fuer Drucker oder PreView painten 3486 sal_Bool bPaint = pFlyOnlyDraw || 3487 ((SwContact*)pUserCall)->GetFmt()->GetPrint().GetValue(); 3488 if ( !bPaint ) 3489 bPaint = pSh->GetWin() && !pSh->IsPreView(); 3490 3491 if ( bPaint ) 3492 { 3493 //Das Paint kann evtl. von von uebergeordneten Flys verhindert werden. 3494 SwFrm *pAnch = 0; 3495 // --> OD #i117962# 3496 if ( pObj->ISA(SwFlyDrawObj) ) 3497 { 3498 bPaint = false; 3499 } 3500 // <-- 3501 else if ( pObj->ISA(SwVirtFlyDrawObj) ) 3502 { 3503 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 3504 if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly ) 3505 return sal_True; 3506 3507 //Die Anzeige eines Zwischenstadiums vermeiden, Flys die nicht mit 3508 //der Seite auf der sie verankert sind ueberlappen werden auch 3509 //nicht gepaintet. 3510 //HACK: Ausnahme: Drucken von Rahmen in Tabellen, diese koennen 3511 //bei uebergrossen Tabellen (HTML) schon mal auserhalb der Seite 3512 //stehen. 3513 SwPageFrm *pPage = pFly->FindPageFrm(); 3514 if ( pPage ) 3515 { 3516 if ( pPage->Frm().IsOver( pFly->Frm() ) ) 3517 pAnch = pFly->AnchorFrm(); 3518 else if ( bTableHack && 3519 pFly->Frm().Top() >= pFly->GetAnchorFrm()->Frm().Top() && 3520 pFly->Frm().Top() < pFly->GetAnchorFrm()->Frm().Bottom() && 3521 long(pSh->GetOut()) == 3522 long(pSh->getIDocumentDeviceAccess()->getPrinter( false ) ) ) 3523 { 3524 pAnch = pFly->AnchorFrm(); 3525 } 3526 } 3527 3528 } 3529 else 3530 { 3531 // OD 13.10.2003 #i19919# - consider 'virtual' drawing objects 3532 // OD 2004-03-29 #i26791# 3533 pAnch = ((SwDrawContact*)pUserCall)->GetAnchorFrm( pObj ); 3534 if ( pAnch ) 3535 { 3536 if ( !pAnch->GetValidPosFlag() ) 3537 pAnch = 0; 3538 else if ( long(pSh->GetOut()) == long(pSh->getIDocumentDeviceAccess()->getPrinter( false ))) 3539 { 3540 //HACK: fuer das Drucken muessen wir ein paar Objekte 3541 //weglassen, da diese sonst doppelt gedruckt werden. 3542 //Die Objekte sollen gedruckt werden, wenn der TableHack 3543 //gerade greift. In der Folge duerfen sie nicht gedruckt werden 3544 //wenn sie mit der Seite dran sind, ueber der sie von der 3545 //Position her gerade schweben. 3546 const SwPageFrm *pPage = pAnch->FindPageFrm(); 3547 if ( !bTableHack && 3548 !pPage->Frm().IsOver( pObj->GetCurrentBoundRect() ) ) 3549 pAnch = 0; 3550 } 3551 } 3552 else 3553 { 3554 // OD 02.07.2003 #108784# - debug assert 3555 if ( !pObj->ISA(SdrObjGroup) ) 3556 { 3557 ASSERT( false, "<SwFlyFrm::IsPaint(..)> - paint of drawing object without anchor frame!?" ); 3558 } 3559 } 3560 } 3561 if ( pAnch ) 3562 { 3563 if ( pAnch->IsInFly() ) 3564 bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(), 3565 pSh ); 3566 else if ( pFlyOnlyDraw ) 3567 bPaint = sal_False; 3568 } 3569 else 3570 bPaint = sal_False; 3571 } 3572 return bPaint; 3573 } 3574 3575 /************************************************************************* 3576 |* SwCellFrm::Paint( const SwRect& ) const 3577 |*************************************************************************/ 3578 void SwCellFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3579 { 3580 if ( GetLayoutRowSpan() >= 1 ) 3581 SwLayoutFrm::Paint( rRect ); 3582 } 3583 3584 /************************************************************************* 3585 |* 3586 |* SwFlyFrm::Paint() 3587 |* 3588 |* Ersterstellung MA ?? 3589 |* Letzte Aenderung MA 16. Jan. 97 3590 |* 3591 |*************************************************************************/ 3592 3593 //Weiter unten definiert 3594 void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay, 3595 const SwRect &rRect, const SwPageFrm *pPage ); 3596 3597 void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3598 { 3599 //begin:optimize thumbnail generate and store procedure to improve odt saving performance, i120030 3600 ViewShell *pShell = getRootFrm()->GetCurrShell(); 3601 if (pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocShell()) 3602 { 3603 sal_Bool bInGenerateThumbnail = pShell->GetDoc()->GetDocShell()->IsInGenerateAndStoreThumbnail(); 3604 if (bInGenerateThumbnail) 3605 { 3606 SwRect aVisRect = pShell->VisArea(); 3607 if (!aVisRect.IsOver(Frm())) 3608 return; 3609 } 3610 } 3611 //end:i120030 3612 3613 //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die 3614 //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben. 3615 //z.B. #33066# 3616 pLines->LockLines(sal_True); 3617 3618 SwRect aRect( rRect ); 3619 aRect._Intersection( Frm() ); 3620 3621 OutputDevice* pOut = pGlobalShell->GetOut(); 3622 pOut->Push( PUSH_CLIPREGION ); 3623 pOut->SetClipRegion(); 3624 const SwPageFrm* pPage = FindPageFrm(); 3625 3626 const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm() 3627 ? (SwNoTxtFrm*)Lower() : 0; 3628 3629 bool bIsChart = false; //#i102950# don't paint additional borders for charts 3630 //check whether we have a chart 3631 if(pNoTxt) 3632 { 3633 const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode()); 3634 if( pNoTNd ) 3635 { 3636 SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode()); 3637 if( pOLENd && ChartHelper::IsChart( pOLENd->GetOLEObj().GetObject() ) ) 3638 bIsChart = true; 3639 } 3640 } 3641 3642 { 3643 bool bContour = GetFmt()->GetSurround().IsContour(); 3644 PolyPolygon aPoly; 3645 if ( bContour ) 3646 { 3647 // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True> 3648 // to indicate that method is called for paint in order to avoid 3649 // load of the intrinsic graphic. 3650 bContour = GetContour( aPoly, sal_True ); 3651 } 3652 3653 // --> OD 2005-06-08 #i47804# - distinguish complete background paint 3654 // and margin paint. 3655 // paint complete background for Writer text fly frames 3656 bool bPaintCompleteBack( !pNoTxt ); 3657 // <-- 3658 // paint complete background for transparent graphic and contour, 3659 // if own background color exists. 3660 const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false; 3661 if ( !bPaintCompleteBack && 3662 ( bIsGraphicTransparent|| bContour ) ) 3663 { 3664 const SwFrmFmt* pSwFrmFmt = dynamic_cast< const SwFrmFmt* >(GetFmt()); 3665 3666 if(pSwFrmFmt && RES_FLYFRMFMT == pSwFrmFmt->Which()) 3667 { 3668 //UUUU check for transparency 3669 const FillAttributesPtr aFillAttributes(pSwFrmFmt->getFillAttributes()); 3670 3671 if(aFillAttributes.get()) 3672 { 3673 bPaintCompleteBack = aFillAttributes->isTransparent(); 3674 } 3675 } 3676 else 3677 { 3678 const SvxBrushItem &rBack = GetFmt()->GetBackground(); 3679 // OD 07.08.2002 #99657# #GetTransChg# 3680 // to determine, if background has to be painted, by checking, if 3681 // background color is not COL_TRANSPARENT ("no fill"/"auto fill") 3682 // or a background graphic exists. 3683 bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) || 3684 rBack.GetGraphicPos() != GPOS_NONE; 3685 } 3686 } 3687 // paint of margin needed. 3688 const bool bPaintMarginOnly( !bPaintCompleteBack && 3689 Prt().SSize() != Frm().SSize() ); 3690 3691 // --> OD 2005-06-08 #i47804# - paint background of parent fly frame 3692 // for transparent graphics in layer Hell, if parent fly frame isn't 3693 // in layer Hell. It's only painted the intersection between the 3694 // parent fly frame area and the paint area <aRect> 3695 const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess(); 3696 3697 if ( bIsGraphicTransparent && 3698 GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() && 3699 GetAnchorFrm()->FindFlyFrm() ) 3700 { 3701 const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm(); 3702 if ( pParentFlyFrm->GetDrawObj()->GetLayer() != 3703 pIDDMA->GetHellId() ) 3704 { 3705 SwFlyFrm* pOldRet = pRetoucheFly2; 3706 pRetoucheFly2 = const_cast<SwFlyFrm*>(this); 3707 3708 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm ); 3709 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3710 SwRect aPaintRect( aRect ); 3711 aPaintRect._Intersection( pParentFlyFrm->Frm() ); 3712 pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False ); 3713 3714 pRetoucheFly2 = pOldRet; 3715 } 3716 } 3717 3718 if ( bPaintCompleteBack || bPaintMarginOnly ) 3719 { 3720 //#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder 3721 //das orig. Rect bekommt, aber PaintBackground das begrenzte. 3722 3723 // OD 2004-04-23 #116347# 3724 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 3725 pOut->SetLineColor(); 3726 3727 pPage = FindPageFrm(); 3728 3729 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 3730 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3731 3732 // OD 06.08.2002 #99657# - paint border before painting background 3733 // paint border 3734 { 3735 SwRect aTmp( rRect ); 3736 PaintBorder( aTmp, pPage, rAttrs ); 3737 } 3738 3739 // paint background 3740 { 3741 SwRegionRects aRegion( aRect ); 3742 // --> OD 2007-12-13 #i80822# 3743 // suppress painting of background in printing area for 3744 // non-transparent graphics. 3745 // if ( bPaintMarginOnly ) 3746 if ( bPaintMarginOnly || 3747 ( pNoTxt && !bIsGraphicTransparent ) ) 3748 // <-- 3749 { 3750 //Was wir eigentlich Painten wollen ist der schmale Streifen 3751 //zwischen PrtArea und aeusserer Umrandung. 3752 SwRect aTmp( Prt() ); aTmp += Frm().Pos(); 3753 aRegion -= aTmp; 3754 } 3755 if ( bContour ) 3756 { 3757 pOut->Push(); 3758 // --> OD 2007-12-13 #i80822# 3759 // apply clip region under the same conditions, which are 3760 // used in <SwNoTxtFrm::Paint(..)> to set the clip region 3761 // for painting the graphic/OLE. Thus, the clip region is 3762 // also applied for the PDF export. 3763 // if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER ) 3764 ViewShell *pSh = getRootFrm()->GetCurrShell(); 3765 if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() ) 3766 // <-- 3767 { 3768 pOut->SetClipRegion( aPoly ); 3769 } 3770 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 3771 PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True ); 3772 pOut->Pop(); 3773 } 3774 else 3775 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 3776 PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True ); 3777 } 3778 3779 pOut->Pop(); 3780 } 3781 } 3782 3783 // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and 3784 // the subsidiary lines of its lowers on its own, due to overlapping with 3785 // other fly frames or other objects. 3786 if( pGlobalShell->GetWin() 3787 && !bIsChart ) //#i102950# don't paint additional borders for charts 3788 { 3789 bool bSubsLineRectsCreated; 3790 if ( pSubsLines ) 3791 { 3792 // Lock already existing subsidiary lines 3793 pSubsLines->LockLines( sal_True ); 3794 bSubsLineRectsCreated = false; 3795 } 3796 else 3797 { 3798 // create new subsidiardy lines 3799 pSubsLines = new SwSubsRects; 3800 bSubsLineRectsCreated = true; 3801 } 3802 3803 bool bSpecSubsLineRectsCreated; 3804 if ( pSpecSubsLines ) 3805 { 3806 // Lock already existing special subsidiary lines 3807 pSpecSubsLines->LockLines( sal_True ); 3808 bSpecSubsLineRectsCreated = false; 3809 } 3810 else 3811 { 3812 // create new special subsidiardy lines 3813 pSpecSubsLines = new SwSubsRects; 3814 bSpecSubsLineRectsCreated = true; 3815 } 3816 // Add subsidiary lines of fly frame and its lowers 3817 RefreshLaySubsidiary( pPage, aRect ); 3818 // paint subsidiary lines of fly frame and its lowers 3819 pSpecSubsLines->PaintSubsidiary( pOut, NULL ); 3820 pSubsLines->PaintSubsidiary( pOut, pLines ); 3821 if ( !bSubsLineRectsCreated ) 3822 // unlock subsidiary lines 3823 pSubsLines->LockLines( sal_False ); 3824 else 3825 // delete created subsidiary lines container 3826 DELETEZ( pSubsLines ); 3827 3828 if ( !bSpecSubsLineRectsCreated ) 3829 // unlock special subsidiary lines 3830 pSpecSubsLines->LockLines( sal_False ); 3831 else 3832 { 3833 // delete created special subsidiary lines container 3834 DELETEZ( pSpecSubsLines ); 3835 } 3836 } 3837 3838 SwLayoutFrm::Paint( aRect ); 3839 3840 Validate(); 3841 3842 // OD 19.12.2002 #106318# - first paint lines added by fly frame paint 3843 // and then unlock other lines. 3844 pLines->PaintLines( pOut ); 3845 pLines->LockLines( sal_False ); 3846 3847 pOut->Pop(); 3848 3849 if ( pProgress && pNoTxt ) 3850 pProgress->Reschedule(); 3851 } 3852 /************************************************************************* 3853 |* 3854 |* SwTabFrm::Paint() 3855 |* 3856 |* Ersterstellung MA 11. May. 93 3857 |* Letzte Aenderung MA 23. Mar. 95 3858 |* 3859 |*************************************************************************/ 3860 3861 void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3862 { 3863 if ( pGlobalShell->GetViewOptions()->IsTable() ) 3864 { 3865 // --> collapsing borders FME 2005-05-27 #i29550# 3866 if ( IsCollapsingBorders() ) 3867 { 3868 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 3869 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3870 3871 // paint shadow 3872 if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE ) 3873 { 3874 SwRect aRect; 3875 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True ); 3876 PaintShadow( rRect, aRect, rAttrs ); 3877 } 3878 3879 // paint lines 3880 SwTabFrmPainter aHelper( *this ); 3881 aHelper.PaintLines( *pGlobalShell->GetOut(), rRect ); 3882 } 3883 // <-- collapsing 3884 3885 SwLayoutFrm::Paint( rRect ); 3886 } 3887 // OD 10.01.2003 #i6467# - no light grey rectangle for page preview 3888 else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() ) 3889 { 3890 // OD 10.01.2003 #i6467# - intersect output rectangle with table frame 3891 SwRect aTabRect( Prt() ); 3892 aTabRect.Pos() += Frm().Pos(); 3893 SwRect aTabOutRect( rRect ); 3894 aTabOutRect.Intersection( aTabRect ); 3895 pGlobalShell->GetViewOptions()-> 3896 DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY ); 3897 } 3898 ((SwTabFrm*)this)->ResetComplete(); 3899 } 3900 3901 /************************************************************************* 3902 |* 3903 |* SwFrm::PaintShadow() 3904 |* 3905 |* Beschreibung Malt einen Schatten wenns das FrmFormat fordert. 3906 |* Der Schatten wird immer an den auesseren Rand des OutRect gemalt. 3907 |* Das OutRect wird ggf. so verkleinert, dass auf diesem das 3908 |* malen der Umrandung stattfinden kann. 3909 |* Ersterstellung MA 21. Dec. 92 3910 |* Letzte Aenderung MA 29. May. 97 3911 |* 3912 |*************************************************************************/ 3913 /// OD 23.08.2002 #99657# 3914 /// draw full shadow rectangle for frames with transparent drawn backgrounds. 3915 void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect, 3916 const SwBorderAttrs &rAttrs ) const 3917 { 3918 const SvxShadowItem &rShadow = rAttrs.GetShadow(); 3919 const long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth() ); 3920 const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() ); 3921 3922 SwRects aRegion( 2, 2 ); 3923 SwRect aOut( rOutRect ); 3924 3925 const sal_Bool bCnt = IsCntntFrm(); 3926 const sal_Bool bTop = !bCnt || rAttrs.GetTopLine ( *(this) ) ? sal_True : sal_False; 3927 const sal_Bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? sal_True : sal_False; 3928 3929 SvxShadowLocation eLoc = rShadow.GetLocation(); 3930 3931 SWRECTFN( this ) 3932 if( IsVertical() ) 3933 { 3934 switch( eLoc ) 3935 { 3936 case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break; 3937 case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break; 3938 case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break; 3939 case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_TOPLEFT; break; 3940 default: break; 3941 } 3942 } 3943 3944 /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to 3945 /// be drawn or only two shadow rectangles beside the frame. 3946 /// draw full shadow rectangle, if frame background is drawn transparent. 3947 /// Status Quo: 3948 /// SwLayoutFrm can have transparent drawn backgrounds. Thus, 3949 /// "asked" their frame format. 3950 sal_Bool bDrawFullShadowRectangle = 3951 ( IsLayoutFrm() && 3952 (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent() 3953 ); 3954 switch ( eLoc ) 3955 { 3956 case SVX_SHADOW_BOTTOMRIGHT: 3957 { 3958 if ( bDrawFullShadowRectangle ) 3959 { 3960 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3961 aOut.Top( aOut.Top() + nHeight ); 3962 aOut.Left( aOut.Left() + nWidth ); 3963 aRegion.Insert( aOut, aRegion.Count() ); 3964 } 3965 else 3966 { 3967 aOut.Top ( aOut.Bottom() - nHeight ); 3968 aOut.Left( aOut.Left() + nWidth ); 3969 if ( bBottom ) 3970 aRegion.Insert( aOut, aRegion.Count() ); 3971 aOut.Left( aOut.Right() - nWidth ); 3972 aOut.Top ( rOutRect.Top() + nHeight ); 3973 if ( bBottom ) 3974 aOut.Bottom( aOut.Bottom() - nHeight ); 3975 if ( bCnt && (!bTop || !bBottom) ) 3976 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 3977 aRegion.Insert( aOut, aRegion.Count() ); 3978 } 3979 3980 rOutRect.Right ( rOutRect.Right() - nWidth ); 3981 rOutRect.Bottom( rOutRect.Bottom()- nHeight ); 3982 } 3983 break; 3984 case SVX_SHADOW_TOPLEFT: 3985 { 3986 if ( bDrawFullShadowRectangle ) 3987 { 3988 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3989 aOut.Bottom( aOut.Bottom() - nHeight ); 3990 aOut.Right( aOut.Right() - nWidth ); 3991 aRegion.Insert( aOut, aRegion.Count() ); 3992 } 3993 else 3994 { 3995 aOut.Bottom( aOut.Top() + nHeight ); 3996 aOut.Right ( aOut.Right() - nWidth ); 3997 if ( bTop ) 3998 aRegion.Insert( aOut, aRegion.Count() ); 3999 aOut.Right ( aOut.Left() + nWidth ); 4000 aOut.Bottom( rOutRect.Bottom() - nHeight ); 4001 if ( bTop ) 4002 aOut.Top( aOut.Top() + nHeight ); 4003 if ( bCnt && (!bBottom || !bTop) ) 4004 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 4005 aRegion.Insert( aOut, aRegion.Count() ); 4006 } 4007 4008 rOutRect.Left( rOutRect.Left() + nWidth ); 4009 rOutRect.Top( rOutRect.Top() + nHeight ); 4010 } 4011 break; 4012 case SVX_SHADOW_TOPRIGHT: 4013 { 4014 if ( bDrawFullShadowRectangle ) 4015 { 4016 /// OD 06.08.2002 #99657# - draw full shadow rectangle 4017 aOut.Bottom( aOut.Bottom() - nHeight); 4018 aOut.Left( aOut.Left() + nWidth ); 4019 aRegion.Insert( aOut, aRegion.Count() ); 4020 } 4021 else 4022 { 4023 aOut.Bottom( aOut.Top() + nHeight ); 4024 aOut.Left ( aOut.Left()+ nWidth ); 4025 if ( bTop ) 4026 aRegion.Insert( aOut, aRegion.Count() ); 4027 aOut.Left ( aOut.Right() - nWidth ); 4028 aOut.Bottom( rOutRect.Bottom() - nHeight ); 4029 if ( bTop ) 4030 aOut.Top( aOut.Top() + nHeight ); 4031 if ( bCnt && (!bBottom || bTop) ) 4032 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 4033 aRegion.Insert( aOut, aRegion.Count() ); 4034 } 4035 4036 rOutRect.Right( rOutRect.Right() - nWidth ); 4037 rOutRect.Top( rOutRect.Top() + nHeight ); 4038 } 4039 break; 4040 case SVX_SHADOW_BOTTOMLEFT: 4041 { 4042 if ( bDrawFullShadowRectangle ) 4043 { 4044 /// OD 06.08.2002 #99657# - draw full shadow rectangle 4045 aOut.Top( aOut.Top() + nHeight ); 4046 aOut.Right( aOut.Right() - nWidth ); 4047 aRegion.Insert( aOut, aRegion.Count() ); 4048 } 4049 else 4050 { 4051 aOut.Top ( aOut.Bottom()- nHeight ); 4052 aOut.Right( aOut.Right() - nWidth ); 4053 if ( bBottom ) 4054 aRegion.Insert( aOut, aRegion.Count() ); 4055 aOut.Right( aOut.Left() + nWidth ); 4056 aOut.Top( rOutRect.Top() + nHeight ); 4057 if ( bBottom ) 4058 aOut.Bottom( aOut.Bottom() - nHeight ); 4059 if ( bCnt && (!bTop || !bBottom) ) 4060 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 4061 aRegion.Insert( aOut, aRegion.Count() ); 4062 } 4063 4064 rOutRect.Left( rOutRect.Left() + nWidth ); 4065 rOutRect.Bottom( rOutRect.Bottom() - nHeight ); 4066 } 4067 break; 4068 default: 4069 ASSERT( !this, "new ShadowLocation() ?" ) 4070 break; 4071 } 4072 4073 OutputDevice *pOut = pGlobalShell->GetOut(); 4074 4075 sal_uLong nOldDrawMode = pOut->GetDrawMode(); 4076 Color aShadowColor( rShadow.GetColor() ); 4077 if( aRegion.Count() && pGlobalShell->GetWin() && 4078 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 4079 { 4080 // Is heigh contrast mode, the output device has already set the 4081 // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function 4082 // to ignore the setting of a new color. Therefore we have to reset 4083 // the drawing mode 4084 pOut->SetDrawMode( 0 ); 4085 aShadowColor = SwViewOption::GetFontColor(); 4086 } 4087 4088 if ( pOut->GetFillColor() != aShadowColor ) 4089 pOut->SetFillColor( aShadowColor ); 4090 4091 pOut->SetDrawMode( nOldDrawMode ); 4092 4093 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 4094 { 4095 SwRect &rOut = aRegion[i]; 4096 aOut = rOut; 4097 // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle 4098 // no alignment necessary, because (1) <rRect> is already aligned 4099 // and because (2) paint of border and background will occur later. 4100 // Thus, (1) assures that no conflicts with neighbour object will occure 4101 // and (2) assures that border and background is not affected by the 4102 // shadow paint. 4103 /* 4104 ::SwAlignRect( aOut, pGlobalShell ); 4105 */ 4106 if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 ) 4107 { 4108 aOut._Intersection( rRect ); 4109 pOut->DrawRect( aOut.SVRect() ); 4110 } 4111 } 4112 } 4113 4114 /************************************************************************* 4115 |* 4116 |* SwFrm::PaintBorderLine() 4117 |* 4118 |* Ersterstellung MA 22. Dec. 92 4119 |* Letzte Aenderung MA 22. Jan. 95 4120 |* 4121 |*************************************************************************/ 4122 4123 void SwFrm::PaintBorderLine( const SwRect& rRect, 4124 const SwRect& rOutRect, 4125 const SwPageFrm *pPage, 4126 const Color *pColor ) const 4127 { 4128 if ( !rOutRect.IsOver( rRect ) ) 4129 return; 4130 4131 SwRect aOut( rOutRect ); 4132 aOut._Intersection( rRect ); 4133 4134 const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0; 4135 sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB : 4136 ( IsInSct() ? SUBCOL_SECT : 4137 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) ); 4138 if( pColor && pGlobalShell->GetWin() && 4139 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 4140 { 4141 pColor = &SwViewOption::GetFontColor(); 4142 } 4143 4144 //if ( pPage->GetSortedObjs() ) 4145 //{ 4146 // SwRegionRects aRegion( aOut, 4, 1 ); 4147 // ::lcl_SubtractFlys( this, pPage, aOut, aRegion ); 4148 // for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 4149 // pLines->AddLineRect( aRegion[i], pColor, pTab, nSubCol ); 4150 //} 4151 //else 4152 pLines->AddLineRect( aOut, pColor, pTab, nSubCol ); 4153 } 4154 4155 /************************************************************************* 4156 |* 4157 |* SwFrm::PaintBorderLines() 4158 |* 4159 |* Beschreibung Nur alle Linien einfach oder alle Linien doppelt!!!! 4160 |* Ersterstellung MA 22. Dec. 92 4161 |* Letzte Aenderung MA 22. Mar. 95 4162 |* 4163 |*************************************************************************/ 4164 4165 // OD 29.04.2003 #107169# - method called for left and right border rectangles. 4166 // For a printer output device perform adjustment for non-overlapping top and 4167 // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate 4168 // printer output device. 4169 // NOTE: For printer output device left/right border rectangle <_iorRect> 4170 // has to be already non-overlapping the outer top/bottom border rectangle. 4171 void MA_FASTCALL lcl_SubTopBottom( SwRect& _iorRect, 4172 const SvxBoxItem& _rBox, 4173 const SwBorderAttrs& _rAttrs, 4174 const SwFrm& _rFrm, 4175 const SwRectFn& _rRectFn, 4176 const sal_Bool _bPrtOutputDev ) 4177 { 4178 const sal_Bool bCnt = _rFrm.IsCntntFrm(); 4179 if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() && 4180 ( !bCnt || _rAttrs.GetTopLine( _rFrm ) ) 4181 ) 4182 { 4183 // substract distance between outer and inner line. 4184 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() ); 4185 // OD 19.05.2003 #109667# - non-overlapping border rectangles: 4186 // adjust x-/y-position, if inner top line is a hair line (width = 1) 4187 sal_Bool bIsInnerTopLineHairline = sal_False; 4188 if ( !_bPrtOutputDev ) 4189 { 4190 // additionally substract width of top outer line 4191 // --> left/right inner/outer line doesn't overlap top outer line. 4192 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() ); 4193 } 4194 else 4195 { 4196 // OD 29.04.2003 #107169# - additionally substract width of top inner line 4197 // --> left/right inner/outer line doesn't overlap top inner line. 4198 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() ); 4199 bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1; 4200 } 4201 (_iorRect.*_rRectFn->fnSubTop)( -nDist ); 4202 // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line 4203 // is a hair line 4204 if ( bIsInnerTopLineHairline ) 4205 { 4206 if ( _rFrm.IsVertical() ) 4207 { 4208 // right of border rectangle has to be checked and adjusted 4209 Point aCompPt( _iorRect.Right(), 0 ); 4210 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() ); 4211 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4212 aRefPt, aCompPt, 4213 sal_True, -1 ); 4214 _iorRect.Right( aCompPt.X() ); 4215 } 4216 else 4217 { 4218 // top of border rectangle has to be checked and adjusted 4219 Point aCompPt( 0, _iorRect.Top() ); 4220 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 ); 4221 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4222 aRefPt, aCompPt, 4223 sal_False, +1 ); 4224 _iorRect.Top( aCompPt.Y() ); 4225 } 4226 } 4227 } 4228 4229 if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() && 4230 ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) ) 4231 ) 4232 { 4233 // substract distance between outer and inner line. 4234 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() ); 4235 // OD 19.05.2003 #109667# - non-overlapping border rectangles: 4236 // adjust x-/y-position, if inner bottom line is a hair line (width = 1) 4237 sal_Bool bIsInnerBottomLineHairline = sal_False; 4238 if ( !_bPrtOutputDev ) 4239 { 4240 // additionally substract width of bottom outer line 4241 // --> left/right inner/outer line doesn't overlap bottom outer line. 4242 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() ); 4243 } 4244 else 4245 { 4246 // OD 29.04.2003 #107169# - additionally substract width of bottom inner line 4247 // --> left/right inner/outer line doesn't overlap bottom inner line. 4248 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() ); 4249 bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1; 4250 } 4251 (_iorRect.*_rRectFn->fnAddBottom)( -nDist ); 4252 // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner 4253 // bottom line is a hair line. 4254 if ( bIsInnerBottomLineHairline ) 4255 { 4256 if ( _rFrm.IsVertical() ) 4257 { 4258 // left of border rectangle has to be checked and adjusted 4259 Point aCompPt( _iorRect.Left(), 0 ); 4260 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() ); 4261 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4262 aRefPt, aCompPt, 4263 sal_True, +1 ); 4264 _iorRect.Left( aCompPt.X() ); 4265 } 4266 else 4267 { 4268 // bottom of border rectangle has to be checked and adjusted 4269 Point aCompPt( 0, _iorRect.Bottom() ); 4270 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 ); 4271 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4272 aRefPt, aCompPt, 4273 sal_False, -1 ); 4274 _iorRect.Bottom( aCompPt.Y() ); 4275 } 4276 } 4277 } 4278 } 4279 4280 // method called for top and bottom border rectangles. 4281 void MA_FASTCALL lcl_SubLeftRight( SwRect& rRect, 4282 const SvxBoxItem& rBox, 4283 const SwRectFn& rRectFn ) 4284 { 4285 if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() ) 4286 { 4287 const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() ) 4288 + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() ); 4289 (rRect.*rRectFn->fnSubLeft)( -nDist ); 4290 } 4291 4292 if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() ) 4293 { 4294 const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() ) 4295 + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() ); 4296 (rRect.*rRectFn->fnAddRight)( -nDist ); 4297 } 4298 } 4299 4300 // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine> 4301 // into new method <lcl_PaintLeftRightLine(..)> 4302 void lcl_PaintLeftRightLine( const sal_Bool _bLeft, 4303 const SwFrm& _rFrm, 4304 const SwPageFrm& _rPage, 4305 const SwRect& _rOutRect, 4306 const SwRect& _rRect, 4307 const SwBorderAttrs& _rAttrs, 4308 const SwRectFn& _rRectFn ) 4309 { 4310 const SvxBoxItem& rBox = _rAttrs.GetBox(); 4311 const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft(); 4312 const SvxBorderLine* pLeftRightBorder = 0; 4313 if ( _bLeft ) 4314 { 4315 pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft(); 4316 } 4317 else 4318 { 4319 pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight(); 4320 } 4321 // OD 06.05.2003 #107169# - init boolean indicating printer output device. 4322 const sal_Bool bPrtOutputDev = 4323 ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() ); 4324 4325 if ( !pLeftRightBorder ) 4326 { 4327 return; 4328 } 4329 4330 SwRect aRect( _rOutRect ); 4331 if ( _bLeft ) 4332 { 4333 (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) - 4334 (aRect.*_rRectFn->fnGetWidth)() ); 4335 } 4336 else 4337 { 4338 (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) - 4339 (aRect.*_rRectFn->fnGetWidth)() ); 4340 } 4341 4342 const sal_Bool bCnt = _rFrm.IsCntntFrm(); 4343 4344 if ( bCnt ) 4345 { 4346 ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn ); 4347 } 4348 4349 // OD 06.05.2003 #107169# - adjustments for printer output device 4350 if ( bPrtOutputDev ) 4351 { 4352 // substract width of outer top line. 4353 if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) ) 4354 { 4355 long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() ); 4356 (aRect.*_rRectFn->fnSubTop)( -nDist ); 4357 // OD 19.05.2003 #109667# - If outer top line is hair line, calculated 4358 // top has to be adjusted. 4359 if ( nDist == 1 ) 4360 { 4361 if ( _rFrm.IsVertical() ) 4362 { 4363 // right of border rectangle has to be checked and adjusted 4364 Point aCompPt( aRect.Right(), 0 ); 4365 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() ); 4366 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4367 aRefPt, aCompPt, 4368 sal_True, -1 ); 4369 aRect.Right( aCompPt.X() ); 4370 } 4371 else 4372 { 4373 // top of border rectangle has to be checked and adjusted 4374 Point aCompPt( 0, aRect.Top() ); 4375 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 ); 4376 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4377 aRefPt, aCompPt, 4378 sal_False, +1 ); 4379 aRect.Top( aCompPt.Y() ); 4380 } 4381 } 4382 } 4383 // substract width of outer bottom line. 4384 if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) ) 4385 { 4386 long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth()); 4387 (aRect.*_rRectFn->fnAddBottom)( -nDist ); 4388 // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated 4389 // top has to be adjusted. 4390 if ( nDist == 1 ) 4391 { 4392 if ( _rFrm.IsVertical() ) 4393 { 4394 // left of border rectangle has to be checked and adjusted 4395 Point aCompPt( aRect.Left(), 0 ); 4396 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() ); 4397 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4398 aRefPt, aCompPt, 4399 sal_True, +1 ); 4400 aRect.Left( aCompPt.X() ); 4401 } 4402 else 4403 { 4404 // bottom of border rectangle has to be checked and adjusted 4405 Point aCompPt( 0, aRect.Bottom() ); 4406 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 ); 4407 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4408 aRefPt, aCompPt, 4409 sal_False, -1 ); 4410 aRect.Bottom( aCompPt.Y() ); 4411 } 4412 } 4413 } 4414 } 4415 4416 if ( !pLeftRightBorder->GetInWidth() ) 4417 { 4418 // OD 06.05.2003 #107169# - add 6th parameter 4419 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev ); 4420 } 4421 4422 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4423 { 4424 SwRect aPaintRect( aRect ); 4425 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4426 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle 4427 // to the prior left postion with width of one twip. 4428 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 ) 4429 { 4430 if ( _bLeft ) 4431 { 4432 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() ); 4433 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() ); 4434 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4435 } 4436 else 4437 { 4438 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4439 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4440 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4441 } 4442 } 4443 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() ); 4444 } 4445 4446 if ( pLeftRightBorder->GetInWidth() ) 4447 { 4448 const long nDist = ::lcl_MinWidthDist( pLeftRightBorder->GetDistance() ); 4449 long nWidth = ::lcl_AlignWidth( pLeftRightBorder->GetInWidth() ); 4450 if ( _bLeft ) 4451 { 4452 (aRect.*_rRectFn->fnAddRight)( nDist + nWidth ); 4453 (aRect.*_rRectFn->fnSubLeft)( nWidth - (aRect.*_rRectFn->fnGetWidth)() ); 4454 } 4455 else 4456 { 4457 (aRect.*_rRectFn->fnSubLeft)( nDist + nWidth ); 4458 (aRect.*_rRectFn->fnAddRight)( nWidth - (aRect.*_rRectFn->fnGetWidth)() ); 4459 } 4460 // OD 06.05.2003 #107169# - add 6th parameter 4461 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev ); 4462 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4463 { 4464 SwRect aPaintRect( aRect ); 4465 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4466 // if <SwAlignRect> reveals rectangle with no width, adjust 4467 // rectangle to the prior left postion with width of one twip. 4468 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 ) 4469 { 4470 if ( _bLeft ) 4471 { 4472 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() ); 4473 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() ); 4474 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4475 } 4476 else 4477 { 4478 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4479 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4480 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4481 } 4482 } 4483 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() ); 4484 } 4485 } 4486 } 4487 4488 // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine> 4489 // into <lcl_PaintTopLine> 4490 void lcl_PaintTopBottomLine( const sal_Bool _bTop, 4491 const SwFrm& _rFrm, 4492 const SwPageFrm& _rPage, 4493 const SwRect& _rOutRect, 4494 const SwRect& _rRect, 4495 const SwBorderAttrs& _rAttrs, 4496 const SwRectFn& _rRectFn ) 4497 { 4498 const SvxBoxItem& rBox = _rAttrs.GetBox(); 4499 const SvxBorderLine* pTopBottomBorder = 0; 4500 if ( _bTop ) 4501 { 4502 pTopBottomBorder = rBox.GetTop(); 4503 } 4504 else 4505 { 4506 pTopBottomBorder = rBox.GetBottom(); 4507 } 4508 4509 if ( !pTopBottomBorder ) 4510 { 4511 return; 4512 } 4513 4514 SwRect aRect( _rOutRect ); 4515 if ( _bTop ) 4516 { 4517 (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) - 4518 (aRect.*_rRectFn->fnGetHeight)() ); 4519 } 4520 else 4521 { 4522 (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) - 4523 (aRect.*_rRectFn->fnGetHeight)() ); 4524 } 4525 4526 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4527 { 4528 SwRect aPaintRect( aRect ); 4529 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4530 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle 4531 // to the prior top postion with width of one twip. 4532 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 ) 4533 { 4534 if ( _bTop ) 4535 { 4536 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() ); 4537 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() ); 4538 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4539 } 4540 else 4541 { 4542 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4543 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4544 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4545 } 4546 } 4547 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() ); 4548 } 4549 4550 if ( pTopBottomBorder->GetInWidth() ) 4551 { 4552 const long nDist = ::lcl_MinHeightDist( pTopBottomBorder->GetDistance() ); 4553 const long nHeight = ::lcl_AlignHeight( pTopBottomBorder->GetInWidth() ); 4554 if ( _bTop ) 4555 { 4556 (aRect.*_rRectFn->fnAddBottom)( nDist + nHeight ); 4557 (aRect.*_rRectFn->fnSubTop)( nHeight - (aRect.*_rRectFn->fnGetHeight)() ); 4558 } 4559 else 4560 { 4561 (aRect.*_rRectFn->fnSubTop)( nDist + nHeight ); 4562 (aRect.*_rRectFn->fnAddBottom)( nHeight -(aRect.*_rRectFn->fnGetHeight)() ); 4563 } 4564 ::lcl_SubLeftRight( aRect, rBox, _rRectFn ); 4565 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4566 { 4567 SwRect aPaintRect( aRect ); 4568 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4569 // if <SwAlignRect> reveals rectangle with no width, adjust 4570 // rectangle to the prior top postion with width of one twip. 4571 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 ) 4572 { 4573 if ( _bTop ) 4574 { 4575 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() ); 4576 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() ); 4577 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4578 } 4579 else 4580 { 4581 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4582 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4583 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4584 } 4585 } 4586 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() ); 4587 } 4588 } 4589 } 4590 4591 4592 /************************************************************************* 4593 |* 4594 |* const SwFrm* lcl_HasNextCell( const SwFrm& rFrm ) 4595 |* 4596 |* No comment. #i15844# 4597 |* 4598 |*************************************************************************/ 4599 4600 const SwFrm* lcl_HasNextCell( const SwFrm& rFrm ) 4601 { 4602 ASSERT( rFrm.IsCellFrm(), 4603 "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" ) 4604 4605 const SwFrm* pTmpFrm = &rFrm; 4606 do 4607 { 4608 if ( pTmpFrm->GetNext() ) 4609 return pTmpFrm->GetNext(); 4610 4611 pTmpFrm = pTmpFrm->GetUpper()->GetUpper(); 4612 } 4613 while ( pTmpFrm->IsCellFrm() ); 4614 4615 return 0; 4616 } 4617 4618 4619 /************************************************************************* 4620 |* 4621 |* SwFrm::PaintBorder() 4622 |* 4623 |* Beschreibung Malt Schatten und Umrandung 4624 |* Ersterstellung MA 23.01.92 4625 |* Letzte Aenderung MA 29. Jul. 96 4626 |* 4627 |*************************************************************************/ 4628 4629 /** local method to determine cell frame, from which the border attributes 4630 for paint of top/bottom border has to be used. 4631 4632 OD 21.02.2003 #b4779636#, #107692# 4633 4634 @author OD 4635 4636 4637 @param _pCellFrm 4638 input parameter - constant pointer to cell frame for which the cell frame 4639 for the border attributes has to be determined. 4640 4641 @param _rCellBorderAttrs 4642 input parameter - constant reference to the border attributes of cell frame 4643 <_pCellFrm>. 4644 4645 @param _bTop 4646 input parameter - boolean, that controls, if cell frame for top border or 4647 for bottom border has to be determined. 4648 4649 @return constant pointer to cell frame, for which the border attributes has 4650 to be used 4651 */ 4652 const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm* _pCellFrm, 4653 const SwBorderAttrs& _rCellBorderAttrs, 4654 const bool _bTop ) 4655 { 4656 ASSERT( _pCellFrm, "No cell frame available, dying soon" ) 4657 4658 // determine, if cell frame is at bottom/top border of a table frame and 4659 // the table frame has/is a follow. 4660 const SwFrm* pTmpFrm = _pCellFrm; 4661 bool bCellAtBorder = true; 4662 bool bCellAtLeftBorder = !_pCellFrm->GetPrev(); 4663 bool bCellAtRightBorder = !_pCellFrm->GetNext(); 4664 while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() ) 4665 { 4666 pTmpFrm = pTmpFrm->GetUpper(); 4667 if ( pTmpFrm->IsRowFrm() && 4668 (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext()) 4669 ) 4670 { 4671 bCellAtBorder = false; 4672 } 4673 if ( pTmpFrm->IsCellFrm() ) 4674 { 4675 if ( pTmpFrm->GetPrev() ) 4676 { 4677 bCellAtLeftBorder = false; 4678 } 4679 if ( pTmpFrm->GetNext() ) 4680 { 4681 bCellAtRightBorder = false; 4682 } 4683 } 4684 } 4685 ASSERT( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" ); 4686 4687 const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm); 4688 const SwTabFrm* pParentTabFrm = 4689 static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper()); 4690 4691 const bool bCellNeedsAttribute = bCellAtBorder && 4692 ( _bTop ? 4693 // bCellInFirstRowWithMaster 4694 ( !pParentRowFrm->GetPrev() && 4695 pParentTabFrm->IsFollow() && 4696 0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) : 4697 // bCellInLastRowWithFollow 4698 ( !pParentRowFrm->GetNext() && 4699 pParentTabFrm->GetFollow() ) 4700 ); 4701 4702 const SwFrm* pRet = _pCellFrm; 4703 if ( bCellNeedsAttribute ) 4704 { 4705 // determine, if cell frame has no borders inside the table. 4706 const SwFrm* pNextCell = 0; 4707 bool bNoBordersInside = false; 4708 4709 if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) ) 4710 { 4711 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell ); 4712 const SwBorderAttrs &rBorderAttrs = *aAccess.Get(); 4713 const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox(); 4714 bCellAtRightBorder = !lcl_HasNextCell( *pNextCell ); 4715 bNoBordersInside = 4716 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) && 4717 !rBorderBox.GetLeft() && 4718 ( !rBorderBox.GetRight() || bCellAtRightBorder ) && 4719 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() ); 4720 } 4721 else 4722 { 4723 const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox(); 4724 bNoBordersInside = 4725 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) && 4726 ( !rBorderBox.GetLeft() || bCellAtLeftBorder ) && 4727 ( !rBorderBox.GetRight() || bCellAtRightBorder ) && 4728 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() ); 4729 } 4730 4731 if ( bNoBordersInside ) 4732 { 4733 if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() ) 4734 { 4735 // #b4779636#-hack: 4736 // Cell frame has no top border and no border inside the table, but 4737 // it is at the top border of a table frame, which is a follow. 4738 // Thus, use border attributes of cell frame in first row of complete table. 4739 // First, determine first table frame of complete table. 4740 SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true ); 4741 // determine first row of complete table. 4742 const SwFrm* pFirstRow = pMasterTabFrm->GetLower(); 4743 // return first cell in first row 4744 SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower()); 4745 while ( !pLowerCell->IsCellFrm() || 4746 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() ) 4747 ) 4748 { 4749 pLowerCell = pLowerCell->GetLower(); 4750 } 4751 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" ); 4752 pRet = pLowerCell; 4753 } 4754 else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() ) 4755 { 4756 // #b4779636#-hack: 4757 // Cell frame has no bottom border and no border inside the table, 4758 // but it is at the bottom border of a table frame, which has a follow. 4759 // Thus, use border attributes of cell frame in last row of complete table. 4760 // First, determine last table frame of complete table. 4761 SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow()); 4762 while ( pLastTabFrm->GetFollow() ) 4763 { 4764 pLastTabFrm = pLastTabFrm->GetFollow(); 4765 } 4766 // determine last row of complete table. 4767 SwFrm* pLastRow = pLastTabFrm->GetLastLower(); 4768 // return first bottom border cell in last row 4769 SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower()); 4770 while ( !pLowerCell->IsCellFrm() || 4771 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() ) 4772 ) 4773 { 4774 if ( pLowerCell->IsRowFrm() ) 4775 { 4776 while ( pLowerCell->GetNext() ) 4777 { 4778 pLowerCell = pLowerCell->GetNext(); 4779 } 4780 } 4781 pLowerCell = pLowerCell->GetLower(); 4782 } 4783 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" ); 4784 pRet = pLowerCell; 4785 } 4786 } 4787 } 4788 4789 return pRet; 4790 } 4791 4792 void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage, 4793 const SwBorderAttrs &rAttrs ) const 4794 { 4795 //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun 4796 if ( (GetType() & 0x90C5) || (Prt().SSize() == Frm().SSize()) ) 4797 return; 4798 4799 if ( (GetType() & 0x2000) && //Cell 4800 !pGlobalShell->GetViewOptions()->IsTable() ) 4801 return; 4802 4803 // --> collapsing borders FME 2005-05-27 #i29550# 4804 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() ) 4805 { 4806 const SwTabFrm* pTabFrm = FindTabFrm(); 4807 if ( pTabFrm->IsCollapsingBorders() ) 4808 return; 4809 4810 if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) ) 4811 return; 4812 } 4813 // <-- 4814 4815 const bool bLine = rAttrs.IsLine() ? true : false; 4816 const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE; 4817 4818 // OD 24.02.2003 #b4779636#, #107692# - flag to control, 4819 // if #b4779636#-hack has to be used. 4820 const bool bb4779636HackActive = true; 4821 // OD 21.02.2003 #b4779636#, #107692# 4822 const SwFrm* pCellFrmForBottomBorderAttrs = 0; 4823 const SwFrm* pCellFrmForTopBorderAttrs = 0; 4824 bool bFoundCellForTopOrBorderAttrs = false; 4825 if ( bb4779636HackActive && IsCellFrm() ) 4826 { 4827 pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false ); 4828 if ( pCellFrmForBottomBorderAttrs != this ) 4829 bFoundCellForTopOrBorderAttrs = true; 4830 pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true ); 4831 if ( pCellFrmForTopBorderAttrs != this ) 4832 bFoundCellForTopOrBorderAttrs = true; 4833 } 4834 4835 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs> 4836 // for #b4779636#-hack 4837 if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs ) 4838 { 4839 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, 4840 //so braucht kein Rand gepainted werden. 4841 //Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden, 4842 //anderfalls wuerden u.U. Teile nicht verarbeitet. 4843 SwRect aRect( Prt() ); 4844 aRect += Frm().Pos(); 4845 ::SwAlignRect( aRect, pGlobalShell ); 4846 // OD 27.09.2002 #103636# - new local boolean variable in order to 4847 // suspend border paint under special cases - see below. 4848 // NOTE: This is a fix for the implementation of feature #99657#. 4849 bool bDrawOnlyShadowForTransparentFrame = false; 4850 if ( aRect.IsInside( rRect ) ) 4851 { 4852 // OD 27.09.2002 #103636# - paint shadow, if background is transparent. 4853 // Because of introduced transparent background for fly frame #99657#, 4854 // the shadow have to be drawn if the background is transparent, 4855 // in spite the fact that the paint rectangle <rRect> lies fully 4856 // in the printing area. 4857 // NOTE to chosen solution: 4858 // On transparent background, continue processing, but suspend 4859 // drawing of border by setting <bDrawOnlyShadowForTransparentFrame> 4860 // to true. 4861 if ( IsLayoutFrm() && 4862 static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() ) 4863 { 4864 bDrawOnlyShadowForTransparentFrame = true; 4865 } 4866 else 4867 { 4868 return; 4869 } 4870 } 4871 4872 if ( !pPage ) 4873 pPage = FindPageFrm(); 4874 4875 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True ); 4876 rAttrs.SetGetCacheLine( sal_True ); 4877 if ( bShadow ) 4878 PaintShadow( rRect, aRect, rAttrs ); 4879 // OD 27.09.2002 #103636# - suspend drawing of border 4880 // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above 4881 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs> 4882 // for #b4779636#-hack. 4883 if ( ( bLine || bFoundCellForTopOrBorderAttrs ) && 4884 !bDrawOnlyShadowForTransparentFrame ) 4885 { 4886 const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this; 4887 SWRECTFN( pDirRefFrm ) 4888 // OD 19.05.2003 #109667# - use new method <lcl_PaintLeftRightLine(..)> 4889 //::lcl_PaintLeftLine ( this, pPage, aRect, rRect, rAttrs, fnRect ); 4890 //::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs, fnRect ); 4891 ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4892 ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4893 if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) ) 4894 { 4895 // OD 21.02.2003 #b4779636#, #107692# - 4896 // #b4779636#-hack: If another cell frame for top border 4897 // paint is found, paint its top border. 4898 if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this ) 4899 { 4900 SwBorderAttrAccess aAccess( SwFrm::GetCache(), 4901 pCellFrmForTopBorderAttrs ); 4902 const SwBorderAttrs &rTopAttrs = *aAccess.Get(); 4903 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4904 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rTopAttrs, fnRect ); 4905 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect ); 4906 } 4907 else 4908 { 4909 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4910 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs, fnRect ); 4911 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4912 } 4913 } 4914 if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) ) 4915 { 4916 // OD 21.02.2003 #b4779636#, #107692# - 4917 // #b4779636#-hack: If another cell frame for bottom border 4918 // paint is found, paint its bottom border. 4919 if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this ) 4920 { 4921 SwBorderAttrAccess aAccess( SwFrm::GetCache(), 4922 pCellFrmForBottomBorderAttrs ); 4923 const SwBorderAttrs &rBottomAttrs = *aAccess.Get(); 4924 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4925 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rBottomAttrs, fnRect); 4926 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect); 4927 } 4928 else 4929 { 4930 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4931 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rAttrs, fnRect); 4932 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect); 4933 } 4934 } 4935 } 4936 rAttrs.SetGetCacheLine( sal_False ); 4937 } 4938 } 4939 /************************************************************************* 4940 |* 4941 |* SwFtnContFrm::PaintBorder() 4942 |* 4943 |* Beschreibung Spezialimplementierung wg. der Fussnotenlinie. 4944 |* Derzeit braucht nur der obere Rand beruecksichtigt werden. 4945 |* Auf andere Linien und Schatten wird verzichtet. 4946 |* Ersterstellung MA 27. Feb. 93 4947 |* Letzte Aenderung MA 08. Sep. 93 4948 |* 4949 |*************************************************************************/ 4950 4951 void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage, 4952 const SwBorderAttrs & ) const 4953 { 4954 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es 4955 //keinen Rand zu painten. 4956 SwRect aRect( Prt() ); 4957 aRect.Pos() += Frm().Pos(); 4958 if ( !aRect.IsInside( rRect ) ) 4959 PaintLine( rRect, pPage ); 4960 } 4961 /************************************************************************* 4962 |* 4963 |* SwFtnContFrm::PaintLine() 4964 |* 4965 |* Beschreibung Fussnotenline malen. 4966 |* Ersterstellung MA 02. Mar. 93 4967 |* Letzte Aenderung MA 28. Mar. 94 4968 |* 4969 |*************************************************************************/ 4970 4971 void SwFtnContFrm::PaintLine( const SwRect& rRect, 4972 const SwPageFrm *pPage ) const 4973 { 4974 //Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc. 4975 //Die Position ist ebenfalls am PageDesc angegeben. 4976 //Der Pen steht direkt im PageDesc. 4977 4978 if ( !pPage ) 4979 pPage = FindPageFrm(); 4980 const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo(); 4981 4982 SWRECTFN( this ) 4983 SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)(); 4984 Fraction aFract( nPrtWidth, 1 ); 4985 const SwTwips nWidth = (long)(aFract *= rInf.GetWidth()); 4986 4987 SwTwips nX = (this->*fnRect->fnGetPrtLeft)(); 4988 switch ( rInf.GetAdj() ) 4989 { 4990 case FTNADJ_CENTER: 4991 nX += nPrtWidth/2 - nWidth/2; break; 4992 case FTNADJ_RIGHT: 4993 nX += nPrtWidth - nWidth; break; 4994 case FTNADJ_LEFT: 4995 /* do nothing */; break; 4996 default: 4997 ASSERT( !this, "Neues Adjustment fuer Fussnotenlinie?" ); 4998 } 4999 SwTwips nLineWidth = rInf.GetLineWidth(); 5000 const SwRect aLineRect = bVert ? 5001 SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth, 5002 nX), Size( nLineWidth, nWidth ) ) 5003 : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ), 5004 Size( nWidth, rInf.GetLineWidth())); 5005 if ( aLineRect.HasArea() ) 5006 PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() ); 5007 } 5008 5009 /************************************************************************* 5010 |* 5011 |* SwLayoutFrm::PaintColLines() 5012 |* 5013 |* Beschreibung Painted die Trennlinien fuer die innenliegenden 5014 |* Spalten. 5015 |* Ersterstellung MA 21. Jun. 93 5016 |* Letzte Aenderung MA 28. Mar. 94 5017 |* 5018 |*************************************************************************/ 5019 5020 void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol, 5021 const SwPageFrm *pPage ) const 5022 { 5023 const SwFrm *pCol = Lower(); 5024 if ( !pCol || !pCol->IsColumnFrm() ) 5025 return; 5026 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 5027 SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 5028 5029 SwRect aLineRect = Prt(); 5030 aLineRect += Frm().Pos(); 5031 5032 SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight()) 5033 / 100 - (aLineRect.*fnRect->fnGetHeight)(); 5034 SwTwips nBottom = 0; 5035 5036 switch ( rFmtCol.GetLineAdj() ) 5037 { 5038 case COLADJ_CENTER: 5039 nBottom = nTop / 2; nTop -= nBottom; break; 5040 case COLADJ_TOP: 5041 nBottom = nTop; nTop = 0; break; 5042 case COLADJ_BOTTOM: 5043 break; 5044 default: 5045 ASSERT( !this, "Neues Adjustment fuer Spaltenlinie?" ); 5046 } 5047 5048 if( nTop ) 5049 (aLineRect.*fnRect->fnSubTop)( nTop ); 5050 if( nBottom ) 5051 (aLineRect.*fnRect->fnAddBottom)( nBottom ); 5052 5053 SwTwips nPenHalf = rFmtCol.GetLineWidth(); 5054 (aLineRect.*fnRect->fnSetWidth)( nPenHalf ); 5055 nPenHalf /= 2; 5056 5057 //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein. 5058 SwRect aRect( rRect ); 5059 (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW ); 5060 (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW ); 5061 SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight; 5062 while ( pCol->GetNext() ) 5063 { 5064 (aLineRect.*fnRect->fnSetPosX) 5065 ( (pCol->Frm().*fnGetX)() - nPenHalf ); 5066 if ( aRect.IsOver( aLineRect ) ) 5067 PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor()); 5068 pCol = pCol->GetNext(); 5069 } 5070 } 5071 5072 void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const 5073 { 5074 if( !bHasGrid || pRetoucheFly || pRetoucheFly2 ) 5075 return; 5076 GETGRID( this ) 5077 if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ? 5078 pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) ) 5079 { 5080 const SwLayoutFrm* pBody = FindBodyCont(); 5081 if( pBody ) 5082 { 5083 SwRect aGrid( pBody->Prt() ); 5084 aGrid += pBody->Frm().Pos(); 5085 5086 SwRect aInter( aGrid ); 5087 aInter.Intersection( rRect ); 5088 if( aInter.HasArea() ) 5089 { 5090 sal_Bool bGrid = pGrid->GetRubyTextBelow(); 5091 sal_Bool bCell = GRID_LINES_CHARS == pGrid->GetGridType(); 5092 long nGrid = pGrid->GetBaseHeight(); 5093 const SwDoc* pDoc = GetFmt()->GetDoc(); 5094 long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor 5095 long nRuby = pGrid->GetRubyHeight(); 5096 long nSum = nGrid + nRuby; 5097 const Color *pCol = &pGrid->GetColor(); 5098 5099 SwTwips nRight = aInter.Left() + aInter.Width(); 5100 SwTwips nBottom = aInter.Top() + aInter.Height(); 5101 if( IsVertical() ) 5102 { 5103 SwTwips nOrig = aGrid.Left() + aGrid.Width(); 5104 SwTwips nY = nOrig + nSum * 5105 ( ( nOrig - aInter.Left() ) / nSum ); 5106 SwRect aTmp( Point( nY, aInter.Top() ), 5107 Size( 1, aInter.Height() ) ); 5108 SwTwips nX = aGrid.Top() + nGrid * 5109 ( ( aInter.Top() - aGrid.Top() )/ nGrid ); 5110 if( nX < aInter.Top() ) 5111 nX += nGrid; 5112 SwTwips nGridBottom = aGrid.Top() + aGrid.Height(); 5113 sal_Bool bLeft = aGrid.Top() >= aInter.Top(); 5114 sal_Bool bRight = nGridBottom <= nBottom; 5115 sal_Bool bBorder = bLeft || bRight; 5116 while( nY > nRight ) 5117 { 5118 aTmp.Pos().X() = nY; 5119 if( bGrid ) 5120 { 5121 nY -= nGrid; 5122 SwTwips nPosY = Max( aInter.Left(), nY ); 5123 SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY; 5124 if( nHeight > 0 ) 5125 { 5126 if( bCell ) 5127 { 5128 SwRect aVert( Point( nPosY, nX ), 5129 Size( nHeight, 1 ) ); 5130 while( aVert.Top() <= nBottom ) 5131 { 5132 PaintBorderLine(rRect,aVert,this,pCol); 5133 aVert.Pos().Y() += nGrid; 5134 } 5135 } 5136 else if( bBorder ) 5137 { 5138 SwRect aVert( Point( nPosY, aGrid.Top() ), 5139 Size( nHeight, 1 ) ); 5140 if( bLeft ) 5141 PaintBorderLine(rRect,aVert,this,pCol); 5142 if( bRight ) 5143 { 5144 aVert.Pos().Y() = nGridBottom; 5145 PaintBorderLine(rRect,aVert,this,pCol); 5146 } 5147 } 5148 } 5149 } 5150 else 5151 { 5152 nY -= nRuby; 5153 if( bBorder ) 5154 { 5155 SwTwips nPos = Max( aInter.Left(), nY ); 5156 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos; 5157 SwRect aVert( Point( nPos, aGrid.Top() ), 5158 Size( nW, 1 ) ); 5159 if( nW > 0 ) 5160 { 5161 if( bLeft ) 5162 PaintBorderLine(rRect,aVert,this,pCol); 5163 if( bRight ) 5164 { 5165 aVert.Pos().Y() = nGridBottom; 5166 PaintBorderLine(rRect,aVert,this,pCol); 5167 } 5168 } 5169 } 5170 } 5171 bGrid = !bGrid; 5172 } 5173 while( nY >= aInter.Left() ) 5174 { 5175 aTmp.Pos().X() = nY; 5176 PaintBorderLine( rRect, aTmp, this, pCol); 5177 if( bGrid ) 5178 { 5179 nY -= nGrid; 5180 SwTwips nHeight = aTmp.Pos().X() 5181 - Max(aInter.Left(), nY ); 5182 if( nHeight > 0 ) 5183 { 5184 if( bCell ) 5185 { 5186 SwRect aVert( Point(aTmp.Pos().X()-nHeight, 5187 nX ), Size( nHeight, 1 ) ); 5188 while( aVert.Top() <= nBottom ) 5189 { 5190 PaintBorderLine(rRect,aVert,this,pCol); 5191 aVert.Pos().Y() += nGrid; 5192 } 5193 } 5194 else if( bBorder ) 5195 { 5196 SwRect aVert( Point(aTmp.Pos().X()-nHeight, 5197 aGrid.Top() ), Size( nHeight, 1 ) ); 5198 if( bLeft ) 5199 PaintBorderLine(rRect,aVert,this,pCol); 5200 if( bRight ) 5201 { 5202 aVert.Pos().Y() = nGridBottom; 5203 PaintBorderLine(rRect,aVert,this,pCol); 5204 } 5205 } 5206 } 5207 } 5208 else 5209 { 5210 nY -= nRuby; 5211 if( bBorder ) 5212 { 5213 SwTwips nPos = Max( aInter.Left(), nY ); 5214 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos; 5215 SwRect aVert( Point( nPos, aGrid.Top() ), 5216 Size( nW, 1 ) ); 5217 if( nW > 0 ) 5218 { 5219 if( bLeft ) 5220 PaintBorderLine(rRect,aVert,this,pCol); 5221 if( bRight ) 5222 { 5223 aVert.Pos().Y() = nGridBottom; 5224 PaintBorderLine(rRect,aVert,this,pCol); 5225 } 5226 } 5227 } 5228 } 5229 bGrid = !bGrid; 5230 } 5231 } 5232 else 5233 { 5234 SwTwips nOrig = aGrid.Top(); 5235 SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum ); 5236 SwRect aTmp( Point( aInter.Left(), nY ), 5237 Size( aInter.Width(), 1 ) ); 5238 //for textgrid refactor 5239 SwTwips nX = aGrid.Left() + nGridWidth * 5240 ( ( aInter.Left() - aGrid.Left() )/ nGridWidth ); 5241 if( nX < aInter.Left() ) 5242 nX += nGridWidth; 5243 SwTwips nGridRight = aGrid.Left() + aGrid.Width(); 5244 sal_Bool bLeft = aGrid.Left() >= aInter.Left(); 5245 sal_Bool bRight = nGridRight <= nRight; 5246 sal_Bool bBorder = bLeft || bRight; 5247 while( nY < aInter.Top() ) 5248 { 5249 aTmp.Pos().Y() = nY; 5250 if( bGrid ) 5251 { 5252 nY += nGrid; 5253 SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() ); 5254 SwTwips nHeight = Min(nBottom, nY ) - nPosY; 5255 if( nHeight ) 5256 { 5257 if( bCell ) 5258 { 5259 SwRect aVert( Point( nX, nPosY ), 5260 Size( 1, nHeight ) ); 5261 while( aVert.Left() <= nRight ) 5262 { 5263 PaintBorderLine(rRect,aVert,this,pCol); 5264 aVert.Pos().X() += nGridWidth; //for textgrid refactor 5265 } 5266 } 5267 else if ( bBorder ) 5268 { 5269 SwRect aVert( Point( aGrid.Left(), nPosY ), 5270 Size( 1, nHeight ) ); 5271 if( bLeft ) 5272 PaintBorderLine(rRect,aVert,this,pCol); 5273 if( bRight ) 5274 { 5275 aVert.Pos().X() = nGridRight; 5276 PaintBorderLine(rRect,aVert,this,pCol); 5277 } 5278 } 5279 } 5280 } 5281 else 5282 { 5283 nY += nRuby; 5284 if( bBorder ) 5285 { 5286 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y()); 5287 SwTwips nH = Min( nBottom, nY ) - nPos; 5288 SwRect aVert( Point( aGrid.Left(), nPos ), 5289 Size( 1, nH ) ); 5290 if( nH > 0 ) 5291 { 5292 if( bLeft ) 5293 PaintBorderLine(rRect,aVert,this,pCol); 5294 if( bRight ) 5295 { 5296 aVert.Pos().X() = nGridRight; 5297 PaintBorderLine(rRect,aVert,this,pCol); 5298 } 5299 } 5300 } 5301 } 5302 bGrid = !bGrid; 5303 } 5304 while( nY <= nBottom ) 5305 { 5306 aTmp.Pos().Y() = nY; 5307 PaintBorderLine( rRect, aTmp, this, pCol); 5308 if( bGrid ) 5309 { 5310 nY += nGrid; 5311 SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y(); 5312 if( nHeight ) 5313 { 5314 if( bCell ) 5315 { 5316 SwRect aVert( Point( nX, aTmp.Pos().Y() ), 5317 Size( 1, nHeight ) ); 5318 while( aVert.Left() <= nRight ) 5319 { 5320 PaintBorderLine( rRect, aVert, this, pCol); 5321 aVert.Pos().X() += nGridWidth; //for textgrid refactor 5322 } 5323 } 5324 else if( bBorder ) 5325 { 5326 SwRect aVert( Point( aGrid.Left(), 5327 aTmp.Pos().Y() ), Size( 1, nHeight ) ); 5328 if( bLeft ) 5329 PaintBorderLine(rRect,aVert,this,pCol); 5330 if( bRight ) 5331 { 5332 aVert.Pos().X() = nGridRight; 5333 PaintBorderLine(rRect,aVert,this,pCol); 5334 } 5335 } 5336 } 5337 } 5338 else 5339 { 5340 nY += nRuby; 5341 if( bBorder ) 5342 { 5343 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y()); 5344 SwTwips nH = Min( nBottom, nY ) - nPos; 5345 SwRect aVert( Point( aGrid.Left(), nPos ), 5346 Size( 1, nH ) ); 5347 if( nH > 0 ) 5348 { 5349 if( bLeft ) 5350 PaintBorderLine(rRect,aVert,this,pCol); 5351 if( bRight ) 5352 { 5353 aVert.Pos().X() = nGridRight; 5354 PaintBorderLine(rRect,aVert,this,pCol); 5355 } 5356 } 5357 } 5358 } 5359 bGrid = !bGrid; 5360 } 5361 } 5362 } 5363 } 5364 } 5365 } 5366 5367 /** paint margin area of a page 5368 5369 OD 20.11.2002 for #104598#: 5370 implement paint of margin area; margin area will be painted for a 5371 view shell with a window and if the document is not in online layout. 5372 5373 @author OD 5374 5375 @param _rOutputRect 5376 input parameter - constant instance reference of the rectangle, for 5377 which an output has to be generated. 5378 5379 @param _pViewShell 5380 input parameter - instance of the view shell, on which the output 5381 has to be generated. 5382 */ 5383 void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect, 5384 ViewShell* _pViewShell ) const 5385 { 5386 if ( _pViewShell->GetWin() && 5387 !_pViewShell->GetViewOptions()->getBrowseMode() ) 5388 { 5389 SwRect aPgPrtRect( Prt() ); 5390 aPgPrtRect.Pos() += Frm().Pos(); 5391 if ( !aPgPrtRect.IsInside( _rOutputRect ) ) 5392 { 5393 SwRect aPgRect = Frm(); 5394 aPgRect._Intersection( _rOutputRect ); 5395 SwRegionRects aPgRegion( aPgRect ); 5396 aPgRegion -= aPgPrtRect; 5397 const SwPageFrm* pPage = static_cast<const SwPageFrm*>(this); 5398 //if ( pPage->GetSortedObjs() ) 5399 // ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion ); 5400 if ( aPgRegion.Count() ) 5401 { 5402 OutputDevice *pOut = _pViewShell->GetOut(); 5403 if ( pOut->GetFillColor() != aGlobalRetoucheColor ) 5404 pOut->SetFillColor( aGlobalRetoucheColor ); 5405 for ( sal_uInt16 i = 0; i < aPgRegion.Count(); ++i ) 5406 { 5407 if ( 1 < aPgRegion.Count() ) 5408 { 5409 ::SwAlignRect( aPgRegion[i], pGlobalShell ); 5410 if( !aPgRegion[i].HasArea() ) 5411 continue; 5412 } 5413 pOut->DrawRect(aPgRegion[i].SVRect()); 5414 } 5415 } 5416 } 5417 } 5418 } 5419 5420 // ---------------------------------------------------------------------- 5421 // 5422 // const SwPageFrm::mnBorderPxWidth, const SwPageFrm::mnShadowPxWidth 5423 // SwPageFrm::GetBorderRect (..), SwPageFrm::GetRightShadowRect(..), 5424 // SwPageFrm::GetBottomShadowRect(..), 5425 // SwPageFrm::PaintBorderAndShadow(..), 5426 // SwPageFrm::GetBorderAndShadowBoundRect(..) 5427 // 5428 // OD 12.02.2003 for #i9719# and #105645# 5429 // ---------------------------------------------------------------------- 5430 5431 const sal_Int8 SwPageFrm::mnBorderPxWidth = 1; 5432 const sal_Int8 SwPageFrm::mnShadowPxWidth = 2; 5433 5434 /** determine rectangle for page border 5435 5436 OD 12.02.2003 for #i9719# and #105645# 5437 5438 @author OD 5439 */ 5440 /*static*/ void SwPageFrm::GetBorderRect( const SwRect& _rPageRect, 5441 ViewShell* _pViewShell, 5442 SwRect& _orBorderRect, 5443 bool bRightSidebar ) 5444 { 5445 SwRect aAlignedPageRect( _rPageRect ); 5446 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5447 Rectangle aBorderPxRect = 5448 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5449 5450 aBorderPxRect.Left() = aBorderPxRect.Left() - mnBorderPxWidth; 5451 aBorderPxRect.Top() = aBorderPxRect.Top() - mnBorderPxWidth; 5452 aBorderPxRect.Right() = aBorderPxRect.Right() + mnBorderPxWidth; 5453 aBorderPxRect.Bottom() = aBorderPxRect.Bottom() + mnBorderPxWidth; 5454 5455 AddSidebarBorders(aBorderPxRect,_pViewShell, bRightSidebar, true); 5456 5457 _orBorderRect = 5458 SwRect( _pViewShell->GetOut()->PixelToLogic( aBorderPxRect ) ); 5459 } 5460 5461 /** determine rectangle for right page shadow 5462 5463 OD 12.02.2003 for #i9719# and #105645# 5464 5465 @author OD 5466 */ 5467 /*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect, 5468 ViewShell* _pViewShell, 5469 SwRect& _orRightShadowRect, 5470 bool bRightSidebar ) 5471 { 5472 SwRect aAlignedPageRect( _rPageRect ); 5473 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5474 Rectangle aPagePxRect = 5475 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5476 5477 Rectangle aRightShadowPxRect( 5478 aPagePxRect.Right() + mnShadowPxWidth, 5479 aPagePxRect.Top() + 1, 5480 aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth, 5481 aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth ); 5482 5483 if ( bRightSidebar ) 5484 AddSidebarBorders(aRightShadowPxRect,_pViewShell, bRightSidebar, true); 5485 5486 _orRightShadowRect = 5487 SwRect( _pViewShell->GetOut()->PixelToLogic( aRightShadowPxRect ) ); 5488 } 5489 5490 /** determine rectangle for bottom page shadow 5491 5492 OD 12.02.2003 for #i9719# and #105645# 5493 5494 @author OD 5495 */ 5496 /*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect, 5497 ViewShell* _pViewShell, 5498 SwRect& _orBottomShadowRect, 5499 bool bRightSidebar ) 5500 { 5501 SwRect aAlignedPageRect( _rPageRect ); 5502 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5503 Rectangle aPagePxRect = 5504 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5505 5506 Rectangle aBottomShadowPxRect( 5507 aPagePxRect.Left() + 1, 5508 aPagePxRect.Bottom() + mnShadowPxWidth, 5509 aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth, 5510 aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth ); 5511 5512 AddSidebarBorders(aBottomShadowPxRect,_pViewShell, bRightSidebar, true); 5513 5514 _orBottomShadowRect = 5515 SwRect( _pViewShell->GetOut()->PixelToLogic( aBottomShadowPxRect ) ); 5516 } 5517 5518 /** paint page border and shadow 5519 5520 OD 12.02.2003 for #i9719# and #105645# 5521 implement paint of page border and shadow 5522 5523 @author OD 5524 */ 5525 /*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect, 5526 ViewShell* _pViewShell, 5527 bool bPaintRightShadow, 5528 bool bRightSidebar ) 5529 { 5530 // --> FME 2004-06-24 #i16816# tagged pdf support 5531 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() ); 5532 // <-- 5533 5534 // get color for page border and shadow paint 5535 const Color& rColor = SwViewOption::GetFontColor(); 5536 5537 // save current fill and line color of output device 5538 Color aFill( _pViewShell->GetOut()->GetFillColor() ); 5539 Color aLine( _pViewShell->GetOut()->GetLineColor() ); 5540 5541 // paint page border 5542 _pViewShell->GetOut()->SetFillColor(); // OD 20.02.2003 #107369# - no fill color 5543 _pViewShell->GetOut()->SetLineColor( rColor ); 5544 SwRect aPaintRect; 5545 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar ); 5546 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() ); 5547 5548 // paint right shadow 5549 if ( bPaintRightShadow ) 5550 { 5551 _pViewShell->GetOut()->SetFillColor( rColor ); 5552 SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar ); 5553 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() ); 5554 } 5555 5556 // paint bottom shadow 5557 SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar ); 5558 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() ); 5559 5560 _pViewShell->GetOut()->SetFillColor( aFill ); 5561 _pViewShell->GetOut()->SetLineColor( aLine ); 5562 } 5563 5564 //mod #i6193# paint sidebar for notes 5565 //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit 5566 /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight) 5567 { 5568 //TOOD: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons 5569 if (!_pViewShell ) 5570 return; 5571 5572 SwRect aPageRect( _rPageRect ); 5573 SwAlignRect( aPageRect, _pViewShell ); 5574 5575 const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr(); 5576 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) // do not show anything in print preview 5577 { 5578 sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight(); 5579 const Rectangle &aVisRect = _pViewShell->VisArea().SVRect(); 5580 //draw border and sidepane 5581 _pViewShell->GetOut()->SetLineColor(); 5582 if (!bRight) 5583 { 5584 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER); 5585 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()))) ; 5586 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5587 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5588 else 5589 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE); 5590 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()))) ; 5591 } 5592 else 5593 { 5594 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER); 5595 SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height())); 5596 _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect()); 5597 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5598 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5599 else 5600 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE); 5601 SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height())); 5602 _pViewShell->GetOut()->DrawRect(aSidebar.SVRect()); 5603 } 5604 if (pMgr->ShowScrollbar(nPageNum)) 5605 { 5606 // draw scrollbar area and arrows 5607 Point aPointBottom; 5608 Point aPointTop; 5609 aPointBottom = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() - pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height()) : 5610 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height()); 5611 aPointTop = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) : 5612 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()); 5613 Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ; 5614 Rectangle aRectBottom(aPointBottom,aSize); 5615 Rectangle aRectTop(aPointTop,aSize); 5616 5617 if (aRectBottom.IsOver(aVisRect)) 5618 { 5619 5620 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5621 { 5622 _pViewShell->GetOut()->SetLineColor(COL_WHITE); 5623 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5624 } 5625 else 5626 { 5627 _pViewShell->GetOut()->SetLineColor(COL_BLACK); 5628 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA); 5629 } 5630 _pViewShell->GetOut()->DrawRect(aRectBottom); 5631 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height())); 5632 5633 _pViewShell->GetOut()->SetLineColor(); 5634 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5635 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5636 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum)); 5637 } 5638 if (aRectTop.IsOver(aVisRect)) 5639 { 5640 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5641 { 5642 _pViewShell->GetOut()->SetLineColor(COL_WHITE); 5643 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5644 } 5645 else 5646 { 5647 _pViewShell->GetOut()->SetLineColor(COL_BLACK); 5648 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA); 5649 } 5650 _pViewShell->GetOut()->DrawRect(aRectTop); 5651 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height())); 5652 5653 _pViewShell->GetOut()->SetLineColor(); 5654 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5655 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5656 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum)); 5657 } 5658 } 5659 } 5660 } 5661 5662 /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown) 5663 { 5664 Polygon aTriangleUp(3); 5665 Polygon aTriangleDown(3); 5666 5667 aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0); 5668 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1); 5669 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2); 5670 5671 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0); 5672 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1); 5673 aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2); 5674 5675 _pViewShell->GetOut()->SetFillColor(aColorUp); 5676 _pViewShell->GetOut()->DrawPolygon(aTriangleUp); 5677 _pViewShell->GetOut()->SetFillColor(aColorDown); 5678 _pViewShell->GetOut()->DrawPolygon(aTriangleDown); 5679 } 5680 5681 /** get bound rectangle of border and shadow for repaints 5682 5683 OD 12.02.2003 for #i9719# and #105645# 5684 5685 author OD 5686 */ 5687 /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect, 5688 ViewShell* _pViewShell, 5689 SwRect& _orBorderAndShadowBoundRect, 5690 bool bRightSidebar ) 5691 { 5692 SwRect aTmpRect; 5693 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, _orBorderAndShadowBoundRect, bRightSidebar ); 5694 SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar ); 5695 _orBorderAndShadowBoundRect.Union( aTmpRect ); 5696 SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar ); 5697 _orBorderAndShadowBoundRect.Union( aTmpRect ); 5698 5699 AddSidebarBorders(_orBorderAndShadowBoundRect, _pViewShell, bRightSidebar, false); 5700 } 5701 5702 /*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx) 5703 { 5704 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5705 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) 5706 { 5707 if (!bRightSidebar) 5708 aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5709 else 5710 aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5711 } 5712 } 5713 5714 /*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx) 5715 { 5716 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5717 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) 5718 { 5719 if (!bRightSidebar) 5720 aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5721 else 5722 aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx); 5723 } 5724 } 5725 5726 /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell ) 5727 { 5728 const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5729 const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0; 5730 return nRet; 5731 } 5732 5733 /************************************************************************* 5734 |* 5735 |* SwFrm::PaintBaBo() 5736 |* 5737 |* Ersterstellung MA 22. Oct. 93 5738 |* Letzte Aenderung MA 19. Jun. 96 5739 |* 5740 |*************************************************************************/ 5741 5742 void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage, 5743 const sal_Bool bLowerBorder ) const 5744 { 5745 if ( !pPage ) 5746 pPage = FindPageFrm(); 5747 5748 OutputDevice *pOut = pGlobalShell->GetOut(); 5749 5750 // --> FME 2004-06-24 #i16816# tagged pdf support 5751 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut ); 5752 // <-- 5753 5754 // OD 2004-04-23 #116347# 5755 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 5756 pOut->SetLineColor(); 5757 5758 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 5759 const SwBorderAttrs &rAttrs = *aAccess.Get(); 5760 5761 // OD 20.11.2002 #104598# - take care of page margin area 5762 // Note: code move from <SwFrm::PaintBackground(..)> to new method 5763 // <SwPageFrm::Paintmargin(..)>. 5764 if ( IsPageFrm() ) 5765 { 5766 static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell ); 5767 } 5768 5769 // OD 06.08.2002 #99657# - paint border before painting background 5770 // paint grid for page frame and paint border 5771 { 5772 SwRect aRect( rRect ); 5773 if( IsPageFrm() ) 5774 ((SwPageFrm*)this)->PaintGrid( pOut, aRect ); 5775 PaintBorder( aRect, pPage, rAttrs ); 5776 } 5777 5778 // paint background 5779 { 5780 PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder ); 5781 } 5782 5783 pOut->Pop(); 5784 } 5785 5786 /************************************************************************* 5787 |* 5788 |* SwFrm::PaintBackground() 5789 |* 5790 |* Ersterstellung MA 04. Jan. 93 5791 |* Letzte Aenderung MA 06. Feb. 97 5792 |* 5793 |*************************************************************************/ 5794 /// OD 05.09.2002 #102912# 5795 /// Do not paint background for fly frames without a background brush by 5796 /// calling <PaintBaBo> at the page or at the fly frame its anchored 5797 void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage, 5798 const SwBorderAttrs & rAttrs, 5799 const sal_Bool bLowerMode, 5800 const sal_Bool bLowerBorder ) const 5801 { 5802 // OD 20.01.2003 #i1837# - no paint of table background, if corresponding 5803 // option is *not* set. 5804 if( IsTabFrm() && 5805 !pGlobalShell->GetViewOptions()->IsTable() ) 5806 { 5807 return; 5808 } 5809 5810 // nothing to do for covered table cells: 5811 if( IsCellFrm() && IsCoveredCell() ) 5812 return; 5813 5814 ViewShell *pSh = pGlobalShell; 5815 5816 // --> FME 2004-06-24 #i16816# tagged pdf support 5817 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); 5818 // <-- 5819 5820 const SvxBrushItem* pItem; 5821 /// OD 05.09.2002 #102912# 5822 /// temporary background brush for a fly frame without a background brush 5823 SvxBrushItem* pTmpBackBrush = 0; 5824 const Color* pCol; 5825 SwRect aOrigBackRect; 5826 const sal_Bool bPageFrm = IsPageFrm(); 5827 sal_Bool bLowMode = sal_True; 5828 5829 //UUUU 5830 FillAttributesPtr aFillAttributes; 5831 5832 sal_Bool bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, bLowerMode ); 5833 5834 //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird. 5835 bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm(); 5836 if ( bNoFlyBackground ) 5837 { 5838 // OD 05.09.2002 #102912# - Fly frame has no background. 5839 // Try to find background brush at parents, if previous call of 5840 // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode> 5841 if ( bLowerMode ) 5842 { 5843 bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, false ); 5844 } 5845 // If still no background found for the fly frame, initialize the 5846 // background brush <pItem> with global retouche color and set <bBack> 5847 // to sal_True, that fly frame will paint its background using this color. 5848 if ( !bBack ) 5849 { 5850 // OD 10.01.2003 #i6467# - on print output, pdf output and 5851 // in embedded mode not editing color COL_WHITE is used instead of 5852 // the global retouche color. 5853 if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER || 5854 pSh->GetViewOptions()->IsPDFExport() || 5855 ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && 5856 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() 5857 ) 5858 ) 5859 { 5860 pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND ); 5861 5862 //UUU 5863 aFillAttributes.reset(new FillAttributes(Color( COL_WHITE ))); 5864 } 5865 else 5866 { 5867 pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND); 5868 5869 //UUU 5870 aFillAttributes.reset(new FillAttributes(aGlobalRetoucheColor)); 5871 } 5872 5873 pItem = pTmpBackBrush; 5874 bBack = true; 5875 } 5876 } 5877 5878 SwRect aPaintRect( Frm() ); 5879 if( IsTxtFrm() || IsSctFrm() ) 5880 aPaintRect = UnionFrm( sal_True ); 5881 5882 if ( aPaintRect.IsOver( rRect ) ) 5883 { 5884 if ( bBack || bPageFrm || !bLowerMode ) 5885 { 5886 const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode(); 5887 SwRect aRect; 5888 if ( (bPageFrm && bBrowse) || 5889 (IsTxtFrm() && Prt().SSize() == Frm().SSize()) ) 5890 { 5891 aRect = Frm(); 5892 ::SwAlignRect( aRect, pGlobalShell ); 5893 } 5894 else 5895 { 5896 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_False ); 5897 if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() ) 5898 { 5899 if ( GetPrev()->GetAttrSet()->GetBackground() == 5900 GetAttrSet()->GetBackground() ) 5901 { 5902 aRect.Top( Frm().Top() ); 5903 } 5904 } 5905 } 5906 aRect.Intersection( rRect ); 5907 5908 OutputDevice *pOut = pSh->GetOut(); 5909 5910 if ( aRect.HasArea() ) 5911 { 5912 SvxBrushItem* pNewItem = 0; 5913 //SwRegionRects aRegion( aRect ); 5914 5915 if( pCol ) 5916 { 5917 pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND ); 5918 pItem = pNewItem; 5919 5920 //UUUU 5921 aFillAttributes.reset(new FillAttributes(*pCol)); 5922 } 5923 5924 //if ( pPage->GetSortedObjs() ) 5925 //{ 5926 // ::lcl_SubtractFlys( this, pPage, aRect, aRegion ); 5927 //} 5928 5929 { 5930 /// OD 06.08.2002 #99657# - determine, if background transparency 5931 /// have to be considered for drawing. 5932 /// --> Status Quo: background transparency have to be 5933 /// considered for fly frames 5934 const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm(); 5935 bool bDone(false); 5936 5937 if(pOut && aFillAttributes.get() && aFillAttributes->isUsed()) 5938 { 5939 bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRect, *pOut); 5940 } 5941 5942 if(!bDone) 5943 { 5944 //for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 5945 //{ 5946 // if ( 1 < aRegion.Count() ) 5947 // { 5948 // ::SwAlignRect( aRegion[i], pGlobalShell ); 5949 // if( !aRegion[i].HasArea() ) 5950 // continue; 5951 // } 5952 /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if 5953 /// background transparency have to be considered 5954 /// Set missing 5th parameter to the default value GRFNUM_NO 5955 /// - see declaration in /core/inc/frmtool.hxx. 5956 ::DrawGraphic( 5957 pItem, 5958 pOut, 5959 aOrigBackRect, 5960 aRect, // aRegion[i], 5961 GRFNUM_NO, 5962 bConsiderBackgroundTransparency ); 5963 //} 5964 } 5965 } 5966 if( pCol ) 5967 delete pNewItem; 5968 } 5969 } 5970 else 5971 bLowMode = bLowerMode ? sal_True : sal_False; 5972 } 5973 5974 /// OD 05.09.2002 #102912# 5975 /// delete temporary background brush. 5976 delete pTmpBackBrush; 5977 5978 //Jetzt noch Lower und dessen Nachbarn. 5979 //Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist 5980 //so hoert der Spass auf. 5981 const SwFrm *pFrm = GetLower(); 5982 if ( pFrm ) 5983 { 5984 SwRect aFrmRect; 5985 SwRect aRect( PaintArea() ); 5986 aRect._Intersection( rRect ); 5987 SwRect aBorderRect( aRect ); 5988 SwShortCut aShortCut( *pFrm, aBorderRect ); 5989 do 5990 { if ( pProgress ) 5991 pProgress->Reschedule(); 5992 5993 aFrmRect = pFrm->PaintArea(); 5994 if ( aFrmRect.IsOver( aBorderRect ) ) 5995 { 5996 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm ); 5997 const SwBorderAttrs &rTmpAttrs = *aAccess.Get(); 5998 /// OD 06.08.2002 #99657# - paint border before painting background 5999 if ( bLowerBorder ) 6000 pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs ); 6001 if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) || 6002 aFrmRect.IsOver( aRect ) ) 6003 pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode, 6004 bLowerBorder ); 6005 } 6006 pFrm = pFrm->GetNext(); 6007 } while ( pFrm && pFrm->GetUpper() == this && 6008 !aShortCut.Stop( aFrmRect ) ); 6009 } 6010 } 6011 6012 /************************************************************************* 6013 |* 6014 |* SwPageFrm::RefreshSubsidiary() 6015 |* 6016 |* Beschreibung Erneuert alle Hilfslinien der Seite. 6017 |* Ersterstellung MA 04. Nov. 92 6018 |* Letzte Aenderung MA 10. May. 95 6019 |* 6020 |*************************************************************************/ 6021 6022 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const 6023 { 6024 if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS ) 6025 { 6026 SwRect aRect( rRect ); 6027 // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of 6028 // the output rectangle. 6029 //::SwAlignRect( aRect, pGlobalShell ); 6030 if ( aRect.HasArea() ) 6031 { 6032 //Beim Paint ueber die Root wird das Array von dort gesteuert. 6033 //Anderfalls kuemmern wir uns selbst darum. 6034 sal_Bool bDelSubs = sal_False; 6035 if ( !pSubsLines ) 6036 { 6037 pSubsLines = new SwSubsRects; 6038 // OD 20.12.2002 #106318# - create container for special subsidiary lines 6039 pSpecSubsLines = new SwSubsRects; 6040 bDelSubs = sal_True; 6041 } 6042 6043 RefreshLaySubsidiary( this, aRect ); 6044 6045 if ( bDelSubs ) 6046 { 6047 // OD 20.12.2002 #106318# - paint special subsidiary lines 6048 // and delete its container 6049 pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL ); 6050 DELETEZ( pSpecSubsLines ); 6051 6052 pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines ); 6053 DELETEZ( pSubsLines ); 6054 } 6055 } 6056 } 6057 } 6058 6059 /************************************************************************* 6060 |* 6061 |* SwLayoutFrm::RefreshLaySubsidiary() 6062 |* 6063 |* Ersterstellung MA 04. Nov. 92 6064 |* Letzte Aenderung MA 22. Jan. 95 6065 |* 6066 |*************************************************************************/ 6067 void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage, 6068 const SwRect &rRect ) const 6069 { 6070 const sal_Bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm(); 6071 const sal_Bool bSubsOpt = IS_SUBS; 6072 const sal_Bool bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE); 6073 const sal_Bool bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt; 6074 const sal_Bool bSubsSect = IsSctFrm() && 6075 bNoLowerColumn && 6076 IS_SUBS_SECTION; 6077 const sal_Bool bSubsFly = IS_SUBS_FLYS && 6078 (GetType() & FRM_FLY) && 6079 bNoLowerColumn && 6080 (!Lower() || !Lower()->IsNoTxtFrm() || 6081 !((SwNoTxtFrm*)Lower())->HasAnimation()); 6082 sal_Bool bSubsBody = sal_False; 6083 if ( GetType() & FRM_BODY ) 6084 { 6085 if ( IsPageBodyFrm() ) 6086 bSubsBody = bSubsOpt && bNoLowerColumn; //nur ohne Spalten 6087 else //Spaltenbody 6088 { 6089 if ( GetUpper()->GetUpper()->IsSctFrm() ) 6090 bSubsBody = IS_SUBS_SECTION; 6091 else 6092 bSubsBody = bSubsOpt; 6093 } 6094 } 6095 6096 if ( bSubsOther || bSubsSect || bSubsBody || bSubsTable || bSubsFly ) 6097 PaintSubsidiaryLines( pPage, rRect ); 6098 6099 const SwFrm *pLow = Lower(); 6100 if( !pLow ) 6101 return; 6102 SwShortCut aShortCut( *pLow, rRect ); 6103 while( pLow && !aShortCut.Stop( pLow->Frm() ) ) 6104 { 6105 if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() ) 6106 { 6107 if ( pLow->IsLayoutFrm() ) 6108 ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect); 6109 else if ( pLow->GetDrawObjs() ) 6110 { 6111 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs()); 6112 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i ) 6113 { 6114 const SwAnchoredObject* pAnchoredObj = rObjs[i]; 6115 if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId( 6116 pAnchoredObj->GetDrawObj()->GetLayer() ) && 6117 pAnchoredObj->ISA(SwFlyFrm) ) 6118 { 6119 const SwFlyFrm *pFly = 6120 static_cast<const SwFlyFrm*>(pAnchoredObj); 6121 if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) ) 6122 { 6123 if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() || 6124 !((SwNoTxtFrm*)pFly->Lower())->HasAnimation()) 6125 pFly->RefreshLaySubsidiary( pPage, rRect ); 6126 } 6127 } 6128 } 6129 } 6130 } 6131 pLow = pLow->GetNext(); 6132 } 6133 } 6134 6135 /************************************************************************* 6136 |* 6137 |* SwLayoutFrm::PaintSubsidiaryLines() 6138 |* 6139 |* Beschreibung Hilfslinien um die PrtAreas malen 6140 |* Nur die LayoutFrm's die direkt Cntnt enthalten. 6141 |* Ersterstellung MA 21. May. 92 6142 |* Letzte Aenderung MA 22. Jan. 95 6143 |* 6144 |*************************************************************************/ 6145 6146 //Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden. 6147 6148 typedef long Size::* SizePtr; 6149 typedef long Point::* PointPtr; 6150 6151 PointPtr pX = &Point::nA; 6152 PointPtr pY = &Point::nB; 6153 SizePtr pWidth = &Size::nA; 6154 SizePtr pHeight = &Size::nB; 6155 6156 // OD 18.11.2002 #99672# - new parameter <_pSubsLines> 6157 void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay, 6158 const SwPageFrm *pPage, 6159 const Point &rP1, 6160 const Point &rP2, 6161 const sal_uInt8 nSubColor, 6162 SwLineRects* _pSubsLines ) 6163 { 6164 //In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein. 6165 ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())), 6166 "Schraege Hilfslinien sind nicht erlaubt." ); 6167 const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX; 6168 const PointPtr pOthPt = pDirPt == pX ? pY : pX; 6169 const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight; 6170 const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth; 6171 Point aP1( rP1 ), 6172 aP2( rP2 ); 6173 6174 while ( aP1.*pDirPt < aP2.*pDirPt ) 6175 { //Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt 6176 //hinter den Fly gesetzt. 6177 //Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt 6178 //ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen. 6179 //Auf diese art und weise wird eine Portion nach der anderen 6180 //ausgegeben. 6181 6182 //Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus, 6183 //die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen. 6184 //Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche 6185 //ich keinem dieser Flys aus. 6186 SwOrderIter aIter( pPage ); 6187 const SwFlyFrm *pMyFly = pLay->FindFlyFrm(); 6188 if ( pMyFly ) 6189 { 6190 aIter.Current( pMyFly->GetVirtDrawObj() ); 6191 while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) ) 6192 { 6193 if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() ) 6194 aIter.Current( pMyFly->GetVirtDrawObj() ); 6195 } 6196 } 6197 else 6198 aIter.Bottom(); 6199 6200 while ( aIter() ) 6201 { 6202 const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter(); 6203 const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0; 6204 6205 //Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich 6206 //_in_ dem Fly sitze weiche ich nicht aus. 6207 if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) ) 6208 { 6209 aIter.Next(); 6210 continue; 6211 } 6212 6213 // OD 19.12.2002 #106318# - do *not* consider fly frames with 6214 // a transparent background. 6215 // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which 6216 // belongs to a invisible layer 6217 if ( pFly->IsBackgroundTransparent() || 6218 !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) ) 6219 { 6220 aIter.Next(); 6221 continue; 6222 } 6223 6224 //Sitzt das Obj auf der Linie 6225 const Rectangle &rBound = pObj->GetCurrentBoundRect(); 6226 const Point aDrPt( rBound.TopLeft() ); 6227 const Size aDrSz( rBound.GetSize() ); 6228 if ( rP1.*pOthPt >= aDrPt.*pOthPt && 6229 rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) ) 6230 { 6231 if ( aP1.*pDirPt >= aDrPt.*pDirPt && 6232 aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) ) 6233 aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz; 6234 6235 if ( aP2.*pDirPt >= aDrPt.*pDirPt && 6236 aP1.*pDirPt < (aDrPt.*pDirPt - 1) ) 6237 aP2.*pDirPt = aDrPt.*pDirPt - 1; 6238 } 6239 aIter.Next(); 6240 } 6241 6242 if ( aP1.*pDirPt < aP2.*pDirPt ) 6243 { 6244 SwRect aRect( aP1, aP2 ); 6245 // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of 6246 // global variable <pSubsLines>. 6247 _pSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6248 } 6249 aP1 = aP2; 6250 aP1.*pDirPt += 1; 6251 aP2 = rP2; 6252 } 6253 } 6254 6255 void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage, 6256 const SwRect &rRect ) const 6257 { 6258 bool bNewTableModel = false; 6259 6260 // --> collapsing borders FME 2005-05-27 #i29550# 6261 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() ) 6262 { 6263 const SwTabFrm* pTabFrm = FindTabFrm(); 6264 if ( pTabFrm->IsCollapsingBorders() ) 6265 return; 6266 6267 bNewTableModel = pTabFrm->GetTable()->IsNewModel(); 6268 // in the new table model, we have an early return for all cell-related 6269 // frames, except from non-covered table cells 6270 if ( bNewTableModel ) 6271 if ( IsTabFrm() || 6272 IsRowFrm() || 6273 ( IsCellFrm() && IsCoveredCell() ) ) 6274 return; 6275 } 6276 // <-- collapsing 6277 6278 const bool bFlys = pPage->GetSortedObjs() ? true : false; 6279 6280 const bool bCell = IsCellFrm() ? true : false; 6281 // use frame area for cells 6282 // OD 13.02.2003 #i3662# - for section use also frame area 6283 const bool bUseFrmArea = bCell || IsSctFrm(); 6284 SwRect aOriginal( bUseFrmArea ? Frm() : Prt() ); 6285 if ( !bUseFrmArea ) 6286 aOriginal.Pos() += Frm().Pos(); 6287 6288 // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area 6289 // in sections to top of section frame. 6290 const bool bColBodyInSection = IsBodyFrm() && 6291 !IsPageBodyFrm() && 6292 GetUpper()->GetUpper()->IsSctFrm(); 6293 if ( bColBodyInSection ) 6294 { 6295 if ( IsVertical() ) 6296 aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() ); 6297 else 6298 aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() ); 6299 } 6300 6301 ::SwAlignRect( aOriginal, pGlobalShell ); 6302 6303 if ( !aOriginal.IsOver( rRect ) ) 6304 return; 6305 6306 SwRect aOut( aOriginal ); 6307 aOut._Intersection( rRect ); 6308 // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's 6309 // printing area with the paint area of the body frame. Otherwise enlargement 6310 // will get lost. 6311 if ( !bColBodyInSection ) 6312 { 6313 aOut.Intersection( PaintArea() ); 6314 } 6315 6316 const SwTwips nRight = aOut.Right(); 6317 const SwTwips nBottom= aOut.Bottom(); 6318 6319 const Point aRT( nRight, aOut.Top() ); 6320 const Point aRB( nRight, nBottom ); 6321 const Point aLB( aOut.Left(), nBottom ); 6322 6323 sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB : 6324 ( IsInSct() ? SUBCOL_SECT : 6325 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) ); 6326 6327 // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks. 6328 sal_Bool bBreak = sal_False; 6329 if ( IsBodyFrm() ) 6330 { 6331 const SwCntntFrm *pCnt = ContainsCntnt(); 6332 if ( pCnt ) 6333 { 6334 // OD 05.11.2002 #102406# - adjust setting of <bBreak>. 6335 bBreak = pCnt->IsPageBreak( sal_True ) || 6336 ( IsColBodyFrm() && pCnt->IsColBreak( sal_True ) ); 6337 } 6338 } 6339 6340 // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section 6341 // sub-lines in <pSpecSubsLine> array. 6342 const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() || 6343 IsFtnFrm() || IsSctFrm(); 6344 SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines; 6345 6346 // NOTE: for cell frames only left and right (horizontal layout) respectively 6347 // top and bottom (vertical layout) lines painted. 6348 // NOTE2: this does not hold for the new table model!!! We paint the top border 6349 // of each non-covered table cell. 6350 const bool bVert = IsVertical() ? true : false; 6351 if ( bFlys ) 6352 { 6353 // OD 14.11.2002 #104822# - add control for drawing left and right lines 6354 if ( !bCell || bNewTableModel || !bVert ) 6355 { 6356 if ( aOriginal.Left() == aOut.Left() ) 6357 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor, 6358 pUsedSubsLines ); 6359 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right 6360 if ( aOriginal.Right() == nRight ) 6361 ::lcl_RefreshLine( this, pPage, aRT, aRB, 6362 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor, 6363 pUsedSubsLines ); 6364 } 6365 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines 6366 if ( !bCell || bNewTableModel || bVert ) 6367 { 6368 if ( aOriginal.Top() == aOut.Top() ) 6369 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top 6370 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT, 6371 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor, 6372 pUsedSubsLines ); 6373 if ( aOriginal.Bottom() == nBottom ) 6374 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor, 6375 pUsedSubsLines ); 6376 } 6377 } 6378 else 6379 { 6380 // OD 14.11.2002 #104822# - add control for drawing left and right lines 6381 if ( !bCell || bNewTableModel || !bVert ) 6382 { 6383 if ( aOriginal.Left() == aOut.Left() ) 6384 { 6385 const SwRect aRect( aOut.Pos(), aLB ); 6386 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6387 } 6388 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right 6389 if ( aOriginal.Right() == nRight ) 6390 { 6391 const SwRect aRect( aRT, aRB ); 6392 pUsedSubsLines->AddLineRect( aRect, 0, 0, 6393 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor ); 6394 } 6395 } 6396 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines 6397 if ( !bCell || bNewTableModel || bVert ) 6398 { 6399 if ( aOriginal.Top() == aOut.Top() ) 6400 { 6401 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top 6402 const SwRect aRect( aOut.Pos(), aRT ); 6403 pUsedSubsLines->AddLineRect( aRect, 0, 0, 6404 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor ); 6405 } 6406 if ( aOriginal.Bottom() == nBottom ) 6407 { 6408 const SwRect aRect( aLB, aRB ); 6409 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6410 } 6411 } 6412 } 6413 } 6414 6415 /************************************************************************* 6416 |* 6417 |* SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData() 6418 |* 6419 |* Beschreibung Erneuert alle Extradaten (Zeilennummern usw) der Seite. 6420 |* Grundsaetzlich sind nur diejenigen Objekte beruecksichtig, 6421 |* die in die seitliche Ausdehnung des Rects ragen. 6422 |* Ersterstellung MA 20. Jan. 98 6423 |* Letzte Aenderung MA 18. Feb. 98 6424 |* 6425 |*************************************************************************/ 6426 6427 void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const 6428 { 6429 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo(); 6430 sal_Bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys()) 6431 || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE; 6432 6433 SwRect aRect( rRect ); 6434 ::SwAlignRect( aRect, pGlobalShell ); 6435 if ( aRect.HasArea() ) 6436 { 6437 SwLayoutFrm::RefreshExtraData( aRect ); 6438 6439 if ( bLineInFly && GetSortedObjs() ) 6440 for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i ) 6441 { 6442 const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i]; 6443 if ( pAnchoredObj->ISA(SwFlyFrm) ) 6444 { 6445 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); 6446 if ( pFly->Frm().Top() <= aRect.Bottom() && 6447 pFly->Frm().Bottom() >= aRect.Top() ) 6448 pFly->RefreshExtraData( aRect ); 6449 } 6450 } 6451 } 6452 } 6453 6454 void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const 6455 { 6456 6457 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo(); 6458 sal_Bool bLineInBody = rInfo.IsPaintLineNumbers(), 6459 bLineInFly = bLineInBody && rInfo.IsCountInFlys(), 6460 bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE; 6461 6462 const SwCntntFrm *pCnt = ContainsCntnt(); 6463 while ( pCnt && IsAnLower( pCnt ) ) 6464 { 6465 if ( pCnt->IsTxtFrm() && ( bRedLine || 6466 ( !pCnt->IsInTab() && 6467 ((bLineInBody && pCnt->IsInDocBody()) || 6468 (bLineInFly && pCnt->IsInFly())) ) ) && 6469 pCnt->Frm().Top() <= rRect.Bottom() && 6470 pCnt->Frm().Bottom() >= rRect.Top() ) 6471 { 6472 ((SwTxtFrm*)pCnt)->PaintExtraData( rRect ); 6473 } 6474 if ( bLineInFly && pCnt->GetDrawObjs() ) 6475 for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i ) 6476 { 6477 const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i]; 6478 if ( pAnchoredObj->ISA(SwFlyFrm) ) 6479 { 6480 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); 6481 if ( pFly->IsFlyInCntFrm() && 6482 pFly->Frm().Top() <= rRect.Bottom() && 6483 pFly->Frm().Bottom() >= rRect.Top() ) 6484 pFly->RefreshExtraData( rRect ); 6485 } 6486 } 6487 pCnt = pCnt->GetNextCntntFrm(); 6488 } 6489 } 6490 6491 /** SwPageFrm::GetDrawBackgrdColor - for #102450# 6492 6493 determine the color, that is respectively will be drawn as background 6494 for the page frame. 6495 Using existing method SwFrm::GetBackgroundBrush to determine the color 6496 that is set at the page frame respectively is parent. If none is found 6497 return the global retouche color 6498 6499 @author OD 6500 6501 @return Color 6502 */ 6503 const Color& SwPageFrm::GetDrawBackgrdColor() const 6504 { 6505 const SvxBrushItem* pBrushItem; 6506 const Color* pDummyColor; 6507 SwRect aDummyRect; 6508 6509 //UUUU 6510 FillAttributesPtr aFillAttributes; 6511 6512 if ( GetBackgroundBrush( aFillAttributes, pBrushItem, pDummyColor, aDummyRect, true) ) 6513 { 6514 const Graphic* pGraphic = pBrushItem->GetGraphic(); 6515 6516 if(pGraphic) 6517 { 6518 // #29105# when a graphic is set, it may be possible to calculate a single 6519 // color which looks good in all places of the graphic. Since it is 6520 // planned to have text edit on the overlay one day and the fallback 6521 // to aGlobalRetoucheColor returns something useful, just use that 6522 // for now. 6523 } 6524 else 6525 { 6526 // not a graphic, use (hopefully) initialized color 6527 return pBrushItem->GetColor(); 6528 } 6529 } 6530 6531 return aGlobalRetoucheColor; 6532 } 6533 6534 /************************************************************************* 6535 |* 6536 |* SwPageFrm::GetEmptyPageFont() 6537 |* 6538 |* create/return font used to paint the "empty page" string 6539 |* 6540 |*************************************************************************/ 6541 6542 const Font& SwPageFrm::GetEmptyPageFont() 6543 { 6544 static Font* pEmptyPgFont = 0; 6545 if ( 0 == pEmptyPgFont ) 6546 { 6547 pEmptyPgFont = new Font; 6548 pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt 6549 pEmptyPgFont->SetWeight( WEIGHT_BOLD ); 6550 pEmptyPgFont->SetStyleName( aEmptyStr ); 6551 pEmptyPgFont->SetName( String::CreateFromAscii( 6552 RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) ); 6553 pEmptyPgFont->SetFamily( FAMILY_SWISS ); 6554 pEmptyPgFont->SetTransparent( sal_True ); 6555 pEmptyPgFont->SetColor( COL_GRAY ); 6556 } 6557 6558 return *pEmptyPgFont; 6559 } 6560 6561 /************************************************************************* 6562 |* 6563 |* SwFrm::Retouche 6564 |* 6565 |* Beschreibung Retouche fuer einen Bereich. 6566 |* Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner 6567 |* Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird 6568 |* per PaintBackground gecleared. 6569 |* Ersterstellung MA 13. Apr. 93 6570 |* Letzte Aenderung MA 25. Jul. 96 6571 |* 6572 |*************************************************************************/ 6573 6574 void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const 6575 { 6576 if ( bFlyMetafile ) 6577 return; 6578 6579 ASSERT( GetUpper(), "Retoucheversuch ohne Upper." ); 6580 ASSERT( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" ); 6581 6582 SwRect aRetouche( GetUpper()->PaintArea() ); 6583 aRetouche.Top( Frm().Top() + Frm().Height() ); 6584 aRetouche.Intersection( pGlobalShell->VisArea() ); 6585 6586 if ( aRetouche.HasArea() ) 6587 { 6588 //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region 6589 //zum ausstanzen. 6590 SwRegionRects aRegion( aRetouche ); 6591 aRegion -= rRect; 6592 ViewShell *pSh = getRootFrm()->GetCurrShell(); 6593 6594 // --> FME 2004-06-24 #i16816# tagged pdf support 6595 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); 6596 // <-- 6597 6598 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 6599 { 6600 SwRect &rRetouche = aRegion[i]; 6601 6602 GetUpper()->PaintBaBo( rRetouche, pPage, sal_True ); 6603 6604 //Hoelle und Himmel muessen auch refreshed werden. 6605 //Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst 6606 //zurueckgesetzt werden! 6607 ResetRetouche(); 6608 SwRect aRetouchePart( rRetouche ); 6609 if ( aRetouchePart.HasArea() ) 6610 { 6611 const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor(); 6612 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 6613 // --> OD #i76669# 6614 SwViewObjectContactRedirector aSwRedirector( *pSh ); 6615 // <-- 6616 6617 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0, 6618 aRetouchePart, &aPageBackgrdColor, 6619 (pPage->IsRightToLeft() ? true : false), 6620 &aSwRedirector ); 6621 pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0, 6622 aRetouchePart, &aPageBackgrdColor, 6623 (pPage->IsRightToLeft() ? true : false), 6624 &aSwRedirector ); 6625 } 6626 6627 SetRetouche(); 6628 6629 //Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier 6630 //leider die Hilfslinien erneuert werden. 6631 pPage->RefreshSubsidiary( aRetouchePart ); 6632 } 6633 } 6634 if ( ViewShell::IsLstEndAction() ) 6635 ResetRetouche(); 6636 } 6637 6638 /** SwFrm::GetBackgroundBrush 6639 6640 @descr 6641 determine the background brush for the frame: 6642 the background brush is taken from it-self or from its parent (anchor/upper). 6643 Normally, the background brush is taken, which has no transparent color or 6644 which has a background graphic. But there are some special cases: 6645 (1) No background brush is taken from a page frame, if view option "IsPageBack" 6646 isn't set. 6647 (2) Background brush from a index section is taken under special conditions. 6648 In this case parameter <rpCol> is set to the index shading color. 6649 (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing 6650 of the frame transparency is considered and its color is not "no fill"/"auto fill" 6651 ---- old description in german: 6652 Beschreibung Liefert die Backgroundbrush fuer den Bereich des 6653 des Frm. Die Brush wird entweder von ihm selbst oder von einem 6654 Upper vorgegeben, die erste Brush wird benutzt. 6655 Ist fuer keinen Frm eine Brush angegeben, so wird sal_False zurueck- 6656 geliefert. 6657 Ersterstellung MA 23. Dec. 92 6658 Letzte Aenderung MA 04. Feb. 97 6659 6660 @param rpBrush 6661 output parameter - constant reference pointer the found background brush 6662 6663 @param rpCol 6664 output parameter - constant reference pointer to the color of the index shading 6665 set under special conditions, if background brush is taken from an index section. 6666 6667 @param rOrigRect 6668 in-/output parameter - reference to the retangle the background brush is 6669 considered for - adjusted to the frame, from which the background brush is 6670 taken. 6671 6672 @parem bLowerMode 6673 input parameter - boolean indicating, if background brush should *not* be 6674 taken from parent. 6675 6676 @author MA 6677 @change 20.08.2002 by OD 6678 @docdate 20.08.2002 6679 6680 @return true, if a background brush for the frame is found 6681 */ 6682 sal_Bool SwFrm::GetBackgroundBrush( 6683 FillAttributesPtr& rFillAttributes, 6684 const SvxBrushItem* & rpBrush, 6685 const Color*& rpCol, 6686 SwRect &rOrigRect, 6687 sal_Bool bLowerMode ) const 6688 { 6689 const SwFrm *pFrm = this; 6690 ViewShell *pSh = getRootFrm()->GetCurrShell(); 6691 const SwViewOption *pOpt = pSh->GetViewOptions(); 6692 rpBrush = 0; 6693 rpCol = NULL; 6694 do 6695 { if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() ) 6696 return sal_False; 6697 6698 //UUUU 6699 const SwLayoutFrm* pSwLayoutFrm = dynamic_cast< const SwLayoutFrm* >(pFrm); 6700 6701 if(pSwLayoutFrm) 6702 { 6703 const SwFrmFmt* pSwFrmFmt = dynamic_cast< const SwFrmFmt* >(pSwLayoutFrm->GetFmt()); 6704 6705 if(pSwFrmFmt && RES_FLYFRMFMT == pSwFrmFmt->Which()) 6706 { 6707 rFillAttributes = pSwFrmFmt->getFillAttributes(); 6708 } 6709 } 6710 6711 const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground(); 6712 6713 if( pFrm->IsSctFrm() ) 6714 { 6715 const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection(); 6716 /// OD 20.08.2002 #99657# #GetTransChg# 6717 /// Note: If frame <pFrm> is a section of the index and 6718 /// it its background color is "no fill"/"auto fill" and 6719 /// it has no background graphic and 6720 /// we are not in the page preview and 6721 /// we are not in read-only mode and 6722 /// option "index shadings" is set and 6723 /// the output is not the printer 6724 /// then set <rpCol> to the color of the index shading 6725 if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() || 6726 TOX_CONTENT_SECTION == pSection->GetType() ) && 6727 (rBack.GetColor() == COL_TRANSPARENT) && 6728 ///rBack.GetColor().GetTransparency() && 6729 rBack.GetGraphicPos() == GPOS_NONE && 6730 !pOpt->IsPagePreview() && 6731 !pOpt->IsReadonly() && 6732 // --> FME 2004-06-29 #114856# Formular view 6733 !pOpt->IsFormView() && 6734 // <-- 6735 SwViewOption::IsIndexShadings() && 6736 !pOpt->IsPDFExport() && 6737 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER ) 6738 { 6739 rpCol = &SwViewOption::GetIndexShadingsColor(); 6740 } 6741 } 6742 6743 /// OD 20.08.2002 #99657# 6744 /// determine, if background draw of frame <pFrm> considers transparency 6745 /// --> Status Quo: background transparency have to be 6746 /// considered for fly frames 6747 const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm(); 6748 6749 /// OD 20.08.2002 #99657# 6750 /// add condition: 6751 /// If <bConsiderBackgroundTransparency> is set - see above -, 6752 /// return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill" 6753 if ( 6754 // done when FillAttributesare set 6755 (rFillAttributes.get() && rFillAttributes->isUsed()) || 6756 6757 // done when SvxBrushItem is used 6758 !rBack.GetColor().GetTransparency() || rBack.GetGraphicPos() != GPOS_NONE || 6759 6760 // done when direct color is forced 6761 rpCol || 6762 6763 // done when consider BG transparency and color is not completely transparent 6764 (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT)) 6765 ) 6766 { 6767 rpBrush = &rBack; 6768 6769 if ( pFrm->IsPageFrm() && pSh->GetViewOptions()->getBrowseMode() ) 6770 { 6771 rOrigRect = pFrm->Frm(); 6772 } 6773 else 6774 { 6775 if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() ) 6776 { 6777 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); 6778 const SwBorderAttrs &rAttrs = *aAccess.Get(); 6779 ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, sal_False ); 6780 } 6781 else 6782 { 6783 rOrigRect = pFrm->Prt(); 6784 rOrigRect += pFrm->Frm().Pos(); 6785 } 6786 } 6787 6788 return sal_True; 6789 } 6790 6791 if ( bLowerMode ) 6792 { 6793 /// Do not try to get background brush from parent (anchor/upper) 6794 return sal_False; 6795 } 6796 6797 /// get parent frame - anchor or upper - for next loop 6798 if ( pFrm->IsFlyFrm() ) 6799 { 6800 /// OD 20.08.2002 - use "static_cast" instead of "old C-cast" 6801 pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm(); 6802 ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor(); 6803 } 6804 else 6805 { 6806 pFrm = pFrm->GetUpper(); 6807 } 6808 } while ( pFrm ); 6809 6810 return sal_False; 6811 } 6812 6813 /************************************************************************* 6814 |* 6815 |* SwFrmFmt::GetGraphic() 6816 |* 6817 |* Ersterstellung MA 23. Jul. 96 6818 |* Letzte Aenderung MA 23. Jul. 96 6819 |* 6820 |*************************************************************************/ 6821 6822 void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO, 6823 Window *pW, sal_uInt16 nZoom ) 6824 { 6825 pSh->pOut = pO; 6826 pSh->pWin = pW; 6827 pSh->pOpt->SetZoom( nZoom ); 6828 } 6829 6830 Graphic SwFrmFmt::MakeGraphic( ImageMap* ) 6831 { 6832 return Graphic(); 6833 } 6834 6835 Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap ) 6836 { 6837 Graphic aRet; 6838 //irgendeinen Fly suchen! 6839 SwIterator<SwFrm,SwFmt> aIter( *this ); 6840 SwFrm *pFirst = aIter.First(); 6841 ViewShell *pSh; 6842 if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) ) 6843 { 6844 ViewShell *pOldGlobal = pGlobalShell; 6845 pGlobalShell = pSh; 6846 6847 sal_Bool bNoteURL = pMap && 6848 SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, sal_True ); 6849 if( bNoteURL ) 6850 { 6851 ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " ); 6852 pNoteURL = new SwNoteURL; 6853 } 6854 SwFlyFrm *pFly = (SwFlyFrm*)pFirst; 6855 6856 OutputDevice *pOld = pSh->GetOut(); 6857 VirtualDevice aDev( *pOld ); 6858 aDev.EnableOutput( sal_False ); 6859 6860 GDIMetaFile aMet; 6861 MapMode aMap( pOld->GetMapMode().GetMapUnit() ); 6862 aDev.SetMapMode( aMap ); 6863 aMet.SetPrefMapMode( aMap ); 6864 6865 ::SwCalcPixStatics( pSh->GetOut() ); 6866 aMet.SetPrefSize( pFly->Frm().SSize() ); 6867 6868 aMet.Record( &aDev ); 6869 aDev.SetLineColor(); 6870 aDev.SetFillColor(); 6871 aDev.SetFont( pOld->GetFont() ); 6872 6873 //Rechteck ggf. ausdehnen, damit die Umrandunge mit aufgezeichnet werden. 6874 SwRect aOut( pFly->Frm() ); 6875 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly ); 6876 const SwBorderAttrs &rAttrs = *aAccess.Get(); 6877 if ( rAttrs.CalcRightLine() ) 6878 aOut.SSize().Width() += 2*nPixelSzW; 6879 if ( rAttrs.CalcBottomLine() ) 6880 aOut.SSize().Height()+= 2*nPixelSzH; 6881 6882 // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev 6883 const Region aRepaintRegion(aOut.SVRect()); 6884 pSh->DLPrePaint2(aRepaintRegion); 6885 6886 Window *pWin = pSh->GetWin(); 6887 sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom(); 6888 ::SetOutDevAndWin( pSh, &aDev, 0, 100 ); 6889 bFlyMetafile = sal_True; 6890 pFlyMetafileOut = pWin; 6891 6892 SwViewImp *pImp = pSh->Imp(); 6893 pFlyOnlyDraw = pFly; 6894 pLines = new SwLineRects; 6895 6896 // OD 09.12.2002 #103045# - determine page, fly frame is on 6897 const SwPageFrm* pFlyPage = pFly->FindPageFrm(); 6898 const Color aPageBackgrdColor = pFlyPage->GetDrawBackgrdColor(); 6899 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 6900 // --> OD #i76669# 6901 SwViewObjectContactRedirector aSwRedirector( *pSh ); 6902 // <-- 6903 pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor, 6904 (pFlyPage->IsRightToLeft() ? true : false), 6905 &aSwRedirector ); 6906 pLines->PaintLines( &aDev ); 6907 if ( pFly->IsFlyInCntFrm() ) 6908 pFly->Paint( aOut ); 6909 pLines->PaintLines( &aDev ); 6910 /// OD 30.08.2002 #102450# - add 3rd parameter 6911 pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor, 6912 (pFlyPage->IsRightToLeft() ? true : false), 6913 &aSwRedirector ); 6914 pLines->PaintLines( &aDev ); 6915 DELETEZ( pLines ); 6916 pFlyOnlyDraw = 0; 6917 6918 pFlyMetafileOut = 0; 6919 bFlyMetafile = sal_False; 6920 ::SetOutDevAndWin( pSh, pOld, pWin, nZoom ); 6921 6922 // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted 6923 pSh->DLPostPaint2(true); 6924 6925 aMet.Stop(); 6926 aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() ); 6927 aRet = Graphic( aMet ); 6928 6929 if( bNoteURL ) 6930 { 6931 ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." ); 6932 pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap ); 6933 delete pNoteURL; 6934 pNoteURL = NULL; 6935 } 6936 pGlobalShell = pOldGlobal; 6937 } 6938 return aRet; 6939 } 6940 6941 Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* ) 6942 { 6943 Graphic aRet; 6944 SdrModel *pMod = getIDocumentDrawModelAccess()->GetDrawModel(); 6945 if ( pMod ) 6946 { 6947 SdrObject *pObj = FindSdrObject(); 6948 SdrView *pView = new SdrView( pMod ); 6949 SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0)); 6950 pView->MarkObj( pObj, pPgView ); 6951 aRet = pView->GetMarkedObjBitmapEx(); 6952 pView->HideSdrPage(); 6953 delete pView; 6954 } 6955 return aRet; 6956 } 6957 6958 6959