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