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