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