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