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 if ( pObj->ISA(SwVirtFlyDrawObj) ) 3426 { 3427 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 3428 if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly ) 3429 return sal_True; 3430 3431 //Die Anzeige eines Zwischenstadiums vermeiden, Flys die nicht mit 3432 //der Seite auf der sie verankert sind ueberlappen werden auch 3433 //nicht gepaintet. 3434 //HACK: Ausnahme: Drucken von Rahmen in Tabellen, diese koennen 3435 //bei uebergrossen Tabellen (HTML) schon mal auserhalb der Seite 3436 //stehen. 3437 SwPageFrm *pPage = pFly->FindPageFrm(); 3438 if ( pPage ) 3439 { 3440 if ( pPage->Frm().IsOver( pFly->Frm() ) ) 3441 pAnch = pFly->AnchorFrm(); 3442 else if ( bTableHack && 3443 pFly->Frm().Top() >= pFly->GetAnchorFrm()->Frm().Top() && 3444 pFly->Frm().Top() < pFly->GetAnchorFrm()->Frm().Bottom() && 3445 long(pSh->GetOut()) == 3446 long(pSh->getIDocumentDeviceAccess()->getPrinter( false ) ) ) 3447 { 3448 pAnch = pFly->AnchorFrm(); 3449 } 3450 } 3451 3452 } 3453 else 3454 { 3455 // OD 13.10.2003 #i19919# - consider 'virtual' drawing objects 3456 // OD 2004-03-29 #i26791# 3457 pAnch = ((SwDrawContact*)pUserCall)->GetAnchorFrm( pObj ); 3458 if ( pAnch ) 3459 { 3460 if ( !pAnch->GetValidPosFlag() ) 3461 pAnch = 0; 3462 else if ( long(pSh->GetOut()) == long(pSh->getIDocumentDeviceAccess()->getPrinter( false ))) 3463 { 3464 //HACK: fuer das Drucken muessen wir ein paar Objekte 3465 //weglassen, da diese sonst doppelt gedruckt werden. 3466 //Die Objekte sollen gedruckt werden, wenn der TableHack 3467 //gerade greift. In der Folge duerfen sie nicht gedruckt werden 3468 //wenn sie mit der Seite dran sind, ueber der sie von der 3469 //Position her gerade schweben. 3470 const SwPageFrm *pPage = pAnch->FindPageFrm(); 3471 if ( !bTableHack && 3472 !pPage->Frm().IsOver( pObj->GetCurrentBoundRect() ) ) 3473 pAnch = 0; 3474 } 3475 } 3476 else 3477 { 3478 // OD 02.07.2003 #108784# - debug assert 3479 if ( !pObj->ISA(SdrObjGroup) ) 3480 { 3481 ASSERT( false, "<SwFlyFrm::IsPaint(..)> - paint of drawing object without anchor frame!?" ); 3482 } 3483 } 3484 } 3485 if ( pAnch ) 3486 { 3487 if ( pAnch->IsInFly() ) 3488 bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(), 3489 pSh ); 3490 else if ( pFlyOnlyDraw ) 3491 bPaint = sal_False; 3492 } 3493 else 3494 bPaint = sal_False; 3495 } 3496 return bPaint; 3497 } 3498 3499 /************************************************************************* 3500 |* SwCellFrm::Paint( const SwRect& ) const 3501 |*************************************************************************/ 3502 void SwCellFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3503 { 3504 if ( GetLayoutRowSpan() >= 1 ) 3505 SwLayoutFrm::Paint( rRect ); 3506 } 3507 3508 /************************************************************************* 3509 |* 3510 |* SwFlyFrm::Paint() 3511 |* 3512 |* Ersterstellung MA ?? 3513 |* Letzte Aenderung MA 16. Jan. 97 3514 |* 3515 |*************************************************************************/ 3516 3517 //Weiter unten definiert 3518 void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay, 3519 const SwRect &rRect, const SwPageFrm *pPage ); 3520 3521 void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3522 { 3523 //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die 3524 //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben. 3525 //z.B. #33066# 3526 pLines->LockLines(sal_True); 3527 3528 SwRect aRect( rRect ); 3529 aRect._Intersection( Frm() ); 3530 3531 OutputDevice* pOut = pGlobalShell->GetOut(); 3532 pOut->Push( PUSH_CLIPREGION ); 3533 pOut->SetClipRegion(); 3534 const SwPageFrm* pPage = FindPageFrm(); 3535 3536 const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm() 3537 ? (SwNoTxtFrm*)Lower() : 0; 3538 3539 bool bIsChart = false; //#i102950# don't paint additional borders for charts 3540 //check whether we have a chart 3541 if(pNoTxt) 3542 { 3543 const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode()); 3544 if( pNoTNd ) 3545 { 3546 SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode()); 3547 if( pOLENd && ChartPrettyPainter::IsChart( pOLENd->GetOLEObj().GetObject() ) ) 3548 bIsChart = true; 3549 } 3550 } 3551 3552 { 3553 bool bContour = GetFmt()->GetSurround().IsContour(); 3554 PolyPolygon aPoly; 3555 if ( bContour ) 3556 { 3557 // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True> 3558 // to indicate that method is called for paint in order to avoid 3559 // load of the intrinsic graphic. 3560 bContour = GetContour( aPoly, sal_True ); 3561 } 3562 3563 // --> OD 2005-06-08 #i47804# - distinguish complete background paint 3564 // and margin paint. 3565 // paint complete background for Writer text fly frames 3566 bool bPaintCompleteBack( !pNoTxt ); 3567 // <-- 3568 // paint complete background for transparent graphic and contour, 3569 // if own background color exists. 3570 const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false; 3571 if ( !bPaintCompleteBack && 3572 ( bIsGraphicTransparent|| bContour ) ) 3573 { 3574 const SvxBrushItem &rBack = GetFmt()->GetBackground(); 3575 // OD 07.08.2002 #99657# #GetTransChg# 3576 // to determine, if background has to be painted, by checking, if 3577 // background color is not COL_TRANSPARENT ("no fill"/"auto fill") 3578 // or a background graphic exists. 3579 bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) || 3580 rBack.GetGraphicPos() != GPOS_NONE; 3581 } 3582 // paint of margin needed. 3583 const bool bPaintMarginOnly( !bPaintCompleteBack && 3584 Prt().SSize() != Frm().SSize() ); 3585 3586 // --> OD 2005-06-08 #i47804# - paint background of parent fly frame 3587 // for transparent graphics in layer Hell, if parent fly frame isn't 3588 // in layer Hell. It's only painted the intersection between the 3589 // parent fly frame area and the paint area <aRect> 3590 const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess(); 3591 3592 if ( bIsGraphicTransparent && 3593 GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() && 3594 GetAnchorFrm()->FindFlyFrm() ) 3595 { 3596 const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm(); 3597 if ( pParentFlyFrm->GetDrawObj()->GetLayer() != 3598 pIDDMA->GetHellId() ) 3599 { 3600 SwFlyFrm* pOldRet = pRetoucheFly2; 3601 pRetoucheFly2 = const_cast<SwFlyFrm*>(this); 3602 3603 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm ); 3604 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3605 SwRect aPaintRect( aRect ); 3606 aPaintRect._Intersection( pParentFlyFrm->Frm() ); 3607 pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False ); 3608 3609 pRetoucheFly2 = pOldRet; 3610 } 3611 } 3612 3613 if ( bPaintCompleteBack || bPaintMarginOnly ) 3614 { 3615 //#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder 3616 //das orig. Rect bekommt, aber PaintBackground das begrenzte. 3617 3618 // OD 2004-04-23 #116347# 3619 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 3620 pOut->SetLineColor(); 3621 3622 pPage = FindPageFrm(); 3623 3624 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 3625 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3626 3627 // OD 06.08.2002 #99657# - paint border before painting background 3628 // paint border 3629 { 3630 SwRect aTmp( rRect ); 3631 PaintBorder( aTmp, pPage, rAttrs ); 3632 } 3633 3634 // paint background 3635 { 3636 SwRegionRects aRegion( aRect ); 3637 // --> OD 2007-12-13 #i80822# 3638 // suppress painting of background in printing area for 3639 // non-transparent graphics. 3640 // if ( bPaintMarginOnly ) 3641 if ( bPaintMarginOnly || 3642 ( pNoTxt && !bIsGraphicTransparent ) ) 3643 // <-- 3644 { 3645 //Was wir eigentlich Painten wollen ist der schmale Streifen 3646 //zwischen PrtArea und aeusserer Umrandung. 3647 SwRect aTmp( Prt() ); aTmp += Frm().Pos(); 3648 aRegion -= aTmp; 3649 } 3650 if ( bContour ) 3651 { 3652 pOut->Push(); 3653 // --> OD 2007-12-13 #i80822# 3654 // apply clip region under the same conditions, which are 3655 // used in <SwNoTxtFrm::Paint(..)> to set the clip region 3656 // for painting the graphic/OLE. Thus, the clip region is 3657 // also applied for the PDF export. 3658 // if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER ) 3659 ViewShell *pSh = getRootFrm()->GetCurrShell(); 3660 if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() ) 3661 // <-- 3662 { 3663 pOut->SetClipRegion( aPoly ); 3664 } 3665 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 3666 PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True ); 3667 pOut->Pop(); 3668 } 3669 else 3670 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 3671 PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True ); 3672 } 3673 3674 pOut->Pop(); 3675 } 3676 } 3677 3678 // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and 3679 // the subsidiary lines of its lowers on its own, due to overlapping with 3680 // other fly frames or other objects. 3681 if( pGlobalShell->GetWin() 3682 && !bIsChart ) //#i102950# don't paint additional borders for charts 3683 { 3684 bool bSubsLineRectsCreated; 3685 if ( pSubsLines ) 3686 { 3687 // Lock already existing subsidiary lines 3688 pSubsLines->LockLines( sal_True ); 3689 bSubsLineRectsCreated = false; 3690 } 3691 else 3692 { 3693 // create new subsidiardy lines 3694 pSubsLines = new SwSubsRects; 3695 bSubsLineRectsCreated = true; 3696 } 3697 3698 bool bSpecSubsLineRectsCreated; 3699 if ( pSpecSubsLines ) 3700 { 3701 // Lock already existing special subsidiary lines 3702 pSpecSubsLines->LockLines( sal_True ); 3703 bSpecSubsLineRectsCreated = false; 3704 } 3705 else 3706 { 3707 // create new special subsidiardy lines 3708 pSpecSubsLines = new SwSubsRects; 3709 bSpecSubsLineRectsCreated = true; 3710 } 3711 // Add subsidiary lines of fly frame and its lowers 3712 RefreshLaySubsidiary( pPage, aRect ); 3713 // paint subsidiary lines of fly frame and its lowers 3714 pSpecSubsLines->PaintSubsidiary( pOut, NULL ); 3715 pSubsLines->PaintSubsidiary( pOut, pLines ); 3716 if ( !bSubsLineRectsCreated ) 3717 // unlock subsidiary lines 3718 pSubsLines->LockLines( sal_False ); 3719 else 3720 // delete created subsidiary lines container 3721 DELETEZ( pSubsLines ); 3722 3723 if ( !bSpecSubsLineRectsCreated ) 3724 // unlock special subsidiary lines 3725 pSpecSubsLines->LockLines( sal_False ); 3726 else 3727 { 3728 // delete created special subsidiary lines container 3729 DELETEZ( pSpecSubsLines ); 3730 } 3731 } 3732 3733 SwLayoutFrm::Paint( aRect ); 3734 3735 Validate(); 3736 3737 // OD 19.12.2002 #106318# - first paint lines added by fly frame paint 3738 // and then unlock other lines. 3739 pLines->PaintLines( pOut ); 3740 pLines->LockLines( sal_False ); 3741 3742 pOut->Pop(); 3743 3744 if ( pProgress && pNoTxt ) 3745 pProgress->Reschedule(); 3746 } 3747 /************************************************************************* 3748 |* 3749 |* SwTabFrm::Paint() 3750 |* 3751 |* Ersterstellung MA 11. May. 93 3752 |* Letzte Aenderung MA 23. Mar. 95 3753 |* 3754 |*************************************************************************/ 3755 3756 void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3757 { 3758 if ( pGlobalShell->GetViewOptions()->IsTable() ) 3759 { 3760 // --> collapsing borders FME 2005-05-27 #i29550# 3761 if ( IsCollapsingBorders() ) 3762 { 3763 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 3764 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3765 3766 // paint shadow 3767 if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE ) 3768 { 3769 SwRect aRect; 3770 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True ); 3771 PaintShadow( rRect, aRect, rAttrs ); 3772 } 3773 3774 // paint lines 3775 SwTabFrmPainter aHelper( *this ); 3776 aHelper.PaintLines( *pGlobalShell->GetOut(), rRect ); 3777 } 3778 // <-- collapsing 3779 3780 SwLayoutFrm::Paint( rRect ); 3781 } 3782 // OD 10.01.2003 #i6467# - no light grey rectangle for page preview 3783 else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() ) 3784 { 3785 // OD 10.01.2003 #i6467# - intersect output rectangle with table frame 3786 SwRect aTabRect( Prt() ); 3787 aTabRect.Pos() += Frm().Pos(); 3788 SwRect aTabOutRect( rRect ); 3789 aTabOutRect.Intersection( aTabRect ); 3790 pGlobalShell->GetViewOptions()-> 3791 DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY ); 3792 } 3793 ((SwTabFrm*)this)->ResetComplete(); 3794 } 3795 3796 /************************************************************************* 3797 |* 3798 |* SwFrm::PaintShadow() 3799 |* 3800 |* Beschreibung Malt einen Schatten wenns das FrmFormat fordert. 3801 |* Der Schatten wird immer an den auesseren Rand des OutRect gemalt. 3802 |* Das OutRect wird ggf. so verkleinert, dass auf diesem das 3803 |* malen der Umrandung stattfinden kann. 3804 |* Ersterstellung MA 21. Dec. 92 3805 |* Letzte Aenderung MA 29. May. 97 3806 |* 3807 |*************************************************************************/ 3808 /// OD 23.08.2002 #99657# 3809 /// draw full shadow rectangle for frames with transparent drawn backgrounds. 3810 void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect, 3811 const SwBorderAttrs &rAttrs ) const 3812 { 3813 const SvxShadowItem &rShadow = rAttrs.GetShadow(); 3814 const long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth() ); 3815 const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() ); 3816 3817 SwRects aRegion( 2, 2 ); 3818 SwRect aOut( rOutRect ); 3819 3820 const sal_Bool bCnt = IsCntntFrm(); 3821 const sal_Bool bTop = !bCnt || rAttrs.GetTopLine ( *(this) ) ? sal_True : sal_False; 3822 const sal_Bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? sal_True : sal_False; 3823 3824 SvxShadowLocation eLoc = rShadow.GetLocation(); 3825 3826 SWRECTFN( this ) 3827 if( IsVertical() ) 3828 { 3829 switch( eLoc ) 3830 { 3831 case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break; 3832 case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break; 3833 case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break; 3834 case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_TOPLEFT; break; 3835 default: break; 3836 } 3837 } 3838 3839 /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to 3840 /// be drawn or only two shadow rectangles beside the frame. 3841 /// draw full shadow rectangle, if frame background is drawn transparent. 3842 /// Status Quo: 3843 /// SwLayoutFrm can have transparent drawn backgrounds. Thus, 3844 /// "asked" their frame format. 3845 sal_Bool bDrawFullShadowRectangle = 3846 ( IsLayoutFrm() && 3847 (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent() 3848 ); 3849 switch ( eLoc ) 3850 { 3851 case SVX_SHADOW_BOTTOMRIGHT: 3852 { 3853 if ( bDrawFullShadowRectangle ) 3854 { 3855 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3856 aOut.Top( aOut.Top() + nHeight ); 3857 aOut.Left( aOut.Left() + nWidth ); 3858 aRegion.Insert( aOut, aRegion.Count() ); 3859 } 3860 else 3861 { 3862 aOut.Top ( aOut.Bottom() - nHeight ); 3863 aOut.Left( aOut.Left() + nWidth ); 3864 if ( bBottom ) 3865 aRegion.Insert( aOut, aRegion.Count() ); 3866 aOut.Left( aOut.Right() - nWidth ); 3867 aOut.Top ( rOutRect.Top() + nHeight ); 3868 if ( bBottom ) 3869 aOut.Bottom( aOut.Bottom() - nHeight ); 3870 if ( bCnt && (!bTop || !bBottom) ) 3871 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 3872 aRegion.Insert( aOut, aRegion.Count() ); 3873 } 3874 3875 rOutRect.Right ( rOutRect.Right() - nWidth ); 3876 rOutRect.Bottom( rOutRect.Bottom()- nHeight ); 3877 } 3878 break; 3879 case SVX_SHADOW_TOPLEFT: 3880 { 3881 if ( bDrawFullShadowRectangle ) 3882 { 3883 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3884 aOut.Bottom( aOut.Bottom() - nHeight ); 3885 aOut.Right( aOut.Right() - nWidth ); 3886 aRegion.Insert( aOut, aRegion.Count() ); 3887 } 3888 else 3889 { 3890 aOut.Bottom( aOut.Top() + nHeight ); 3891 aOut.Right ( aOut.Right() - nWidth ); 3892 if ( bTop ) 3893 aRegion.Insert( aOut, aRegion.Count() ); 3894 aOut.Right ( aOut.Left() + nWidth ); 3895 aOut.Bottom( rOutRect.Bottom() - nHeight ); 3896 if ( bTop ) 3897 aOut.Top( aOut.Top() + nHeight ); 3898 if ( bCnt && (!bBottom || !bTop) ) 3899 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 3900 aRegion.Insert( aOut, aRegion.Count() ); 3901 } 3902 3903 rOutRect.Left( rOutRect.Left() + nWidth ); 3904 rOutRect.Top( rOutRect.Top() + nHeight ); 3905 } 3906 break; 3907 case SVX_SHADOW_TOPRIGHT: 3908 { 3909 if ( bDrawFullShadowRectangle ) 3910 { 3911 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3912 aOut.Bottom( aOut.Bottom() - nHeight); 3913 aOut.Left( aOut.Left() + nWidth ); 3914 aRegion.Insert( aOut, aRegion.Count() ); 3915 } 3916 else 3917 { 3918 aOut.Bottom( aOut.Top() + nHeight ); 3919 aOut.Left ( aOut.Left()+ nWidth ); 3920 if ( bTop ) 3921 aRegion.Insert( aOut, aRegion.Count() ); 3922 aOut.Left ( aOut.Right() - nWidth ); 3923 aOut.Bottom( rOutRect.Bottom() - nHeight ); 3924 if ( bTop ) 3925 aOut.Top( aOut.Top() + nHeight ); 3926 if ( bCnt && (!bBottom || bTop) ) 3927 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 3928 aRegion.Insert( aOut, aRegion.Count() ); 3929 } 3930 3931 rOutRect.Right( rOutRect.Right() - nWidth ); 3932 rOutRect.Top( rOutRect.Top() + nHeight ); 3933 } 3934 break; 3935 case SVX_SHADOW_BOTTOMLEFT: 3936 { 3937 if ( bDrawFullShadowRectangle ) 3938 { 3939 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3940 aOut.Top( aOut.Top() + nHeight ); 3941 aOut.Right( aOut.Right() - nWidth ); 3942 aRegion.Insert( aOut, aRegion.Count() ); 3943 } 3944 else 3945 { 3946 aOut.Top ( aOut.Bottom()- nHeight ); 3947 aOut.Right( aOut.Right() - nWidth ); 3948 if ( bBottom ) 3949 aRegion.Insert( aOut, aRegion.Count() ); 3950 aOut.Right( aOut.Left() + nWidth ); 3951 aOut.Top( rOutRect.Top() + nHeight ); 3952 if ( bBottom ) 3953 aOut.Bottom( aOut.Bottom() - nHeight ); 3954 if ( bCnt && (!bTop || !bBottom) ) 3955 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 3956 aRegion.Insert( aOut, aRegion.Count() ); 3957 } 3958 3959 rOutRect.Left( rOutRect.Left() + nWidth ); 3960 rOutRect.Bottom( rOutRect.Bottom() - nHeight ); 3961 } 3962 break; 3963 default: 3964 ASSERT( !this, "new ShadowLocation() ?" ) 3965 break; 3966 } 3967 3968 OutputDevice *pOut = pGlobalShell->GetOut(); 3969 3970 sal_uLong nOldDrawMode = pOut->GetDrawMode(); 3971 Color aShadowColor( rShadow.GetColor() ); 3972 if( aRegion.Count() && pGlobalShell->GetWin() && 3973 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 3974 { 3975 // Is heigh contrast mode, the output device has already set the 3976 // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function 3977 // to ignore the setting of a new color. Therefore we have to reset 3978 // the drawing mode 3979 pOut->SetDrawMode( 0 ); 3980 aShadowColor = SwViewOption::GetFontColor(); 3981 } 3982 3983 if ( pOut->GetFillColor() != aShadowColor ) 3984 pOut->SetFillColor( aShadowColor ); 3985 3986 pOut->SetDrawMode( nOldDrawMode ); 3987 3988 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 3989 { 3990 SwRect &rOut = aRegion[i]; 3991 aOut = rOut; 3992 // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle 3993 // no alignment necessary, because (1) <rRect> is already aligned 3994 // and because (2) paint of border and background will occur later. 3995 // Thus, (1) assures that no conflicts with neighbour object will occure 3996 // and (2) assures that border and background is not affected by the 3997 // shadow paint. 3998 /* 3999 ::SwAlignRect( aOut, pGlobalShell ); 4000 */ 4001 if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 ) 4002 { 4003 aOut._Intersection( rRect ); 4004 pOut->DrawRect( aOut.SVRect() ); 4005 } 4006 } 4007 } 4008 4009 /************************************************************************* 4010 |* 4011 |* SwFrm::PaintBorderLine() 4012 |* 4013 |* Ersterstellung MA 22. Dec. 92 4014 |* Letzte Aenderung MA 22. Jan. 95 4015 |* 4016 |*************************************************************************/ 4017 4018 void SwFrm::PaintBorderLine( const SwRect& rRect, 4019 const SwRect& rOutRect, 4020 const SwPageFrm *pPage, 4021 const Color *pColor ) const 4022 { 4023 if ( !rOutRect.IsOver( rRect ) ) 4024 return; 4025 4026 SwRect aOut( rOutRect ); 4027 aOut._Intersection( rRect ); 4028 4029 const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0; 4030 sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB : 4031 ( IsInSct() ? SUBCOL_SECT : 4032 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) ); 4033 if( pColor && pGlobalShell->GetWin() && 4034 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 4035 { 4036 pColor = &SwViewOption::GetFontColor(); 4037 } 4038 4039 if ( pPage->GetSortedObjs() ) 4040 { 4041 SwRegionRects aRegion( aOut, 4, 1 ); 4042 ::lcl_SubtractFlys( this, pPage, aOut, aRegion ); 4043 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 4044 pLines->AddLineRect( aRegion[i], pColor, pTab, nSubCol ); 4045 } 4046 else 4047 pLines->AddLineRect( aOut, pColor, pTab, nSubCol ); 4048 } 4049 4050 /************************************************************************* 4051 |* 4052 |* SwFrm::PaintBorderLines() 4053 |* 4054 |* Beschreibung Nur alle Linien einfach oder alle Linien doppelt!!!! 4055 |* Ersterstellung MA 22. Dec. 92 4056 |* Letzte Aenderung MA 22. Mar. 95 4057 |* 4058 |*************************************************************************/ 4059 4060 // OD 29.04.2003 #107169# - method called for left and right border rectangles. 4061 // For a printer output device perform adjustment for non-overlapping top and 4062 // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate 4063 // printer output device. 4064 // NOTE: For printer output device left/right border rectangle <_iorRect> 4065 // has to be already non-overlapping the outer top/bottom border rectangle. 4066 void MA_FASTCALL lcl_SubTopBottom( SwRect& _iorRect, 4067 const SvxBoxItem& _rBox, 4068 const SwBorderAttrs& _rAttrs, 4069 const SwFrm& _rFrm, 4070 const SwRectFn& _rRectFn, 4071 const sal_Bool _bPrtOutputDev ) 4072 { 4073 const sal_Bool bCnt = _rFrm.IsCntntFrm(); 4074 if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() && 4075 ( !bCnt || _rAttrs.GetTopLine( _rFrm ) ) 4076 ) 4077 { 4078 // substract distance between outer and inner line. 4079 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() ); 4080 // OD 19.05.2003 #109667# - non-overlapping border rectangles: 4081 // adjust x-/y-position, if inner top line is a hair line (width = 1) 4082 sal_Bool bIsInnerTopLineHairline = sal_False; 4083 if ( !_bPrtOutputDev ) 4084 { 4085 // additionally substract width of top outer line 4086 // --> left/right inner/outer line doesn't overlap top outer line. 4087 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() ); 4088 } 4089 else 4090 { 4091 // OD 29.04.2003 #107169# - additionally substract width of top inner line 4092 // --> left/right inner/outer line doesn't overlap top inner line. 4093 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() ); 4094 bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1; 4095 } 4096 (_iorRect.*_rRectFn->fnSubTop)( -nDist ); 4097 // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line 4098 // is a hair line 4099 if ( bIsInnerTopLineHairline ) 4100 { 4101 if ( _rFrm.IsVertical() ) 4102 { 4103 // right of border rectangle has to be checked and adjusted 4104 Point aCompPt( _iorRect.Right(), 0 ); 4105 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() ); 4106 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4107 aRefPt, aCompPt, 4108 sal_True, -1 ); 4109 _iorRect.Right( aCompPt.X() ); 4110 } 4111 else 4112 { 4113 // top of border rectangle has to be checked and adjusted 4114 Point aCompPt( 0, _iorRect.Top() ); 4115 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 ); 4116 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4117 aRefPt, aCompPt, 4118 sal_False, +1 ); 4119 _iorRect.Top( aCompPt.Y() ); 4120 } 4121 } 4122 } 4123 4124 if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() && 4125 ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) ) 4126 ) 4127 { 4128 // substract distance between outer and inner line. 4129 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() ); 4130 // OD 19.05.2003 #109667# - non-overlapping border rectangles: 4131 // adjust x-/y-position, if inner bottom line is a hair line (width = 1) 4132 sal_Bool bIsInnerBottomLineHairline = sal_False; 4133 if ( !_bPrtOutputDev ) 4134 { 4135 // additionally substract width of bottom outer line 4136 // --> left/right inner/outer line doesn't overlap bottom outer line. 4137 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() ); 4138 } 4139 else 4140 { 4141 // OD 29.04.2003 #107169# - additionally substract width of bottom inner line 4142 // --> left/right inner/outer line doesn't overlap bottom inner line. 4143 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() ); 4144 bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1; 4145 } 4146 (_iorRect.*_rRectFn->fnAddBottom)( -nDist ); 4147 // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner 4148 // bottom line is a hair line. 4149 if ( bIsInnerBottomLineHairline ) 4150 { 4151 if ( _rFrm.IsVertical() ) 4152 { 4153 // left of border rectangle has to be checked and adjusted 4154 Point aCompPt( _iorRect.Left(), 0 ); 4155 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() ); 4156 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4157 aRefPt, aCompPt, 4158 sal_True, +1 ); 4159 _iorRect.Left( aCompPt.X() ); 4160 } 4161 else 4162 { 4163 // bottom of border rectangle has to be checked and adjusted 4164 Point aCompPt( 0, _iorRect.Bottom() ); 4165 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 ); 4166 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4167 aRefPt, aCompPt, 4168 sal_False, -1 ); 4169 _iorRect.Bottom( aCompPt.Y() ); 4170 } 4171 } 4172 } 4173 } 4174 4175 // method called for top and bottom border rectangles. 4176 void MA_FASTCALL lcl_SubLeftRight( SwRect& rRect, 4177 const SvxBoxItem& rBox, 4178 const SwRectFn& rRectFn ) 4179 { 4180 if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() ) 4181 { 4182 const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() ) 4183 + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() ); 4184 (rRect.*rRectFn->fnSubLeft)( -nDist ); 4185 } 4186 4187 if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() ) 4188 { 4189 const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() ) 4190 + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() ); 4191 (rRect.*rRectFn->fnAddRight)( -nDist ); 4192 } 4193 } 4194 4195 // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine> 4196 // into new method <lcl_PaintLeftRightLine(..)> 4197 void lcl_PaintLeftRightLine( const sal_Bool _bLeft, 4198 const SwFrm& _rFrm, 4199 const SwPageFrm& _rPage, 4200 const SwRect& _rOutRect, 4201 const SwRect& _rRect, 4202 const SwBorderAttrs& _rAttrs, 4203 const SwRectFn& _rRectFn ) 4204 { 4205 const SvxBoxItem& rBox = _rAttrs.GetBox(); 4206 const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft(); 4207 const SvxBorderLine* pLeftRightBorder = 0; 4208 if ( _bLeft ) 4209 { 4210 pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft(); 4211 } 4212 else 4213 { 4214 pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight(); 4215 } 4216 // OD 06.05.2003 #107169# - init boolean indicating printer output device. 4217 const sal_Bool bPrtOutputDev = 4218 ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() ); 4219 4220 if ( !pLeftRightBorder ) 4221 { 4222 return; 4223 } 4224 4225 SwRect aRect( _rOutRect ); 4226 if ( _bLeft ) 4227 { 4228 (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) - 4229 (aRect.*_rRectFn->fnGetWidth)() ); 4230 } 4231 else 4232 { 4233 (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) - 4234 (aRect.*_rRectFn->fnGetWidth)() ); 4235 } 4236 4237 const sal_Bool bCnt = _rFrm.IsCntntFrm(); 4238 4239 if ( bCnt ) 4240 { 4241 ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn ); 4242 } 4243 4244 // OD 06.05.2003 #107169# - adjustments for printer output device 4245 if ( bPrtOutputDev ) 4246 { 4247 // substract width of outer top line. 4248 if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) ) 4249 { 4250 long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() ); 4251 (aRect.*_rRectFn->fnSubTop)( -nDist ); 4252 // OD 19.05.2003 #109667# - If outer top line is hair line, calculated 4253 // top has to be adjusted. 4254 if ( nDist == 1 ) 4255 { 4256 if ( _rFrm.IsVertical() ) 4257 { 4258 // right of border rectangle has to be checked and adjusted 4259 Point aCompPt( aRect.Right(), 0 ); 4260 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() ); 4261 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4262 aRefPt, aCompPt, 4263 sal_True, -1 ); 4264 aRect.Right( aCompPt.X() ); 4265 } 4266 else 4267 { 4268 // top of border rectangle has to be checked and adjusted 4269 Point aCompPt( 0, aRect.Top() ); 4270 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 ); 4271 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4272 aRefPt, aCompPt, 4273 sal_False, +1 ); 4274 aRect.Top( aCompPt.Y() ); 4275 } 4276 } 4277 } 4278 // substract width of outer bottom line. 4279 if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) ) 4280 { 4281 long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth()); 4282 (aRect.*_rRectFn->fnAddBottom)( -nDist ); 4283 // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated 4284 // top has to be adjusted. 4285 if ( nDist == 1 ) 4286 { 4287 if ( _rFrm.IsVertical() ) 4288 { 4289 // left of border rectangle has to be checked and adjusted 4290 Point aCompPt( aRect.Left(), 0 ); 4291 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() ); 4292 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4293 aRefPt, aCompPt, 4294 sal_True, +1 ); 4295 aRect.Left( aCompPt.X() ); 4296 } 4297 else 4298 { 4299 // bottom of border rectangle has to be checked and adjusted 4300 Point aCompPt( 0, aRect.Bottom() ); 4301 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 ); 4302 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4303 aRefPt, aCompPt, 4304 sal_False, -1 ); 4305 aRect.Bottom( aCompPt.Y() ); 4306 } 4307 } 4308 } 4309 } 4310 4311 if ( !pLeftRightBorder->GetInWidth() ) 4312 { 4313 // OD 06.05.2003 #107169# - add 6th parameter 4314 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev ); 4315 } 4316 4317 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4318 { 4319 SwRect aPaintRect( aRect ); 4320 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4321 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle 4322 // to the prior left postion with width of one twip. 4323 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 ) 4324 { 4325 if ( _bLeft ) 4326 { 4327 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() ); 4328 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() ); 4329 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4330 } 4331 else 4332 { 4333 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4334 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4335 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4336 } 4337 } 4338 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() ); 4339 } 4340 4341 if ( pLeftRightBorder->GetInWidth() ) 4342 { 4343 const long nDist = ::lcl_MinWidthDist( pLeftRightBorder->GetDistance() ); 4344 long nWidth = ::lcl_AlignWidth( pLeftRightBorder->GetInWidth() ); 4345 if ( _bLeft ) 4346 { 4347 (aRect.*_rRectFn->fnAddRight)( nDist + nWidth ); 4348 (aRect.*_rRectFn->fnSubLeft)( nWidth - (aRect.*_rRectFn->fnGetWidth)() ); 4349 } 4350 else 4351 { 4352 (aRect.*_rRectFn->fnSubLeft)( nDist + nWidth ); 4353 (aRect.*_rRectFn->fnAddRight)( nWidth - (aRect.*_rRectFn->fnGetWidth)() ); 4354 } 4355 // OD 06.05.2003 #107169# - add 6th parameter 4356 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev ); 4357 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4358 { 4359 SwRect aPaintRect( aRect ); 4360 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4361 // if <SwAlignRect> reveals rectangle with no width, adjust 4362 // rectangle to the prior left postion with width of one twip. 4363 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 ) 4364 { 4365 if ( _bLeft ) 4366 { 4367 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() ); 4368 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() ); 4369 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4370 } 4371 else 4372 { 4373 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4374 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4375 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4376 } 4377 } 4378 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() ); 4379 } 4380 } 4381 } 4382 4383 // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine> 4384 // into <lcl_PaintTopLine> 4385 void lcl_PaintTopBottomLine( const sal_Bool _bTop, 4386 const SwFrm& _rFrm, 4387 const SwPageFrm& _rPage, 4388 const SwRect& _rOutRect, 4389 const SwRect& _rRect, 4390 const SwBorderAttrs& _rAttrs, 4391 const SwRectFn& _rRectFn ) 4392 { 4393 const SvxBoxItem& rBox = _rAttrs.GetBox(); 4394 const SvxBorderLine* pTopBottomBorder = 0; 4395 if ( _bTop ) 4396 { 4397 pTopBottomBorder = rBox.GetTop(); 4398 } 4399 else 4400 { 4401 pTopBottomBorder = rBox.GetBottom(); 4402 } 4403 4404 if ( !pTopBottomBorder ) 4405 { 4406 return; 4407 } 4408 4409 SwRect aRect( _rOutRect ); 4410 if ( _bTop ) 4411 { 4412 (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) - 4413 (aRect.*_rRectFn->fnGetHeight)() ); 4414 } 4415 else 4416 { 4417 (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) - 4418 (aRect.*_rRectFn->fnGetHeight)() ); 4419 } 4420 4421 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4422 { 4423 SwRect aPaintRect( aRect ); 4424 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4425 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle 4426 // to the prior top postion with width of one twip. 4427 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 ) 4428 { 4429 if ( _bTop ) 4430 { 4431 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() ); 4432 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() ); 4433 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4434 } 4435 else 4436 { 4437 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4438 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4439 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4440 } 4441 } 4442 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() ); 4443 } 4444 4445 if ( pTopBottomBorder->GetInWidth() ) 4446 { 4447 const long nDist = ::lcl_MinHeightDist( pTopBottomBorder->GetDistance() ); 4448 const long nHeight = ::lcl_AlignHeight( pTopBottomBorder->GetInWidth() ); 4449 if ( _bTop ) 4450 { 4451 (aRect.*_rRectFn->fnAddBottom)( nDist + nHeight ); 4452 (aRect.*_rRectFn->fnSubTop)( nHeight - (aRect.*_rRectFn->fnGetHeight)() ); 4453 } 4454 else 4455 { 4456 (aRect.*_rRectFn->fnSubTop)( nDist + nHeight ); 4457 (aRect.*_rRectFn->fnAddBottom)( nHeight -(aRect.*_rRectFn->fnGetHeight)() ); 4458 } 4459 ::lcl_SubLeftRight( aRect, rBox, _rRectFn ); 4460 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4461 { 4462 SwRect aPaintRect( aRect ); 4463 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4464 // if <SwAlignRect> reveals rectangle with no width, adjust 4465 // rectangle to the prior top postion with width of one twip. 4466 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 ) 4467 { 4468 if ( _bTop ) 4469 { 4470 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() ); 4471 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() ); 4472 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4473 } 4474 else 4475 { 4476 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4477 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4478 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4479 } 4480 } 4481 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() ); 4482 } 4483 } 4484 } 4485 4486 4487 /************************************************************************* 4488 |* 4489 |* const SwFrm* lcl_HasNextCell( const SwFrm& rFrm ) 4490 |* 4491 |* No comment. #i15844# 4492 |* 4493 |*************************************************************************/ 4494 4495 const SwFrm* lcl_HasNextCell( const SwFrm& rFrm ) 4496 { 4497 ASSERT( rFrm.IsCellFrm(), 4498 "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" ) 4499 4500 const SwFrm* pTmpFrm = &rFrm; 4501 do 4502 { 4503 if ( pTmpFrm->GetNext() ) 4504 return pTmpFrm->GetNext(); 4505 4506 pTmpFrm = pTmpFrm->GetUpper()->GetUpper(); 4507 } 4508 while ( pTmpFrm->IsCellFrm() ); 4509 4510 return 0; 4511 } 4512 4513 4514 /************************************************************************* 4515 |* 4516 |* SwFrm::PaintBorder() 4517 |* 4518 |* Beschreibung Malt Schatten und Umrandung 4519 |* Ersterstellung MA 23.01.92 4520 |* Letzte Aenderung MA 29. Jul. 96 4521 |* 4522 |*************************************************************************/ 4523 4524 /** local method to determine cell frame, from which the border attributes 4525 for paint of top/bottom border has to be used. 4526 4527 OD 21.02.2003 #b4779636#, #107692# 4528 4529 @author OD 4530 4531 4532 @param _pCellFrm 4533 input parameter - constant pointer to cell frame for which the cell frame 4534 for the border attributes has to be determined. 4535 4536 @param _rCellBorderAttrs 4537 input parameter - constant reference to the border attributes of cell frame 4538 <_pCellFrm>. 4539 4540 @param _bTop 4541 input parameter - boolean, that controls, if cell frame for top border or 4542 for bottom border has to be determined. 4543 4544 @return constant pointer to cell frame, for which the border attributes has 4545 to be used 4546 */ 4547 const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm* _pCellFrm, 4548 const SwBorderAttrs& _rCellBorderAttrs, 4549 const bool _bTop ) 4550 { 4551 ASSERT( _pCellFrm, "No cell frame available, dying soon" ) 4552 4553 // determine, if cell frame is at bottom/top border of a table frame and 4554 // the table frame has/is a follow. 4555 const SwFrm* pTmpFrm = _pCellFrm; 4556 bool bCellAtBorder = true; 4557 bool bCellAtLeftBorder = !_pCellFrm->GetPrev(); 4558 bool bCellAtRightBorder = !_pCellFrm->GetNext(); 4559 while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() ) 4560 { 4561 pTmpFrm = pTmpFrm->GetUpper(); 4562 if ( pTmpFrm->IsRowFrm() && 4563 (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext()) 4564 ) 4565 { 4566 bCellAtBorder = false; 4567 } 4568 if ( pTmpFrm->IsCellFrm() ) 4569 { 4570 if ( pTmpFrm->GetPrev() ) 4571 { 4572 bCellAtLeftBorder = false; 4573 } 4574 if ( pTmpFrm->GetNext() ) 4575 { 4576 bCellAtRightBorder = false; 4577 } 4578 } 4579 } 4580 ASSERT( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" ); 4581 4582 const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm); 4583 const SwTabFrm* pParentTabFrm = 4584 static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper()); 4585 4586 const bool bCellNeedsAttribute = bCellAtBorder && 4587 ( _bTop ? 4588 // bCellInFirstRowWithMaster 4589 ( !pParentRowFrm->GetPrev() && 4590 pParentTabFrm->IsFollow() && 4591 0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) : 4592 // bCellInLastRowWithFollow 4593 ( !pParentRowFrm->GetNext() && 4594 pParentTabFrm->GetFollow() ) 4595 ); 4596 4597 const SwFrm* pRet = _pCellFrm; 4598 if ( bCellNeedsAttribute ) 4599 { 4600 // determine, if cell frame has no borders inside the table. 4601 const SwFrm* pNextCell = 0; 4602 bool bNoBordersInside = false; 4603 4604 if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) ) 4605 { 4606 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell ); 4607 const SwBorderAttrs &rBorderAttrs = *aAccess.Get(); 4608 const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox(); 4609 bCellAtRightBorder = !lcl_HasNextCell( *pNextCell ); 4610 bNoBordersInside = 4611 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) && 4612 !rBorderBox.GetLeft() && 4613 ( !rBorderBox.GetRight() || bCellAtRightBorder ) && 4614 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() ); 4615 } 4616 else 4617 { 4618 const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox(); 4619 bNoBordersInside = 4620 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) && 4621 ( !rBorderBox.GetLeft() || bCellAtLeftBorder ) && 4622 ( !rBorderBox.GetRight() || bCellAtRightBorder ) && 4623 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() ); 4624 } 4625 4626 if ( bNoBordersInside ) 4627 { 4628 if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() ) 4629 { 4630 // #b4779636#-hack: 4631 // Cell frame has no top border and no border inside the table, but 4632 // it is at the top border of a table frame, which is a follow. 4633 // Thus, use border attributes of cell frame in first row of complete table. 4634 // First, determine first table frame of complete table. 4635 SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true ); 4636 // determine first row of complete table. 4637 const SwFrm* pFirstRow = pMasterTabFrm->GetLower(); 4638 // return first cell in first row 4639 SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower()); 4640 while ( !pLowerCell->IsCellFrm() || 4641 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() ) 4642 ) 4643 { 4644 pLowerCell = pLowerCell->GetLower(); 4645 } 4646 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" ); 4647 pRet = pLowerCell; 4648 } 4649 else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() ) 4650 { 4651 // #b4779636#-hack: 4652 // Cell frame has no bottom border and no border inside the table, 4653 // but it is at the bottom border of a table frame, which has a follow. 4654 // Thus, use border attributes of cell frame in last row of complete table. 4655 // First, determine last table frame of complete table. 4656 SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow()); 4657 while ( pLastTabFrm->GetFollow() ) 4658 { 4659 pLastTabFrm = pLastTabFrm->GetFollow(); 4660 } 4661 // determine last row of complete table. 4662 SwFrm* pLastRow = pLastTabFrm->GetLastLower(); 4663 // return first bottom border cell in last row 4664 SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower()); 4665 while ( !pLowerCell->IsCellFrm() || 4666 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() ) 4667 ) 4668 { 4669 if ( pLowerCell->IsRowFrm() ) 4670 { 4671 while ( pLowerCell->GetNext() ) 4672 { 4673 pLowerCell = pLowerCell->GetNext(); 4674 } 4675 } 4676 pLowerCell = pLowerCell->GetLower(); 4677 } 4678 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" ); 4679 pRet = pLowerCell; 4680 } 4681 } 4682 } 4683 4684 return pRet; 4685 } 4686 4687 void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage, 4688 const SwBorderAttrs &rAttrs ) const 4689 { 4690 //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun 4691 if ( (GetType() & 0x90C5) || (Prt().SSize() == Frm().SSize()) ) 4692 return; 4693 4694 if ( (GetType() & 0x2000) && //Cell 4695 !pGlobalShell->GetViewOptions()->IsTable() ) 4696 return; 4697 4698 // --> collapsing borders FME 2005-05-27 #i29550# 4699 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() ) 4700 { 4701 const SwTabFrm* pTabFrm = FindTabFrm(); 4702 if ( pTabFrm->IsCollapsingBorders() ) 4703 return; 4704 4705 if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) ) 4706 return; 4707 } 4708 // <-- 4709 4710 const bool bLine = rAttrs.IsLine() ? true : false; 4711 const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE; 4712 4713 // OD 24.02.2003 #b4779636#, #107692# - flag to control, 4714 // if #b4779636#-hack has to be used. 4715 const bool bb4779636HackActive = true; 4716 // OD 21.02.2003 #b4779636#, #107692# 4717 const SwFrm* pCellFrmForBottomBorderAttrs = 0; 4718 const SwFrm* pCellFrmForTopBorderAttrs = 0; 4719 bool bFoundCellForTopOrBorderAttrs = false; 4720 if ( bb4779636HackActive && IsCellFrm() ) 4721 { 4722 pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false ); 4723 if ( pCellFrmForBottomBorderAttrs != this ) 4724 bFoundCellForTopOrBorderAttrs = true; 4725 pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true ); 4726 if ( pCellFrmForTopBorderAttrs != this ) 4727 bFoundCellForTopOrBorderAttrs = true; 4728 } 4729 4730 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs> 4731 // for #b4779636#-hack 4732 if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs ) 4733 { 4734 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, 4735 //so braucht kein Rand gepainted werden. 4736 //Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden, 4737 //anderfalls wuerden u.U. Teile nicht verarbeitet. 4738 SwRect aRect( Prt() ); 4739 aRect += Frm().Pos(); 4740 ::SwAlignRect( aRect, pGlobalShell ); 4741 // OD 27.09.2002 #103636# - new local boolean variable in order to 4742 // suspend border paint under special cases - see below. 4743 // NOTE: This is a fix for the implementation of feature #99657#. 4744 bool bDrawOnlyShadowForTransparentFrame = false; 4745 if ( aRect.IsInside( rRect ) ) 4746 { 4747 // OD 27.09.2002 #103636# - paint shadow, if background is transparent. 4748 // Because of introduced transparent background for fly frame #99657#, 4749 // the shadow have to be drawn if the background is transparent, 4750 // in spite the fact that the paint rectangle <rRect> lies fully 4751 // in the printing area. 4752 // NOTE to chosen solution: 4753 // On transparent background, continue processing, but suspend 4754 // drawing of border by setting <bDrawOnlyShadowForTransparentFrame> 4755 // to true. 4756 if ( IsLayoutFrm() && 4757 static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() ) 4758 { 4759 bDrawOnlyShadowForTransparentFrame = true; 4760 } 4761 else 4762 { 4763 return; 4764 } 4765 } 4766 4767 if ( !pPage ) 4768 pPage = FindPageFrm(); 4769 4770 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True ); 4771 rAttrs.SetGetCacheLine( sal_True ); 4772 if ( bShadow ) 4773 PaintShadow( rRect, aRect, rAttrs ); 4774 // OD 27.09.2002 #103636# - suspend drawing of border 4775 // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above 4776 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs> 4777 // for #b4779636#-hack. 4778 if ( ( bLine || bFoundCellForTopOrBorderAttrs ) && 4779 !bDrawOnlyShadowForTransparentFrame ) 4780 { 4781 const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this; 4782 SWRECTFN( pDirRefFrm ) 4783 // OD 19.05.2003 #109667# - use new method <lcl_PaintLeftRightLine(..)> 4784 //::lcl_PaintLeftLine ( this, pPage, aRect, rRect, rAttrs, fnRect ); 4785 //::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs, fnRect ); 4786 ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4787 ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4788 if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) ) 4789 { 4790 // OD 21.02.2003 #b4779636#, #107692# - 4791 // #b4779636#-hack: If another cell frame for top border 4792 // paint is found, paint its top border. 4793 if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this ) 4794 { 4795 SwBorderAttrAccess aAccess( SwFrm::GetCache(), 4796 pCellFrmForTopBorderAttrs ); 4797 const SwBorderAttrs &rTopAttrs = *aAccess.Get(); 4798 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4799 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rTopAttrs, fnRect ); 4800 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect ); 4801 } 4802 else 4803 { 4804 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4805 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs, fnRect ); 4806 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4807 } 4808 } 4809 if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) ) 4810 { 4811 // OD 21.02.2003 #b4779636#, #107692# - 4812 // #b4779636#-hack: If another cell frame for bottom border 4813 // paint is found, paint its bottom border. 4814 if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this ) 4815 { 4816 SwBorderAttrAccess aAccess( SwFrm::GetCache(), 4817 pCellFrmForBottomBorderAttrs ); 4818 const SwBorderAttrs &rBottomAttrs = *aAccess.Get(); 4819 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4820 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rBottomAttrs, fnRect); 4821 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect); 4822 } 4823 else 4824 { 4825 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4826 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rAttrs, fnRect); 4827 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect); 4828 } 4829 } 4830 } 4831 rAttrs.SetGetCacheLine( sal_False ); 4832 } 4833 } 4834 /************************************************************************* 4835 |* 4836 |* SwFtnContFrm::PaintBorder() 4837 |* 4838 |* Beschreibung Spezialimplementierung wg. der Fussnotenlinie. 4839 |* Derzeit braucht nur der obere Rand beruecksichtigt werden. 4840 |* Auf andere Linien und Schatten wird verzichtet. 4841 |* Ersterstellung MA 27. Feb. 93 4842 |* Letzte Aenderung MA 08. Sep. 93 4843 |* 4844 |*************************************************************************/ 4845 4846 void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage, 4847 const SwBorderAttrs & ) const 4848 { 4849 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es 4850 //keinen Rand zu painten. 4851 SwRect aRect( Prt() ); 4852 aRect.Pos() += Frm().Pos(); 4853 if ( !aRect.IsInside( rRect ) ) 4854 PaintLine( rRect, pPage ); 4855 } 4856 /************************************************************************* 4857 |* 4858 |* SwFtnContFrm::PaintLine() 4859 |* 4860 |* Beschreibung Fussnotenline malen. 4861 |* Ersterstellung MA 02. Mar. 93 4862 |* Letzte Aenderung MA 28. Mar. 94 4863 |* 4864 |*************************************************************************/ 4865 4866 void SwFtnContFrm::PaintLine( const SwRect& rRect, 4867 const SwPageFrm *pPage ) const 4868 { 4869 //Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc. 4870 //Die Position ist ebenfalls am PageDesc angegeben. 4871 //Der Pen steht direkt im PageDesc. 4872 4873 if ( !pPage ) 4874 pPage = FindPageFrm(); 4875 const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo(); 4876 4877 SWRECTFN( this ) 4878 SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)(); 4879 Fraction aFract( nPrtWidth, 1 ); 4880 const SwTwips nWidth = (long)(aFract *= rInf.GetWidth()); 4881 4882 SwTwips nX = (this->*fnRect->fnGetPrtLeft)(); 4883 switch ( rInf.GetAdj() ) 4884 { 4885 case FTNADJ_CENTER: 4886 nX += nPrtWidth/2 - nWidth/2; break; 4887 case FTNADJ_RIGHT: 4888 nX += nPrtWidth - nWidth; break; 4889 case FTNADJ_LEFT: 4890 /* do nothing */; break; 4891 default: 4892 ASSERT( !this, "Neues Adjustment fuer Fussnotenlinie?" ); 4893 } 4894 SwTwips nLineWidth = rInf.GetLineWidth(); 4895 const SwRect aLineRect = bVert ? 4896 SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth, 4897 nX), Size( nLineWidth, nWidth ) ) 4898 : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ), 4899 Size( nWidth, rInf.GetLineWidth())); 4900 if ( aLineRect.HasArea() ) 4901 PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() ); 4902 } 4903 4904 /************************************************************************* 4905 |* 4906 |* SwLayoutFrm::PaintColLines() 4907 |* 4908 |* Beschreibung Painted die Trennlinien fuer die innenliegenden 4909 |* Spalten. 4910 |* Ersterstellung MA 21. Jun. 93 4911 |* Letzte Aenderung MA 28. Mar. 94 4912 |* 4913 |*************************************************************************/ 4914 4915 void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol, 4916 const SwPageFrm *pPage ) const 4917 { 4918 const SwFrm *pCol = Lower(); 4919 if ( !pCol || !pCol->IsColumnFrm() ) 4920 return; 4921 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 4922 SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 4923 4924 SwRect aLineRect = Prt(); 4925 aLineRect += Frm().Pos(); 4926 4927 SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight()) 4928 / 100 - (aLineRect.*fnRect->fnGetHeight)(); 4929 SwTwips nBottom = 0; 4930 4931 switch ( rFmtCol.GetLineAdj() ) 4932 { 4933 case COLADJ_CENTER: 4934 nBottom = nTop / 2; nTop -= nBottom; break; 4935 case COLADJ_TOP: 4936 nBottom = nTop; nTop = 0; break; 4937 case COLADJ_BOTTOM: 4938 break; 4939 default: 4940 ASSERT( !this, "Neues Adjustment fuer Spaltenlinie?" ); 4941 } 4942 4943 if( nTop ) 4944 (aLineRect.*fnRect->fnSubTop)( nTop ); 4945 if( nBottom ) 4946 (aLineRect.*fnRect->fnAddBottom)( nBottom ); 4947 4948 SwTwips nPenHalf = rFmtCol.GetLineWidth(); 4949 (aLineRect.*fnRect->fnSetWidth)( nPenHalf ); 4950 nPenHalf /= 2; 4951 4952 //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein. 4953 SwRect aRect( rRect ); 4954 (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW ); 4955 (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW ); 4956 SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight; 4957 while ( pCol->GetNext() ) 4958 { 4959 (aLineRect.*fnRect->fnSetPosX) 4960 ( (pCol->Frm().*fnGetX)() - nPenHalf ); 4961 if ( aRect.IsOver( aLineRect ) ) 4962 PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor()); 4963 pCol = pCol->GetNext(); 4964 } 4965 } 4966 4967 void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const 4968 { 4969 if( !bHasGrid || pRetoucheFly || pRetoucheFly2 ) 4970 return; 4971 GETGRID( this ) 4972 if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ? 4973 pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) ) 4974 { 4975 const SwLayoutFrm* pBody = FindBodyCont(); 4976 if( pBody ) 4977 { 4978 SwRect aGrid( pBody->Prt() ); 4979 aGrid += pBody->Frm().Pos(); 4980 4981 SwRect aInter( aGrid ); 4982 aInter.Intersection( rRect ); 4983 if( aInter.HasArea() ) 4984 { 4985 sal_Bool bGrid = pGrid->GetRubyTextBelow(); 4986 sal_Bool bCell = GRID_LINES_CHARS == pGrid->GetGridType(); 4987 long nGrid = pGrid->GetBaseHeight(); 4988 const SwDoc* pDoc = GetFmt()->GetDoc(); 4989 long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor 4990 long nRuby = pGrid->GetRubyHeight(); 4991 long nSum = nGrid + nRuby; 4992 const Color *pCol = &pGrid->GetColor(); 4993 4994 SwTwips nRight = aInter.Left() + aInter.Width(); 4995 SwTwips nBottom = aInter.Top() + aInter.Height(); 4996 if( IsVertical() ) 4997 { 4998 SwTwips nOrig = aGrid.Left() + aGrid.Width(); 4999 SwTwips nY = nOrig + nSum * 5000 ( ( nOrig - aInter.Left() ) / nSum ); 5001 SwRect aTmp( Point( nY, aInter.Top() ), 5002 Size( 1, aInter.Height() ) ); 5003 SwTwips nX = aGrid.Top() + nGrid * 5004 ( ( aInter.Top() - aGrid.Top() )/ nGrid ); 5005 if( nX < aInter.Top() ) 5006 nX += nGrid; 5007 SwTwips nGridBottom = aGrid.Top() + aGrid.Height(); 5008 sal_Bool bLeft = aGrid.Top() >= aInter.Top(); 5009 sal_Bool bRight = nGridBottom <= nBottom; 5010 sal_Bool bBorder = bLeft || bRight; 5011 while( nY > nRight ) 5012 { 5013 aTmp.Pos().X() = nY; 5014 if( bGrid ) 5015 { 5016 nY -= nGrid; 5017 SwTwips nPosY = Max( aInter.Left(), nY ); 5018 SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY; 5019 if( nHeight > 0 ) 5020 { 5021 if( bCell ) 5022 { 5023 SwRect aVert( Point( nPosY, nX ), 5024 Size( nHeight, 1 ) ); 5025 while( aVert.Top() <= nBottom ) 5026 { 5027 PaintBorderLine(rRect,aVert,this,pCol); 5028 aVert.Pos().Y() += nGrid; 5029 } 5030 } 5031 else if( bBorder ) 5032 { 5033 SwRect aVert( Point( nPosY, aGrid.Top() ), 5034 Size( nHeight, 1 ) ); 5035 if( bLeft ) 5036 PaintBorderLine(rRect,aVert,this,pCol); 5037 if( bRight ) 5038 { 5039 aVert.Pos().Y() = nGridBottom; 5040 PaintBorderLine(rRect,aVert,this,pCol); 5041 } 5042 } 5043 } 5044 } 5045 else 5046 { 5047 nY -= nRuby; 5048 if( bBorder ) 5049 { 5050 SwTwips nPos = Max( aInter.Left(), nY ); 5051 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos; 5052 SwRect aVert( Point( nPos, aGrid.Top() ), 5053 Size( nW, 1 ) ); 5054 if( nW > 0 ) 5055 { 5056 if( bLeft ) 5057 PaintBorderLine(rRect,aVert,this,pCol); 5058 if( bRight ) 5059 { 5060 aVert.Pos().Y() = nGridBottom; 5061 PaintBorderLine(rRect,aVert,this,pCol); 5062 } 5063 } 5064 } 5065 } 5066 bGrid = !bGrid; 5067 } 5068 while( nY >= aInter.Left() ) 5069 { 5070 aTmp.Pos().X() = nY; 5071 PaintBorderLine( rRect, aTmp, this, pCol); 5072 if( bGrid ) 5073 { 5074 nY -= nGrid; 5075 SwTwips nHeight = aTmp.Pos().X() 5076 - Max(aInter.Left(), nY ); 5077 if( nHeight > 0 ) 5078 { 5079 if( bCell ) 5080 { 5081 SwRect aVert( Point(aTmp.Pos().X()-nHeight, 5082 nX ), Size( nHeight, 1 ) ); 5083 while( aVert.Top() <= nBottom ) 5084 { 5085 PaintBorderLine(rRect,aVert,this,pCol); 5086 aVert.Pos().Y() += nGrid; 5087 } 5088 } 5089 else if( bBorder ) 5090 { 5091 SwRect aVert( Point(aTmp.Pos().X()-nHeight, 5092 aGrid.Top() ), Size( nHeight, 1 ) ); 5093 if( bLeft ) 5094 PaintBorderLine(rRect,aVert,this,pCol); 5095 if( bRight ) 5096 { 5097 aVert.Pos().Y() = nGridBottom; 5098 PaintBorderLine(rRect,aVert,this,pCol); 5099 } 5100 } 5101 } 5102 } 5103 else 5104 { 5105 nY -= nRuby; 5106 if( bBorder ) 5107 { 5108 SwTwips nPos = Max( aInter.Left(), nY ); 5109 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos; 5110 SwRect aVert( Point( nPos, aGrid.Top() ), 5111 Size( nW, 1 ) ); 5112 if( nW > 0 ) 5113 { 5114 if( bLeft ) 5115 PaintBorderLine(rRect,aVert,this,pCol); 5116 if( bRight ) 5117 { 5118 aVert.Pos().Y() = nGridBottom; 5119 PaintBorderLine(rRect,aVert,this,pCol); 5120 } 5121 } 5122 } 5123 } 5124 bGrid = !bGrid; 5125 } 5126 } 5127 else 5128 { 5129 SwTwips nOrig = aGrid.Top(); 5130 SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum ); 5131 SwRect aTmp( Point( aInter.Left(), nY ), 5132 Size( aInter.Width(), 1 ) ); 5133 //for textgrid refactor 5134 SwTwips nX = aGrid.Left() + nGridWidth * 5135 ( ( aInter.Left() - aGrid.Left() )/ nGridWidth ); 5136 if( nX < aInter.Left() ) 5137 nX += nGridWidth; 5138 SwTwips nGridRight = aGrid.Left() + aGrid.Width(); 5139 sal_Bool bLeft = aGrid.Left() >= aInter.Left(); 5140 sal_Bool bRight = nGridRight <= nRight; 5141 sal_Bool bBorder = bLeft || bRight; 5142 while( nY < aInter.Top() ) 5143 { 5144 aTmp.Pos().Y() = nY; 5145 if( bGrid ) 5146 { 5147 nY += nGrid; 5148 SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() ); 5149 SwTwips nHeight = Min(nBottom, nY ) - nPosY; 5150 if( nHeight ) 5151 { 5152 if( bCell ) 5153 { 5154 SwRect aVert( Point( nX, nPosY ), 5155 Size( 1, nHeight ) ); 5156 while( aVert.Left() <= nRight ) 5157 { 5158 PaintBorderLine(rRect,aVert,this,pCol); 5159 aVert.Pos().X() += nGridWidth; //for textgrid refactor 5160 } 5161 } 5162 else if ( bBorder ) 5163 { 5164 SwRect aVert( Point( aGrid.Left(), nPosY ), 5165 Size( 1, nHeight ) ); 5166 if( bLeft ) 5167 PaintBorderLine(rRect,aVert,this,pCol); 5168 if( bRight ) 5169 { 5170 aVert.Pos().X() = nGridRight; 5171 PaintBorderLine(rRect,aVert,this,pCol); 5172 } 5173 } 5174 } 5175 } 5176 else 5177 { 5178 nY += nRuby; 5179 if( bBorder ) 5180 { 5181 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y()); 5182 SwTwips nH = Min( nBottom, nY ) - nPos; 5183 SwRect aVert( Point( aGrid.Left(), nPos ), 5184 Size( 1, nH ) ); 5185 if( nH > 0 ) 5186 { 5187 if( bLeft ) 5188 PaintBorderLine(rRect,aVert,this,pCol); 5189 if( bRight ) 5190 { 5191 aVert.Pos().X() = nGridRight; 5192 PaintBorderLine(rRect,aVert,this,pCol); 5193 } 5194 } 5195 } 5196 } 5197 bGrid = !bGrid; 5198 } 5199 while( nY <= nBottom ) 5200 { 5201 aTmp.Pos().Y() = nY; 5202 PaintBorderLine( rRect, aTmp, this, pCol); 5203 if( bGrid ) 5204 { 5205 nY += nGrid; 5206 SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y(); 5207 if( nHeight ) 5208 { 5209 if( bCell ) 5210 { 5211 SwRect aVert( Point( nX, aTmp.Pos().Y() ), 5212 Size( 1, nHeight ) ); 5213 while( aVert.Left() <= nRight ) 5214 { 5215 PaintBorderLine( rRect, aVert, this, pCol); 5216 aVert.Pos().X() += nGridWidth; //for textgrid refactor 5217 } 5218 } 5219 else if( bBorder ) 5220 { 5221 SwRect aVert( Point( aGrid.Left(), 5222 aTmp.Pos().Y() ), Size( 1, nHeight ) ); 5223 if( bLeft ) 5224 PaintBorderLine(rRect,aVert,this,pCol); 5225 if( bRight ) 5226 { 5227 aVert.Pos().X() = nGridRight; 5228 PaintBorderLine(rRect,aVert,this,pCol); 5229 } 5230 } 5231 } 5232 } 5233 else 5234 { 5235 nY += nRuby; 5236 if( bBorder ) 5237 { 5238 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y()); 5239 SwTwips nH = Min( nBottom, nY ) - nPos; 5240 SwRect aVert( Point( aGrid.Left(), nPos ), 5241 Size( 1, nH ) ); 5242 if( nH > 0 ) 5243 { 5244 if( bLeft ) 5245 PaintBorderLine(rRect,aVert,this,pCol); 5246 if( bRight ) 5247 { 5248 aVert.Pos().X() = nGridRight; 5249 PaintBorderLine(rRect,aVert,this,pCol); 5250 } 5251 } 5252 } 5253 } 5254 bGrid = !bGrid; 5255 } 5256 } 5257 } 5258 } 5259 } 5260 } 5261 5262 /** paint margin area of a page 5263 5264 OD 20.11.2002 for #104598#: 5265 implement paint of margin area; margin area will be painted for a 5266 view shell with a window and if the document is not in online layout. 5267 5268 @author OD 5269 5270 @param _rOutputRect 5271 input parameter - constant instance reference of the rectangle, for 5272 which an output has to be generated. 5273 5274 @param _pViewShell 5275 input parameter - instance of the view shell, on which the output 5276 has to be generated. 5277 */ 5278 void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect, 5279 ViewShell* _pViewShell ) const 5280 { 5281 if ( _pViewShell->GetWin() && 5282 !_pViewShell->GetViewOptions()->getBrowseMode() ) 5283 { 5284 SwRect aPgPrtRect( Prt() ); 5285 aPgPrtRect.Pos() += Frm().Pos(); 5286 if ( !aPgPrtRect.IsInside( _rOutputRect ) ) 5287 { 5288 SwRect aPgRect = Frm(); 5289 aPgRect._Intersection( _rOutputRect ); 5290 SwRegionRects aPgRegion( aPgRect ); 5291 aPgRegion -= aPgPrtRect; 5292 const SwPageFrm* pPage = static_cast<const SwPageFrm*>(this); 5293 if ( pPage->GetSortedObjs() ) 5294 ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion ); 5295 if ( aPgRegion.Count() ) 5296 { 5297 OutputDevice *pOut = _pViewShell->GetOut(); 5298 if ( pOut->GetFillColor() != aGlobalRetoucheColor ) 5299 pOut->SetFillColor( aGlobalRetoucheColor ); 5300 for ( sal_uInt16 i = 0; i < aPgRegion.Count(); ++i ) 5301 { 5302 if ( 1 < aPgRegion.Count() ) 5303 { 5304 ::SwAlignRect( aPgRegion[i], pGlobalShell ); 5305 if( !aPgRegion[i].HasArea() ) 5306 continue; 5307 } 5308 pOut->DrawRect(aPgRegion[i].SVRect()); 5309 } 5310 } 5311 } 5312 } 5313 } 5314 5315 // ---------------------------------------------------------------------- 5316 // 5317 // const SwPageFrm::mnBorderPxWidth, const SwPageFrm::mnShadowPxWidth 5318 // SwPageFrm::GetBorderRect (..), SwPageFrm::GetRightShadowRect(..), 5319 // SwPageFrm::GetBottomShadowRect(..), 5320 // SwPageFrm::PaintBorderAndShadow(..), 5321 // SwPageFrm::GetBorderAndShadowBoundRect(..) 5322 // 5323 // OD 12.02.2003 for #i9719# and #105645# 5324 // ---------------------------------------------------------------------- 5325 5326 const sal_Int8 SwPageFrm::mnBorderPxWidth = 1; 5327 const sal_Int8 SwPageFrm::mnShadowPxWidth = 2; 5328 5329 /** determine rectangle for page border 5330 5331 OD 12.02.2003 for #i9719# and #105645# 5332 5333 @author OD 5334 */ 5335 /*static*/ void SwPageFrm::GetBorderRect( const SwRect& _rPageRect, 5336 ViewShell* _pViewShell, 5337 SwRect& _orBorderRect, 5338 bool bRightSidebar ) 5339 { 5340 SwRect aAlignedPageRect( _rPageRect ); 5341 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5342 Rectangle aBorderPxRect = 5343 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5344 5345 aBorderPxRect.Left() = aBorderPxRect.Left() - mnBorderPxWidth; 5346 aBorderPxRect.Top() = aBorderPxRect.Top() - mnBorderPxWidth; 5347 aBorderPxRect.Right() = aBorderPxRect.Right() + mnBorderPxWidth; 5348 aBorderPxRect.Bottom() = aBorderPxRect.Bottom() + mnBorderPxWidth; 5349 5350 AddSidebarBorders(aBorderPxRect,_pViewShell, bRightSidebar, true); 5351 5352 _orBorderRect = 5353 SwRect( _pViewShell->GetOut()->PixelToLogic( aBorderPxRect ) ); 5354 } 5355 5356 /** determine rectangle for right page shadow 5357 5358 OD 12.02.2003 for #i9719# and #105645# 5359 5360 @author OD 5361 */ 5362 /*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect, 5363 ViewShell* _pViewShell, 5364 SwRect& _orRightShadowRect, 5365 bool bRightSidebar ) 5366 { 5367 SwRect aAlignedPageRect( _rPageRect ); 5368 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5369 Rectangle aPagePxRect = 5370 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5371 5372 Rectangle aRightShadowPxRect( 5373 aPagePxRect.Right() + mnShadowPxWidth, 5374 aPagePxRect.Top() + 1, 5375 aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth, 5376 aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth ); 5377 5378 if ( bRightSidebar ) 5379 AddSidebarBorders(aRightShadowPxRect,_pViewShell, bRightSidebar, true); 5380 5381 _orRightShadowRect = 5382 SwRect( _pViewShell->GetOut()->PixelToLogic( aRightShadowPxRect ) ); 5383 } 5384 5385 /** determine rectangle for bottom page shadow 5386 5387 OD 12.02.2003 for #i9719# and #105645# 5388 5389 @author OD 5390 */ 5391 /*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect, 5392 ViewShell* _pViewShell, 5393 SwRect& _orBottomShadowRect, 5394 bool bRightSidebar ) 5395 { 5396 SwRect aAlignedPageRect( _rPageRect ); 5397 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5398 Rectangle aPagePxRect = 5399 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5400 5401 Rectangle aBottomShadowPxRect( 5402 aPagePxRect.Left() + 1, 5403 aPagePxRect.Bottom() + mnShadowPxWidth, 5404 aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth, 5405 aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth ); 5406 5407 AddSidebarBorders(aBottomShadowPxRect,_pViewShell, bRightSidebar, true); 5408 5409 _orBottomShadowRect = 5410 SwRect( _pViewShell->GetOut()->PixelToLogic( aBottomShadowPxRect ) ); 5411 } 5412 5413 /** paint page border and shadow 5414 5415 OD 12.02.2003 for #i9719# and #105645# 5416 implement paint of page border and shadow 5417 5418 @author OD 5419 */ 5420 /*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect, 5421 ViewShell* _pViewShell, 5422 bool bPaintRightShadow, 5423 bool bRightSidebar ) 5424 { 5425 // --> FME 2004-06-24 #i16816# tagged pdf support 5426 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() ); 5427 // <-- 5428 5429 // get color for page border and shadow paint 5430 const Color& rColor = SwViewOption::GetFontColor(); 5431 5432 // save current fill and line color of output device 5433 Color aFill( _pViewShell->GetOut()->GetFillColor() ); 5434 Color aLine( _pViewShell->GetOut()->GetLineColor() ); 5435 5436 // paint page border 5437 _pViewShell->GetOut()->SetFillColor(); // OD 20.02.2003 #107369# - no fill color 5438 _pViewShell->GetOut()->SetLineColor( rColor ); 5439 SwRect aPaintRect; 5440 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar ); 5441 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() ); 5442 5443 // paint right shadow 5444 if ( bPaintRightShadow ) 5445 { 5446 _pViewShell->GetOut()->SetFillColor( rColor ); 5447 SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar ); 5448 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() ); 5449 } 5450 5451 // paint bottom shadow 5452 SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar ); 5453 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() ); 5454 5455 _pViewShell->GetOut()->SetFillColor( aFill ); 5456 _pViewShell->GetOut()->SetLineColor( aLine ); 5457 } 5458 5459 //mod #i6193# paint sidebar for notes 5460 //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit 5461 /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight) 5462 { 5463 //TOOD: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons 5464 if (!_pViewShell ) 5465 return; 5466 5467 SwRect aPageRect( _rPageRect ); 5468 SwAlignRect( aPageRect, _pViewShell ); 5469 5470 const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr(); 5471 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) // do not show anything in print preview 5472 { 5473 sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight(); 5474 const Rectangle &aVisRect = _pViewShell->VisArea().SVRect(); 5475 //draw border and sidepane 5476 _pViewShell->GetOut()->SetLineColor(); 5477 if (!bRight) 5478 { 5479 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER); 5480 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()))) ; 5481 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5482 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5483 else 5484 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE); 5485 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()))) ; 5486 } 5487 else 5488 { 5489 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER); 5490 SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height())); 5491 _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect()); 5492 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5493 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5494 else 5495 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE); 5496 SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height())); 5497 _pViewShell->GetOut()->DrawRect(aSidebar.SVRect()); 5498 } 5499 if (pMgr->ShowScrollbar(nPageNum)) 5500 { 5501 // draw scrollbar area and arrows 5502 Point aPointBottom; 5503 Point aPointTop; 5504 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()) : 5505 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height()); 5506 aPointTop = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) : 5507 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()); 5508 Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ; 5509 Rectangle aRectBottom(aPointBottom,aSize); 5510 Rectangle aRectTop(aPointTop,aSize); 5511 5512 if (aRectBottom.IsOver(aVisRect)) 5513 { 5514 5515 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5516 { 5517 _pViewShell->GetOut()->SetLineColor(COL_WHITE); 5518 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5519 } 5520 else 5521 { 5522 _pViewShell->GetOut()->SetLineColor(COL_BLACK); 5523 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA); 5524 } 5525 _pViewShell->GetOut()->DrawRect(aRectBottom); 5526 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height())); 5527 5528 _pViewShell->GetOut()->SetLineColor(); 5529 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5530 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5531 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum)); 5532 } 5533 if (aRectTop.IsOver(aVisRect)) 5534 { 5535 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5536 { 5537 _pViewShell->GetOut()->SetLineColor(COL_WHITE); 5538 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5539 } 5540 else 5541 { 5542 _pViewShell->GetOut()->SetLineColor(COL_BLACK); 5543 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA); 5544 } 5545 _pViewShell->GetOut()->DrawRect(aRectTop); 5546 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height())); 5547 5548 _pViewShell->GetOut()->SetLineColor(); 5549 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5550 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5551 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum)); 5552 } 5553 } 5554 } 5555 } 5556 5557 /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown) 5558 { 5559 Polygon aTriangleUp(3); 5560 Polygon aTriangleDown(3); 5561 5562 aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0); 5563 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1); 5564 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2); 5565 5566 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0); 5567 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1); 5568 aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2); 5569 5570 _pViewShell->GetOut()->SetFillColor(aColorUp); 5571 _pViewShell->GetOut()->DrawPolygon(aTriangleUp); 5572 _pViewShell->GetOut()->SetFillColor(aColorDown); 5573 _pViewShell->GetOut()->DrawPolygon(aTriangleDown); 5574 } 5575 5576 /** get bound rectangle of border and shadow for repaints 5577 5578 OD 12.02.2003 for #i9719# and #105645# 5579 5580 author OD 5581 */ 5582 /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect, 5583 ViewShell* _pViewShell, 5584 SwRect& _orBorderAndShadowBoundRect, 5585 bool bRightSidebar ) 5586 { 5587 SwRect aTmpRect; 5588 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, _orBorderAndShadowBoundRect, bRightSidebar ); 5589 SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar ); 5590 _orBorderAndShadowBoundRect.Union( aTmpRect ); 5591 SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar ); 5592 _orBorderAndShadowBoundRect.Union( aTmpRect ); 5593 5594 AddSidebarBorders(_orBorderAndShadowBoundRect, _pViewShell, bRightSidebar, false); 5595 } 5596 5597 /*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx) 5598 { 5599 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5600 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) 5601 { 5602 if (!bRightSidebar) 5603 aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5604 else 5605 aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5606 } 5607 } 5608 5609 /*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx) 5610 { 5611 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5612 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) 5613 { 5614 if (!bRightSidebar) 5615 aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5616 else 5617 aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx); 5618 } 5619 } 5620 5621 /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell ) 5622 { 5623 const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5624 const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0; 5625 return nRet; 5626 } 5627 5628 /************************************************************************* 5629 |* 5630 |* SwFrm::PaintBaBo() 5631 |* 5632 |* Ersterstellung MA 22. Oct. 93 5633 |* Letzte Aenderung MA 19. Jun. 96 5634 |* 5635 |*************************************************************************/ 5636 5637 void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage, 5638 const sal_Bool bLowerBorder ) const 5639 { 5640 if ( !pPage ) 5641 pPage = FindPageFrm(); 5642 5643 OutputDevice *pOut = pGlobalShell->GetOut(); 5644 5645 // --> FME 2004-06-24 #i16816# tagged pdf support 5646 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut ); 5647 // <-- 5648 5649 // OD 2004-04-23 #116347# 5650 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 5651 pOut->SetLineColor(); 5652 5653 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 5654 const SwBorderAttrs &rAttrs = *aAccess.Get(); 5655 5656 // OD 20.11.2002 #104598# - take care of page margin area 5657 // Note: code move from <SwFrm::PaintBackground(..)> to new method 5658 // <SwPageFrm::Paintmargin(..)>. 5659 if ( IsPageFrm() ) 5660 { 5661 static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell ); 5662 } 5663 5664 // OD 06.08.2002 #99657# - paint border before painting background 5665 // paint grid for page frame and paint border 5666 { 5667 SwRect aRect( rRect ); 5668 if( IsPageFrm() ) 5669 ((SwPageFrm*)this)->PaintGrid( pOut, aRect ); 5670 PaintBorder( aRect, pPage, rAttrs ); 5671 } 5672 5673 // paint background 5674 { 5675 PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder ); 5676 } 5677 5678 pOut->Pop(); 5679 } 5680 5681 /************************************************************************* 5682 |* 5683 |* SwFrm::PaintBackground() 5684 |* 5685 |* Ersterstellung MA 04. Jan. 93 5686 |* Letzte Aenderung MA 06. Feb. 97 5687 |* 5688 |*************************************************************************/ 5689 /// OD 05.09.2002 #102912# 5690 /// Do not paint background for fly frames without a background brush by 5691 /// calling <PaintBaBo> at the page or at the fly frame its anchored 5692 void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage, 5693 const SwBorderAttrs & rAttrs, 5694 const sal_Bool bLowerMode, 5695 const sal_Bool bLowerBorder ) const 5696 { 5697 // OD 20.01.2003 #i1837# - no paint of table background, if corresponding 5698 // option is *not* set. 5699 if( IsTabFrm() && 5700 !pGlobalShell->GetViewOptions()->IsTable() ) 5701 { 5702 return; 5703 } 5704 5705 // nothing to do for covered table cells: 5706 if( IsCellFrm() && IsCoveredCell() ) 5707 return; 5708 5709 ViewShell *pSh = pGlobalShell; 5710 5711 // --> FME 2004-06-24 #i16816# tagged pdf support 5712 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); 5713 // <-- 5714 5715 const SvxBrushItem* pItem; 5716 /// OD 05.09.2002 #102912# 5717 /// temporary background brush for a fly frame without a background brush 5718 SvxBrushItem* pTmpBackBrush = 0; 5719 const Color* pCol; 5720 SwRect aOrigBackRect; 5721 const sal_Bool bPageFrm = IsPageFrm(); 5722 sal_Bool bLowMode = sal_True; 5723 5724 sal_Bool bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, bLowerMode ); 5725 //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird. 5726 bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm(); 5727 if ( bNoFlyBackground ) 5728 { 5729 // OD 05.09.2002 #102912# - Fly frame has no background. 5730 // Try to find background brush at parents, if previous call of 5731 // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode> 5732 if ( bLowerMode ) 5733 { 5734 bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, false ); 5735 } 5736 // If still no background found for the fly frame, initialize the 5737 // background brush <pItem> with global retouche color and set <bBack> 5738 // to sal_True, that fly frame will paint its background using this color. 5739 if ( !bBack ) 5740 { 5741 // OD 10.01.2003 #i6467# - on print output, pdf output and 5742 // in embedded mode not editing color COL_WHITE is used instead of 5743 // the global retouche color. 5744 if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER || 5745 pSh->GetViewOptions()->IsPDFExport() || 5746 ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && 5747 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() 5748 ) 5749 ) 5750 { 5751 pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND ); 5752 } 5753 else 5754 { 5755 pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND); 5756 } 5757 pItem = pTmpBackBrush; 5758 bBack = true; 5759 } 5760 } 5761 5762 SwRect aPaintRect( Frm() ); 5763 if( IsTxtFrm() || IsSctFrm() ) 5764 aPaintRect = UnionFrm( sal_True ); 5765 5766 if ( aPaintRect.IsOver( rRect ) ) 5767 { 5768 if ( bBack || bPageFrm || !bLowerMode ) 5769 { 5770 const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode(); 5771 SwRect aRect; 5772 if ( (bPageFrm && bBrowse) || 5773 (IsTxtFrm() && Prt().SSize() == Frm().SSize()) ) 5774 { 5775 aRect = Frm(); 5776 ::SwAlignRect( aRect, pGlobalShell ); 5777 } 5778 else 5779 { 5780 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_False ); 5781 if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() ) 5782 { 5783 if ( GetPrev()->GetAttrSet()->GetBackground() == 5784 GetAttrSet()->GetBackground() ) 5785 { 5786 aRect.Top( Frm().Top() ); 5787 } 5788 } 5789 } 5790 aRect.Intersection( rRect ); 5791 5792 OutputDevice *pOut = pSh->GetOut(); 5793 5794 if ( aRect.HasArea() ) 5795 { 5796 SvxBrushItem* pNewItem = 0; 5797 SwRegionRects aRegion( aRect ); 5798 if( pCol ) 5799 { 5800 pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND ); 5801 pItem = pNewItem; 5802 } 5803 if ( pPage->GetSortedObjs() ) 5804 ::lcl_SubtractFlys( this, pPage, aRect, aRegion ); 5805 5806 { 5807 /// OD 06.08.2002 #99657# - determine, if background transparency 5808 /// have to be considered for drawing. 5809 /// --> Status Quo: background transparency have to be 5810 /// considered for fly frames 5811 const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm(); 5812 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 5813 { 5814 if ( 1 < aRegion.Count() ) 5815 { 5816 ::SwAlignRect( aRegion[i], pGlobalShell ); 5817 if( !aRegion[i].HasArea() ) 5818 continue; 5819 } 5820 /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if 5821 /// background transparency have to be considered 5822 /// Set missing 5th parameter to the default value GRFNUM_NO 5823 /// - see declaration in /core/inc/frmtool.hxx. 5824 ::DrawGraphic( pItem, pOut, aOrigBackRect, aRegion[i], GRFNUM_NO, 5825 bConsiderBackgroundTransparency ); 5826 } 5827 } 5828 if( pCol ) 5829 delete pNewItem; 5830 } 5831 } 5832 else 5833 bLowMode = bLowerMode ? sal_True : sal_False; 5834 } 5835 5836 /// OD 05.09.2002 #102912# 5837 /// delete temporary background brush. 5838 delete pTmpBackBrush; 5839 5840 //Jetzt noch Lower und dessen Nachbarn. 5841 //Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist 5842 //so hoert der Spass auf. 5843 const SwFrm *pFrm = GetLower(); 5844 if ( pFrm ) 5845 { 5846 SwRect aFrmRect; 5847 SwRect aRect( PaintArea() ); 5848 aRect._Intersection( rRect ); 5849 SwRect aBorderRect( aRect ); 5850 SwShortCut aShortCut( *pFrm, aBorderRect ); 5851 do 5852 { if ( pProgress ) 5853 pProgress->Reschedule(); 5854 5855 aFrmRect = pFrm->PaintArea(); 5856 if ( aFrmRect.IsOver( aBorderRect ) ) 5857 { 5858 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm ); 5859 const SwBorderAttrs &rTmpAttrs = *aAccess.Get(); 5860 /// OD 06.08.2002 #99657# - paint border before painting background 5861 if ( bLowerBorder ) 5862 pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs ); 5863 if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) || 5864 aFrmRect.IsOver( aRect ) ) 5865 pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode, 5866 bLowerBorder ); 5867 } 5868 pFrm = pFrm->GetNext(); 5869 } while ( pFrm && pFrm->GetUpper() == this && 5870 !aShortCut.Stop( aFrmRect ) ); 5871 } 5872 } 5873 5874 /************************************************************************* 5875 |* 5876 |* SwPageFrm::RefreshSubsidiary() 5877 |* 5878 |* Beschreibung Erneuert alle Hilfslinien der Seite. 5879 |* Ersterstellung MA 04. Nov. 92 5880 |* Letzte Aenderung MA 10. May. 95 5881 |* 5882 |*************************************************************************/ 5883 5884 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const 5885 { 5886 if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS ) 5887 { 5888 SwRect aRect( rRect ); 5889 // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of 5890 // the output rectangle. 5891 //::SwAlignRect( aRect, pGlobalShell ); 5892 if ( aRect.HasArea() ) 5893 { 5894 //Beim Paint ueber die Root wird das Array von dort gesteuert. 5895 //Anderfalls kuemmern wir uns selbst darum. 5896 sal_Bool bDelSubs = sal_False; 5897 if ( !pSubsLines ) 5898 { 5899 pSubsLines = new SwSubsRects; 5900 // OD 20.12.2002 #106318# - create container for special subsidiary lines 5901 pSpecSubsLines = new SwSubsRects; 5902 bDelSubs = sal_True; 5903 } 5904 5905 RefreshLaySubsidiary( this, aRect ); 5906 5907 if ( bDelSubs ) 5908 { 5909 // OD 20.12.2002 #106318# - paint special subsidiary lines 5910 // and delete its container 5911 pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL ); 5912 DELETEZ( pSpecSubsLines ); 5913 5914 pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines ); 5915 DELETEZ( pSubsLines ); 5916 } 5917 } 5918 } 5919 } 5920 5921 /************************************************************************* 5922 |* 5923 |* SwLayoutFrm::RefreshLaySubsidiary() 5924 |* 5925 |* Ersterstellung MA 04. Nov. 92 5926 |* Letzte Aenderung MA 22. Jan. 95 5927 |* 5928 |*************************************************************************/ 5929 void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage, 5930 const SwRect &rRect ) const 5931 { 5932 const sal_Bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm(); 5933 const sal_Bool bSubsOpt = IS_SUBS; 5934 const sal_Bool bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE); 5935 const sal_Bool bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt; 5936 const sal_Bool bSubsSect = IsSctFrm() && 5937 bNoLowerColumn && 5938 IS_SUBS_SECTION; 5939 const sal_Bool bSubsFly = IS_SUBS_FLYS && 5940 (GetType() & FRM_FLY) && 5941 bNoLowerColumn && 5942 (!Lower() || !Lower()->IsNoTxtFrm() || 5943 !((SwNoTxtFrm*)Lower())->HasAnimation()); 5944 sal_Bool bSubsBody = sal_False; 5945 if ( GetType() & FRM_BODY ) 5946 { 5947 if ( IsPageBodyFrm() ) 5948 bSubsBody = bSubsOpt && bNoLowerColumn; //nur ohne Spalten 5949 else //Spaltenbody 5950 { 5951 if ( GetUpper()->GetUpper()->IsSctFrm() ) 5952 bSubsBody = IS_SUBS_SECTION; 5953 else 5954 bSubsBody = bSubsOpt; 5955 } 5956 } 5957 5958 if ( bSubsOther || bSubsSect || bSubsBody || bSubsTable || bSubsFly ) 5959 PaintSubsidiaryLines( pPage, rRect ); 5960 5961 const SwFrm *pLow = Lower(); 5962 if( !pLow ) 5963 return; 5964 SwShortCut aShortCut( *pLow, rRect ); 5965 while( pLow && !aShortCut.Stop( pLow->Frm() ) ) 5966 { 5967 if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() ) 5968 { 5969 if ( pLow->IsLayoutFrm() ) 5970 ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect); 5971 else if ( pLow->GetDrawObjs() ) 5972 { 5973 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs()); 5974 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i ) 5975 { 5976 const SwAnchoredObject* pAnchoredObj = rObjs[i]; 5977 if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId( 5978 pAnchoredObj->GetDrawObj()->GetLayer() ) && 5979 pAnchoredObj->ISA(SwFlyFrm) ) 5980 { 5981 const SwFlyFrm *pFly = 5982 static_cast<const SwFlyFrm*>(pAnchoredObj); 5983 if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) ) 5984 { 5985 if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() || 5986 !((SwNoTxtFrm*)pFly->Lower())->HasAnimation()) 5987 pFly->RefreshLaySubsidiary( pPage, rRect ); 5988 } 5989 } 5990 } 5991 } 5992 } 5993 pLow = pLow->GetNext(); 5994 } 5995 } 5996 5997 /************************************************************************* 5998 |* 5999 |* SwLayoutFrm::PaintSubsidiaryLines() 6000 |* 6001 |* Beschreibung Hilfslinien um die PrtAreas malen 6002 |* Nur die LayoutFrm's die direkt Cntnt enthalten. 6003 |* Ersterstellung MA 21. May. 92 6004 |* Letzte Aenderung MA 22. Jan. 95 6005 |* 6006 |*************************************************************************/ 6007 6008 //Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden. 6009 6010 typedef long Size::* SizePtr; 6011 typedef long Point::* PointPtr; 6012 6013 PointPtr pX = &Point::nA; 6014 PointPtr pY = &Point::nB; 6015 SizePtr pWidth = &Size::nA; 6016 SizePtr pHeight = &Size::nB; 6017 6018 // OD 18.11.2002 #99672# - new parameter <_pSubsLines> 6019 void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay, 6020 const SwPageFrm *pPage, 6021 const Point &rP1, 6022 const Point &rP2, 6023 const sal_uInt8 nSubColor, 6024 SwLineRects* _pSubsLines ) 6025 { 6026 //In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein. 6027 ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())), 6028 "Schraege Hilfslinien sind nicht erlaubt." ); 6029 const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX; 6030 const PointPtr pOthPt = pDirPt == pX ? pY : pX; 6031 const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight; 6032 const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth; 6033 Point aP1( rP1 ), 6034 aP2( rP2 ); 6035 6036 while ( aP1.*pDirPt < aP2.*pDirPt ) 6037 { //Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt 6038 //hinter den Fly gesetzt. 6039 //Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt 6040 //ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen. 6041 //Auf diese art und weise wird eine Portion nach der anderen 6042 //ausgegeben. 6043 6044 //Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus, 6045 //die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen. 6046 //Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche 6047 //ich keinem dieser Flys aus. 6048 SwOrderIter aIter( pPage ); 6049 const SwFlyFrm *pMyFly = pLay->FindFlyFrm(); 6050 if ( pMyFly ) 6051 { 6052 aIter.Current( pMyFly->GetVirtDrawObj() ); 6053 while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) ) 6054 { 6055 if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() ) 6056 aIter.Current( pMyFly->GetVirtDrawObj() ); 6057 } 6058 } 6059 else 6060 aIter.Bottom(); 6061 6062 while ( aIter() ) 6063 { 6064 const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter(); 6065 const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0; 6066 6067 //Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich 6068 //_in_ dem Fly sitze weiche ich nicht aus. 6069 if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) ) 6070 { 6071 aIter.Next(); 6072 continue; 6073 } 6074 6075 // OD 19.12.2002 #106318# - do *not* consider fly frames with 6076 // a transparent background. 6077 // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which 6078 // belongs to a invisible layer 6079 if ( pFly->IsBackgroundTransparent() || 6080 !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) ) 6081 { 6082 aIter.Next(); 6083 continue; 6084 } 6085 6086 //Sitzt das Obj auf der Linie 6087 const Rectangle &rBound = pObj->GetCurrentBoundRect(); 6088 const Point aDrPt( rBound.TopLeft() ); 6089 const Size aDrSz( rBound.GetSize() ); 6090 if ( rP1.*pOthPt >= aDrPt.*pOthPt && 6091 rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) ) 6092 { 6093 if ( aP1.*pDirPt >= aDrPt.*pDirPt && 6094 aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) ) 6095 aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz; 6096 6097 if ( aP2.*pDirPt >= aDrPt.*pDirPt && 6098 aP1.*pDirPt < (aDrPt.*pDirPt - 1) ) 6099 aP2.*pDirPt = aDrPt.*pDirPt - 1; 6100 } 6101 aIter.Next(); 6102 } 6103 6104 if ( aP1.*pDirPt < aP2.*pDirPt ) 6105 { 6106 SwRect aRect( aP1, aP2 ); 6107 // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of 6108 // global variable <pSubsLines>. 6109 _pSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6110 } 6111 aP1 = aP2; 6112 aP1.*pDirPt += 1; 6113 aP2 = rP2; 6114 } 6115 } 6116 6117 void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage, 6118 const SwRect &rRect ) const 6119 { 6120 bool bNewTableModel = false; 6121 6122 // --> collapsing borders FME 2005-05-27 #i29550# 6123 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() ) 6124 { 6125 const SwTabFrm* pTabFrm = FindTabFrm(); 6126 if ( pTabFrm->IsCollapsingBorders() ) 6127 return; 6128 6129 bNewTableModel = pTabFrm->GetTable()->IsNewModel(); 6130 // in the new table model, we have an early return for all cell-related 6131 // frames, except from non-covered table cells 6132 if ( bNewTableModel ) 6133 if ( IsTabFrm() || 6134 IsRowFrm() || 6135 ( IsCellFrm() && IsCoveredCell() ) ) 6136 return; 6137 } 6138 // <-- collapsing 6139 6140 const bool bFlys = pPage->GetSortedObjs() ? true : false; 6141 6142 const bool bCell = IsCellFrm() ? true : false; 6143 // use frame area for cells 6144 // OD 13.02.2003 #i3662# - for section use also frame area 6145 const bool bUseFrmArea = bCell || IsSctFrm(); 6146 SwRect aOriginal( bUseFrmArea ? Frm() : Prt() ); 6147 if ( !bUseFrmArea ) 6148 aOriginal.Pos() += Frm().Pos(); 6149 6150 // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area 6151 // in sections to top of section frame. 6152 const bool bColBodyInSection = IsBodyFrm() && 6153 !IsPageBodyFrm() && 6154 GetUpper()->GetUpper()->IsSctFrm(); 6155 if ( bColBodyInSection ) 6156 { 6157 if ( IsVertical() ) 6158 aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() ); 6159 else 6160 aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() ); 6161 } 6162 6163 ::SwAlignRect( aOriginal, pGlobalShell ); 6164 6165 if ( !aOriginal.IsOver( rRect ) ) 6166 return; 6167 6168 SwRect aOut( aOriginal ); 6169 aOut._Intersection( rRect ); 6170 // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's 6171 // printing area with the paint area of the body frame. Otherwise enlargement 6172 // will get lost. 6173 if ( !bColBodyInSection ) 6174 { 6175 aOut.Intersection( PaintArea() ); 6176 } 6177 6178 const SwTwips nRight = aOut.Right(); 6179 const SwTwips nBottom= aOut.Bottom(); 6180 6181 const Point aRT( nRight, aOut.Top() ); 6182 const Point aRB( nRight, nBottom ); 6183 const Point aLB( aOut.Left(), nBottom ); 6184 6185 sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB : 6186 ( IsInSct() ? SUBCOL_SECT : 6187 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) ); 6188 6189 // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks. 6190 sal_Bool bBreak = sal_False; 6191 if ( IsBodyFrm() ) 6192 { 6193 const SwCntntFrm *pCnt = ContainsCntnt(); 6194 if ( pCnt ) 6195 { 6196 // OD 05.11.2002 #102406# - adjust setting of <bBreak>. 6197 bBreak = pCnt->IsPageBreak( sal_True ) || 6198 ( IsColBodyFrm() && pCnt->IsColBreak( sal_True ) ); 6199 } 6200 } 6201 6202 // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section 6203 // sub-lines in <pSpecSubsLine> array. 6204 const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() || 6205 IsFtnFrm() || IsSctFrm(); 6206 SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines; 6207 6208 // NOTE: for cell frames only left and right (horizontal layout) respectively 6209 // top and bottom (vertical layout) lines painted. 6210 // NOTE2: this does not hold for the new table model!!! We paint the top border 6211 // of each non-covered table cell. 6212 const bool bVert = IsVertical() ? true : false; 6213 if ( bFlys ) 6214 { 6215 // OD 14.11.2002 #104822# - add control for drawing left and right lines 6216 if ( !bCell || bNewTableModel || !bVert ) 6217 { 6218 if ( aOriginal.Left() == aOut.Left() ) 6219 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor, 6220 pUsedSubsLines ); 6221 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right 6222 if ( aOriginal.Right() == nRight ) 6223 ::lcl_RefreshLine( this, pPage, aRT, aRB, 6224 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor, 6225 pUsedSubsLines ); 6226 } 6227 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines 6228 if ( !bCell || bNewTableModel || bVert ) 6229 { 6230 if ( aOriginal.Top() == aOut.Top() ) 6231 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top 6232 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT, 6233 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor, 6234 pUsedSubsLines ); 6235 if ( aOriginal.Bottom() == nBottom ) 6236 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor, 6237 pUsedSubsLines ); 6238 } 6239 } 6240 else 6241 { 6242 // OD 14.11.2002 #104822# - add control for drawing left and right lines 6243 if ( !bCell || bNewTableModel || !bVert ) 6244 { 6245 if ( aOriginal.Left() == aOut.Left() ) 6246 { 6247 const SwRect aRect( aOut.Pos(), aLB ); 6248 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6249 } 6250 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right 6251 if ( aOriginal.Right() == nRight ) 6252 { 6253 const SwRect aRect( aRT, aRB ); 6254 pUsedSubsLines->AddLineRect( aRect, 0, 0, 6255 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor ); 6256 } 6257 } 6258 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines 6259 if ( !bCell || bNewTableModel || bVert ) 6260 { 6261 if ( aOriginal.Top() == aOut.Top() ) 6262 { 6263 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top 6264 const SwRect aRect( aOut.Pos(), aRT ); 6265 pUsedSubsLines->AddLineRect( aRect, 0, 0, 6266 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor ); 6267 } 6268 if ( aOriginal.Bottom() == nBottom ) 6269 { 6270 const SwRect aRect( aLB, aRB ); 6271 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6272 } 6273 } 6274 } 6275 } 6276 6277 /************************************************************************* 6278 |* 6279 |* SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData() 6280 |* 6281 |* Beschreibung Erneuert alle Extradaten (Zeilennummern usw) der Seite. 6282 |* Grundsaetzlich sind nur diejenigen Objekte beruecksichtig, 6283 |* die in die seitliche Ausdehnung des Rects ragen. 6284 |* Ersterstellung MA 20. Jan. 98 6285 |* Letzte Aenderung MA 18. Feb. 98 6286 |* 6287 |*************************************************************************/ 6288 6289 void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const 6290 { 6291 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo(); 6292 sal_Bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys()) 6293 || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE; 6294 6295 SwRect aRect( rRect ); 6296 ::SwAlignRect( aRect, pGlobalShell ); 6297 if ( aRect.HasArea() ) 6298 { 6299 SwLayoutFrm::RefreshExtraData( aRect ); 6300 6301 if ( bLineInFly && GetSortedObjs() ) 6302 for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i ) 6303 { 6304 const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i]; 6305 if ( pAnchoredObj->ISA(SwFlyFrm) ) 6306 { 6307 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); 6308 if ( pFly->Frm().Top() <= aRect.Bottom() && 6309 pFly->Frm().Bottom() >= aRect.Top() ) 6310 pFly->RefreshExtraData( aRect ); 6311 } 6312 } 6313 } 6314 } 6315 6316 void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const 6317 { 6318 6319 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo(); 6320 sal_Bool bLineInBody = rInfo.IsPaintLineNumbers(), 6321 bLineInFly = bLineInBody && rInfo.IsCountInFlys(), 6322 bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE; 6323 6324 const SwCntntFrm *pCnt = ContainsCntnt(); 6325 while ( pCnt && IsAnLower( pCnt ) ) 6326 { 6327 if ( pCnt->IsTxtFrm() && ( bRedLine || 6328 ( !pCnt->IsInTab() && 6329 ((bLineInBody && pCnt->IsInDocBody()) || 6330 (bLineInFly && pCnt->IsInFly())) ) ) && 6331 pCnt->Frm().Top() <= rRect.Bottom() && 6332 pCnt->Frm().Bottom() >= rRect.Top() ) 6333 { 6334 ((SwTxtFrm*)pCnt)->PaintExtraData( rRect ); 6335 } 6336 if ( bLineInFly && pCnt->GetDrawObjs() ) 6337 for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i ) 6338 { 6339 const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i]; 6340 if ( pAnchoredObj->ISA(SwFlyFrm) ) 6341 { 6342 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); 6343 if ( pFly->IsFlyInCntFrm() && 6344 pFly->Frm().Top() <= rRect.Bottom() && 6345 pFly->Frm().Bottom() >= rRect.Top() ) 6346 pFly->RefreshExtraData( rRect ); 6347 } 6348 } 6349 pCnt = pCnt->GetNextCntntFrm(); 6350 } 6351 } 6352 6353 /** SwPageFrm::GetDrawBackgrdColor - for #102450# 6354 6355 determine the color, that is respectively will be drawn as background 6356 for the page frame. 6357 Using existing method SwFrm::GetBackgroundBrush to determine the color 6358 that is set at the page frame respectively is parent. If none is found 6359 return the global retouche color 6360 6361 @author OD 6362 6363 @return Color 6364 */ 6365 const Color& SwPageFrm::GetDrawBackgrdColor() const 6366 { 6367 const SvxBrushItem* pBrushItem; 6368 const Color* pDummyColor; 6369 SwRect aDummyRect; 6370 if ( GetBackgroundBrush( pBrushItem, pDummyColor, aDummyRect, true) ) 6371 return pBrushItem->GetColor(); 6372 else 6373 return aGlobalRetoucheColor; 6374 } 6375 6376 /************************************************************************* 6377 |* 6378 |* SwPageFrm::GetEmptyPageFont() 6379 |* 6380 |* create/return font used to paint the "empty page" string 6381 |* 6382 |*************************************************************************/ 6383 6384 const Font& SwPageFrm::GetEmptyPageFont() 6385 { 6386 static Font* pEmptyPgFont = 0; 6387 if ( 0 == pEmptyPgFont ) 6388 { 6389 pEmptyPgFont = new Font; 6390 pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt 6391 pEmptyPgFont->SetWeight( WEIGHT_BOLD ); 6392 pEmptyPgFont->SetStyleName( aEmptyStr ); 6393 pEmptyPgFont->SetName( String::CreateFromAscii( 6394 RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) ); 6395 pEmptyPgFont->SetFamily( FAMILY_SWISS ); 6396 pEmptyPgFont->SetTransparent( sal_True ); 6397 pEmptyPgFont->SetColor( COL_GRAY ); 6398 } 6399 6400 return *pEmptyPgFont; 6401 } 6402 6403 /************************************************************************* 6404 |* 6405 |* SwFrm::Retouche 6406 |* 6407 |* Beschreibung Retouche fuer einen Bereich. 6408 |* Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner 6409 |* Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird 6410 |* per PaintBackground gecleared. 6411 |* Ersterstellung MA 13. Apr. 93 6412 |* Letzte Aenderung MA 25. Jul. 96 6413 |* 6414 |*************************************************************************/ 6415 6416 void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const 6417 { 6418 if ( bFlyMetafile ) 6419 return; 6420 6421 ASSERT( GetUpper(), "Retoucheversuch ohne Upper." ); 6422 ASSERT( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" ); 6423 6424 SwRect aRetouche( GetUpper()->PaintArea() ); 6425 aRetouche.Top( Frm().Top() + Frm().Height() ); 6426 aRetouche.Intersection( pGlobalShell->VisArea() ); 6427 6428 if ( aRetouche.HasArea() ) 6429 { 6430 //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region 6431 //zum ausstanzen. 6432 SwRegionRects aRegion( aRetouche ); 6433 aRegion -= rRect; 6434 ViewShell *pSh = getRootFrm()->GetCurrShell(); 6435 6436 // --> FME 2004-06-24 #i16816# tagged pdf support 6437 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); 6438 // <-- 6439 6440 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 6441 { 6442 SwRect &rRetouche = aRegion[i]; 6443 6444 GetUpper()->PaintBaBo( rRetouche, pPage, sal_True ); 6445 6446 //Hoelle und Himmel muessen auch refreshed werden. 6447 //Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst 6448 //zurueckgesetzt werden! 6449 ResetRetouche(); 6450 SwRect aRetouchePart( rRetouche ); 6451 if ( aRetouchePart.HasArea() ) 6452 { 6453 const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor(); 6454 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 6455 // --> OD #i76669# 6456 SwViewObjectContactRedirector aSwRedirector( *pSh ); 6457 // <-- 6458 6459 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0, 6460 aRetouchePart, &aPageBackgrdColor, 6461 (pPage->IsRightToLeft() ? true : false), 6462 &aSwRedirector ); 6463 pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0, 6464 aRetouchePart, &aPageBackgrdColor, 6465 (pPage->IsRightToLeft() ? true : false), 6466 &aSwRedirector ); 6467 } 6468 6469 SetRetouche(); 6470 6471 //Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier 6472 //leider die Hilfslinien erneuert werden. 6473 pPage->RefreshSubsidiary( aRetouchePart ); 6474 } 6475 } 6476 if ( ViewShell::IsLstEndAction() ) 6477 ResetRetouche(); 6478 } 6479 6480 /** SwFrm::GetBackgroundBrush 6481 6482 @descr 6483 determine the background brush for the frame: 6484 the background brush is taken from it-self or from its parent (anchor/upper). 6485 Normally, the background brush is taken, which has no transparent color or 6486 which has a background graphic. But there are some special cases: 6487 (1) No background brush is taken from a page frame, if view option "IsPageBack" 6488 isn't set. 6489 (2) Background brush from a index section is taken under special conditions. 6490 In this case parameter <rpCol> is set to the index shading color. 6491 (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing 6492 of the frame transparency is considered and its color is not "no fill"/"auto fill" 6493 ---- old description in german: 6494 Beschreibung Liefert die Backgroundbrush fuer den Bereich des 6495 des Frm. Die Brush wird entweder von ihm selbst oder von einem 6496 Upper vorgegeben, die erste Brush wird benutzt. 6497 Ist fuer keinen Frm eine Brush angegeben, so wird sal_False zurueck- 6498 geliefert. 6499 Ersterstellung MA 23. Dec. 92 6500 Letzte Aenderung MA 04. Feb. 97 6501 6502 @param rpBrush 6503 output parameter - constant reference pointer the found background brush 6504 6505 @param rpCol 6506 output parameter - constant reference pointer to the color of the index shading 6507 set under special conditions, if background brush is taken from an index section. 6508 6509 @param rOrigRect 6510 in-/output parameter - reference to the retangle the background brush is 6511 considered for - adjusted to the frame, from which the background brush is 6512 taken. 6513 6514 @parem bLowerMode 6515 input parameter - boolean indicating, if background brush should *not* be 6516 taken from parent. 6517 6518 @author MA 6519 @change 20.08.2002 by OD 6520 @docdate 20.08.2002 6521 6522 @return true, if a background brush for the frame is found 6523 */ 6524 sal_Bool SwFrm::GetBackgroundBrush( const SvxBrushItem* & rpBrush, 6525 const Color*& rpCol, 6526 SwRect &rOrigRect, 6527 sal_Bool bLowerMode ) const 6528 { 6529 const SwFrm *pFrm = this; 6530 ViewShell *pSh = getRootFrm()->GetCurrShell(); 6531 const SwViewOption *pOpt = pSh->GetViewOptions(); 6532 rpBrush = 0; 6533 rpCol = NULL; 6534 do 6535 { if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() ) 6536 return sal_False; 6537 6538 const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground(); 6539 if( pFrm->IsSctFrm() ) 6540 { 6541 const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection(); 6542 /// OD 20.08.2002 #99657# #GetTransChg# 6543 /// Note: If frame <pFrm> is a section of the index and 6544 /// it its background color is "no fill"/"auto fill" and 6545 /// it has no background graphic and 6546 /// we are not in the page preview and 6547 /// we are not in read-only mode and 6548 /// option "index shadings" is set and 6549 /// the output is not the printer 6550 /// then set <rpCol> to the color of the index shading 6551 if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() || 6552 TOX_CONTENT_SECTION == pSection->GetType() ) && 6553 (rBack.GetColor() == COL_TRANSPARENT) && 6554 ///rBack.GetColor().GetTransparency() && 6555 rBack.GetGraphicPos() == GPOS_NONE && 6556 !pOpt->IsPagePreview() && 6557 !pOpt->IsReadonly() && 6558 // --> FME 2004-06-29 #114856# Formular view 6559 !pOpt->IsFormView() && 6560 // <-- 6561 SwViewOption::IsIndexShadings() && 6562 !pOpt->IsPDFExport() && 6563 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER ) 6564 { 6565 rpCol = &SwViewOption::GetIndexShadingsColor(); 6566 } 6567 } 6568 6569 /// OD 20.08.2002 #99657# 6570 /// determine, if background draw of frame <pFrm> considers transparency 6571 /// --> Status Quo: background transparency have to be 6572 /// considered for fly frames 6573 const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm(); 6574 /// OD 20.08.2002 #99657# 6575 /// add condition: 6576 /// If <bConsiderBackgroundTransparency> is set - see above -, 6577 /// return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill" 6578 if ( !rBack.GetColor().GetTransparency() || 6579 rBack.GetGraphicPos() != GPOS_NONE || 6580 rpCol || 6581 (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT)) 6582 ) 6583 { 6584 rpBrush = &rBack; 6585 if ( pFrm->IsPageFrm() && 6586 pSh->GetViewOptions()->getBrowseMode() ) 6587 rOrigRect = pFrm->Frm(); 6588 else 6589 { 6590 if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() ) 6591 { 6592 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); 6593 const SwBorderAttrs &rAttrs = *aAccess.Get(); 6594 ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, sal_False ); 6595 } 6596 else 6597 { 6598 rOrigRect = pFrm->Prt(); 6599 rOrigRect += pFrm->Frm().Pos(); 6600 } 6601 } 6602 return sal_True; 6603 } 6604 6605 if ( bLowerMode ) 6606 /// Do not try to get background brush from parent (anchor/upper) 6607 return sal_False; 6608 6609 /// get parent frame - anchor or upper - for next loop 6610 if ( pFrm->IsFlyFrm() ) 6611 /// OD 20.08.2002 - use "static_cast" instead of "old C-cast" 6612 pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm(); 6613 ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor(); 6614 else 6615 pFrm = pFrm->GetUpper(); 6616 6617 } while ( pFrm ); 6618 6619 return sal_False; 6620 } 6621 6622 /************************************************************************* 6623 |* 6624 |* SwFrmFmt::GetGraphic() 6625 |* 6626 |* Ersterstellung MA 23. Jul. 96 6627 |* Letzte Aenderung MA 23. Jul. 96 6628 |* 6629 |*************************************************************************/ 6630 6631 void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO, 6632 Window *pW, sal_uInt16 nZoom ) 6633 { 6634 pSh->pOut = pO; 6635 pSh->pWin = pW; 6636 pSh->pOpt->SetZoom( nZoom ); 6637 } 6638 6639 Graphic SwFrmFmt::MakeGraphic( ImageMap* ) 6640 { 6641 return Graphic(); 6642 } 6643 6644 Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap ) 6645 { 6646 Graphic aRet; 6647 //irgendeinen Fly suchen! 6648 SwIterator<SwFrm,SwFmt> aIter( *this ); 6649 SwFrm *pFirst = aIter.First(); 6650 ViewShell *pSh; 6651 if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) ) 6652 { 6653 ViewShell *pOldGlobal = pGlobalShell; 6654 pGlobalShell = pSh; 6655 6656 sal_Bool bNoteURL = pMap && 6657 SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, sal_True ); 6658 if( bNoteURL ) 6659 { 6660 ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " ); 6661 pNoteURL = new SwNoteURL; 6662 } 6663 SwFlyFrm *pFly = (SwFlyFrm*)pFirst; 6664 6665 OutputDevice *pOld = pSh->GetOut(); 6666 VirtualDevice aDev( *pOld ); 6667 aDev.EnableOutput( sal_False ); 6668 6669 GDIMetaFile aMet; 6670 MapMode aMap( pOld->GetMapMode().GetMapUnit() ); 6671 aDev.SetMapMode( aMap ); 6672 aMet.SetPrefMapMode( aMap ); 6673 6674 ::SwCalcPixStatics( pSh->GetOut() ); 6675 aMet.SetPrefSize( pFly->Frm().SSize() ); 6676 6677 aMet.Record( &aDev ); 6678 aDev.SetLineColor(); 6679 aDev.SetFillColor(); 6680 aDev.SetFont( pOld->GetFont() ); 6681 6682 //Rechteck ggf. ausdehnen, damit die Umrandunge mit aufgezeichnet werden. 6683 SwRect aOut( pFly->Frm() ); 6684 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly ); 6685 const SwBorderAttrs &rAttrs = *aAccess.Get(); 6686 if ( rAttrs.CalcRightLine() ) 6687 aOut.SSize().Width() += 2*nPixelSzW; 6688 if ( rAttrs.CalcBottomLine() ) 6689 aOut.SSize().Height()+= 2*nPixelSzH; 6690 6691 // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev 6692 const Region aRepaintRegion(aOut.SVRect()); 6693 pSh->DLPrePaint2(aRepaintRegion); 6694 6695 Window *pWin = pSh->GetWin(); 6696 sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom(); 6697 ::SetOutDevAndWin( pSh, &aDev, 0, 100 ); 6698 bFlyMetafile = sal_True; 6699 pFlyMetafileOut = pWin; 6700 6701 SwViewImp *pImp = pSh->Imp(); 6702 pFlyOnlyDraw = pFly; 6703 pLines = new SwLineRects; 6704 6705 // OD 09.12.2002 #103045# - determine page, fly frame is on 6706 const SwPageFrm* pFlyPage = pFly->FindPageFrm(); 6707 const Color aPageBackgrdColor = pFlyPage->GetDrawBackgrdColor(); 6708 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 6709 // --> OD #i76669# 6710 SwViewObjectContactRedirector aSwRedirector( *pSh ); 6711 // <-- 6712 pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor, 6713 (pFlyPage->IsRightToLeft() ? true : false), 6714 &aSwRedirector ); 6715 pLines->PaintLines( &aDev ); 6716 if ( pFly->IsFlyInCntFrm() ) 6717 pFly->Paint( aOut ); 6718 pLines->PaintLines( &aDev ); 6719 /// OD 30.08.2002 #102450# - add 3rd parameter 6720 pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor, 6721 (pFlyPage->IsRightToLeft() ? true : false), 6722 &aSwRedirector ); 6723 pLines->PaintLines( &aDev ); 6724 DELETEZ( pLines ); 6725 pFlyOnlyDraw = 0; 6726 6727 pFlyMetafileOut = 0; 6728 bFlyMetafile = sal_False; 6729 ::SetOutDevAndWin( pSh, pOld, pWin, nZoom ); 6730 6731 // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted 6732 pSh->DLPostPaint2(true); 6733 6734 aMet.Stop(); 6735 aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() ); 6736 aRet = Graphic( aMet ); 6737 6738 if( bNoteURL ) 6739 { 6740 ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." ); 6741 pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap ); 6742 delete pNoteURL; 6743 pNoteURL = NULL; 6744 } 6745 pGlobalShell = pOldGlobal; 6746 } 6747 return aRet; 6748 } 6749 6750 Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* ) 6751 { 6752 Graphic aRet; 6753 SdrModel *pMod = getIDocumentDrawModelAccess()->GetDrawModel(); 6754 if ( pMod ) 6755 { 6756 SdrObject *pObj = FindSdrObject(); 6757 SdrView *pView = new SdrView( pMod ); 6758 SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0)); 6759 pView->MarkObj( pObj, pPgView ); 6760 aRet = pView->GetMarkedObjBitmap(); 6761 pView->HideSdrPage(); 6762 delete pView; 6763 } 6764 return aRet; 6765 } 6766 6767 6768