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 1614 /// OD 17.10.2002 #103876# - outsourcing drawing of background with a background color. 1615 ::lcl_DrawGraphicBackgrd( rBrush, pOut, aAlignedGrfRect, *pGrf, bGrfNum, bBackgrdAlreadyDrawn ); 1616 1617 /// OD 25.09.2002 #99739# - 1618 /// Because for drawing a graphic left-top-corner and size coordinations are 1619 /// used, these coordinations have to be determined on pixel level. 1620 ::SwAlignGrfRect( &aAlignedGrfRect, *pOut ); 1621 pGrf->DrawWithPDFHandling( *pOut, aAlignedGrfRect.Pos(), aAlignedGrfRect.SSize() ); 1622 1623 if ( bNotInside ) 1624 pOut->Pop(); 1625 } // end of method <lcl_DrawGraphic> 1626 1627 bool MA_FASTCALL DrawFillAttributes( 1628 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes, 1629 const SwRect& rOriginalLayoutRect, 1630 const SwRect& rPaintRect, 1631 OutputDevice& rOut) 1632 { 1633 static bool bUseNew(true); 1634 static bool bReturnWhenNew(true); 1635 1636 if(bUseNew && rFillAttributes.get() && rFillAttributes->isUsed()) 1637 { 1638 basegfx::B2DRange aPaintRange( 1639 rPaintRect.Left(), 1640 rPaintRect.Top(), 1641 rPaintRect.Right(), 1642 rPaintRect.Bottom()); 1643 1644 if(!aPaintRange.isEmpty() && 1645 !basegfx::fTools::equalZero(aPaintRange.getWidth()) && 1646 !basegfx::fTools::equalZero(aPaintRange.getHeight())) 1647 { 1648 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 1649 1650 //UUUU need to expand for correct AAed and non-AAed visualization as primitive. 1651 // This must probably be removed again when we will be able to get all Writer visualization 1652 // as primitives and Writer prepares all it's stuff in high precision coordinates (also 1653 // needs to avoid moving boundaries around to better show overlapping stuff...) 1654 if(aSvtOptionsDrawinglayer.IsAntiAliasing()) 1655 { 1656 // if AAed in principle expand by 0.5 in all directions. Since painting edges of 1657 // AAed regions does not add to no transparency (0.5 opacity covered by 0.5 opacity 1658 // is not full opacity but 0.75 opacity) we need some overlap here to avoid paint 1659 // artifacts. Checked experimentally - a little bit more in Y is needed, probably 1660 // due to still existing integer alignment and crunching in Writer. 1661 static double fExpandX = 0.55; 1662 static double fExpandY = 0.70; 1663 const basegfx::B2DVector aSingleUnit(rOut.GetInverseViewTransformation() * basegfx::B2DVector(fExpandX, fExpandY)); 1664 1665 aPaintRange.expand(aPaintRange.getMinimum() - aSingleUnit); 1666 aPaintRange.expand(aPaintRange.getMaximum() + aSingleUnit); 1667 } 1668 else 1669 { 1670 // if not AAed expand by one unit to bottom right due to the missing unit 1671 // from SwRect/Rectangle integer handling 1672 const basegfx::B2DVector aSingleUnit(rOut.GetInverseViewTransformation() * basegfx::B2DVector(1.0, 1.0)); 1673 1674 aPaintRange.expand(aPaintRange.getMaximum() + aSingleUnit); 1675 } 1676 1677 const basegfx::B2DRange aDefineRange( 1678 rOriginalLayoutRect.Left(), 1679 rOriginalLayoutRect.Top(), 1680 rOriginalLayoutRect.Right(), 1681 rOriginalLayoutRect.Bottom()); 1682 1683 const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rFillAttributes->getPrimitive2DSequence( 1684 aPaintRange, 1685 aDefineRange); 1686 1687 if(rSequence.getLength()) 1688 { 1689 const drawinglayer::geometry::ViewInformation2D aViewInformation2D( 1690 basegfx::B2DHomMatrix(), 1691 rOut.GetViewTransformation(), 1692 aPaintRange, 1693 0, 1694 0.0, 1695 uno::Sequence< beans::PropertyValue >()); 1696 drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice( 1697 rOut, 1698 aViewInformation2D); 1699 1700 if(pProcessor) 1701 { 1702 pProcessor->process(rSequence); 1703 1704 delete pProcessor; 1705 1706 if(bReturnWhenNew) 1707 { 1708 return true; 1709 } 1710 } 1711 } 1712 } 1713 } 1714 1715 return false; 1716 } 1717 1718 void MA_FASTCALL DrawGraphic( 1719 const SvxBrushItem *pBrush, 1720 OutputDevice *pOutDev, 1721 const SwRect &rOrg, 1722 const SwRect &rOut, 1723 const sal_uInt8 nGrfNum, 1724 const sal_Bool bConsiderBackgroundTransparency ) 1725 /// OD 05.08.2002 #99657# - add 6th parameter to indicate that method should 1726 /// consider background transparency, saved in the color of the brush item 1727 { 1728 ViewShell &rSh = *pGlobalShell; 1729 /// OD 17.10.2002 #103876# - change type from <sal_Bool> to <bool> 1730 bool bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum; 1731 bool bGrfNum = GRFNUM_NO != nGrfNum; 1732 Size aGrfSize; 1733 SvxGraphicPosition ePos = GPOS_NONE; 1734 if( pBrush && !bReplaceGrfNum ) 1735 { 1736 if( rSh.GetViewOptions()->IsGraphic() ) 1737 { 1738 //#125488#: load graphic directly in PDF import 1739 // --> OD 2006-08-25 #i68953# - also during print load graphic directly. 1740 if ( (rSh).GetViewOptions()->IsPDFExport() || 1741 rSh.GetOut()->GetOutDevType() == OUTDEV_PRINTER ) 1742 // <-- 1743 { 1744 ((SvxBrushItem*)pBrush)->PurgeMedium(); 1745 ((SvxBrushItem*)pBrush)->SetDoneLink( Link() ); 1746 } 1747 else 1748 ((SvxBrushItem*)pBrush)->SetDoneLink( STATIC_LINK( 1749 rSh.GetDoc(), SwDoc, BackgroundDone ) ); 1750 //SfxObjectShell &rObjSh = *GETOBJSHELL(); 1751 const Graphic* pGrf = pBrush->GetGraphic(); 1752 if( pGrf && GRAPHIC_NONE != pGrf->GetType() ) 1753 { 1754 ePos = pBrush->GetGraphicPos(); 1755 if( pGrf->IsSupportedGraphic() ) 1756 // don't the use the specific output device! Bug 94802 1757 aGrfSize = ::GetGraphicSizeTwip( *pGrf, 0 ); 1758 } 1759 } 1760 else 1761 bReplaceGrfNum = bGrfNum; 1762 } 1763 1764 SwRect aGrf; 1765 aGrf.SSize( aGrfSize ); 1766 sal_Bool bDraw = sal_True; 1767 sal_Bool bRetouche = sal_True; 1768 switch ( ePos ) 1769 { 1770 case GPOS_LT: 1771 aGrf.Pos() = rOrg.Pos(); 1772 break; 1773 1774 case GPOS_MT: 1775 aGrf.Pos().Y() = rOrg.Top(); 1776 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2; 1777 break; 1778 1779 case GPOS_RT: 1780 aGrf.Pos().Y() = rOrg.Top(); 1781 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width(); 1782 break; 1783 1784 case GPOS_LM: 1785 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2; 1786 aGrf.Pos().X() = rOrg.Left(); 1787 break; 1788 1789 case GPOS_MM: 1790 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2; 1791 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2; 1792 break; 1793 1794 case GPOS_RM: 1795 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2; 1796 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width(); 1797 break; 1798 1799 case GPOS_LB: 1800 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height(); 1801 aGrf.Pos().X() = rOrg.Left(); 1802 break; 1803 1804 case GPOS_MB: 1805 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height(); 1806 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2; 1807 break; 1808 1809 case GPOS_RB: 1810 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height(); 1811 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width(); 1812 break; 1813 1814 case GPOS_AREA: 1815 aGrf = rOrg; 1816 /// OD 05.09.2002 #102912# 1817 /// In spite the fact that the background graphic have to fill the complete 1818 /// area, it has been checked, if the graphic will completely fill out 1819 /// the region to be painted <rOut> and thus, nothing has to be retouched. 1820 /// For example, this is the case for a fly frame without a background 1821 /// brush positioned on the border of the page and inherited the 1822 /// background brush from the page. 1823 bRetouche = !rOut.IsInside( aGrf ); 1824 break; 1825 1826 case GPOS_TILED: 1827 { 1828 // OD 17.10.2002 #103876# - draw background of tiled graphic 1829 // before drawing tiled graphic in loop 1830 // determine graphic object 1831 GraphicObject* pGraphicObj = const_cast< GraphicObject* >(pBrush->GetGraphicObject()); 1832 // calculate aligned paint rectangle 1833 SwRect aAlignedPaintRect = rOut; 1834 ::SwAlignRect( aAlignedPaintRect, &rSh ); 1835 // OD 25.10.2002 #103876# - draw background color for aligned paint rectangle 1836 lcl_DrawGraphicBackgrd( *pBrush, pOutDev, aAlignedPaintRect, *pGraphicObj, bGrfNum ); 1837 1838 // set left-top-corner of background graphic to left-top-corner of the 1839 // area, from which the background brush is determined. 1840 aGrf.Pos() = rOrg.Pos(); 1841 // setup clipping at output device 1842 pOutDev->Push( PUSH_CLIPREGION ); 1843 pOutDev->IntersectClipRegion( rOut.SVRect() ); 1844 // OD 28.10.2002 #103876# - use new method <GraphicObject::DrawTiled(::)> 1845 { 1846 // calculate paint offset 1847 Point aPaintOffset( aAlignedPaintRect.Pos() - aGrf.Pos() ); 1848 // draw background graphic tiled for aligned paint rectangle 1849 // --> OD 2005-02-15 #i42643# - apply fix #104004# for Calc 1850 // also for Writer - see /sc/source/view/printfun.cxx 1851 // For PDF export, every draw operation for bitmaps takes a 1852 // noticeable amount of place (~50 characters). Thus, optimize 1853 // between tile bitmap size and number of drawing operations here. 1854 // 1855 // A_out 1856 // n_chars = k1 * ---------- + k2 * A_bitmap 1857 // A_bitmap 1858 // 1859 // minimum n_chars is obtained for (derive for A_bitmap, 1860 // set to 0, take positive solution): 1861 // k1 1862 // A_bitmap = Sqrt( ---- A_out ) 1863 // k2 1864 // 1865 // where k1 is the number of chars per draw operation, and 1866 // k2 is the number of chars per bitmap pixel. 1867 // This is approximately 50 and 7 for current PDF writer, respectively. 1868 // 1869 const double k1( 50 ); 1870 const double k2( 7 ); 1871 const Size aSize( aAlignedPaintRect.SSize() ); 1872 const double Abitmap( k1/k2 * static_cast<double>(aSize.Width())*aSize.Height() ); 1873 1874 pGraphicObj->DrawTiled( pOutDev, 1875 aAlignedPaintRect.SVRect(), 1876 aGrf.SSize(), 1877 Size( aPaintOffset.X(), aPaintOffset.Y() ), 1878 NULL, GRFMGR_DRAW_STANDARD, 1879 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) ); 1880 // <-- 1881 } 1882 // reset clipping at output device 1883 pOutDev->Pop(); 1884 // set <bDraw> and <bRetouche> to false, indicating that background 1885 // graphic and background are already drawn. 1886 bDraw = bRetouche = sal_False; 1887 } 1888 break; 1889 1890 case GPOS_NONE: 1891 bDraw = sal_False; 1892 break; 1893 1894 default: ASSERT( !pOutDev, "new Graphic position?" ); 1895 } 1896 1897 /// OD 02.09.2002 #99657# 1898 /// init variable <bGrfBackgrdAlreadDrawn> to indicate, if background of 1899 /// graphic is already drawn or not. 1900 bool bGrfBackgrdAlreadyDrawn = false; 1901 if ( bRetouche ) 1902 { 1903 // OD 2004-04-23 #116347# 1904 pOutDev->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 1905 pOutDev->SetLineColor(); 1906 1907 // OD 07.08.2002 #99657# #GetTransChg# 1908 // check, if a existing background graphic (not filling the complete 1909 // background) is transparent drawn and the background color is 1910 // "no fill" respectively "auto fill", if background transparency 1911 // has to be considered. 1912 // If YES, memorise transparency of background graphic. 1913 // check also, if background graphic bitmap is transparent. 1914 bool bTransparentGrfWithNoFillBackgrd = false; 1915 sal_Int32 nGrfTransparency = 0; 1916 bool bGrfIsTransparent = false; 1917 if ( (ePos != GPOS_NONE) && 1918 (ePos != GPOS_TILED) && (ePos != GPOS_AREA) 1919 ) 1920 { 1921 GraphicObject *pGrf = (GraphicObject*)pBrush->GetGraphicObject(); 1922 if ( bConsiderBackgroundTransparency ) 1923 { 1924 GraphicAttr pGrfAttr = pGrf->GetAttr(); 1925 if ( (pGrfAttr.GetTransparency() != 0) && 1926 ( pBrush && (pBrush->GetColor() == COL_TRANSPARENT) ) 1927 ) 1928 { 1929 bTransparentGrfWithNoFillBackgrd = true; 1930 nGrfTransparency = pGrfAttr.GetTransparency(); 1931 } 1932 } 1933 if ( pGrf->IsTransparent() ) 1934 { 1935 bGrfIsTransparent = true; 1936 } 1937 } 1938 1939 /// OD 06.08.2002 #99657# #GetTransChg# - to get color of brush, 1940 /// check background color against COL_TRANSPARENT ("no fill"/"auto fill") 1941 /// instead of checking, if transparency is not set. 1942 const Color aColor( pBrush && 1943 ( !(pBrush->GetColor() == COL_TRANSPARENT) || 1944 bFlyMetafile ) 1945 ? pBrush->GetColor() 1946 : aGlobalRetoucheColor ); 1947 1948 /// OD 08.08.2002 #99657# - determine, if background region have to be 1949 /// drawn transparent. 1950 /// background region has to be drawn transparent, if 1951 /// background transparency have to be considered 1952 /// AND 1953 /// ( background color is transparent OR 1954 /// background graphic is transparent and background color is "no fill" 1955 /// ) 1956 sal_Bool bDrawTransparent = bConsiderBackgroundTransparency && 1957 ( ( aColor.GetTransparency() != 0) || 1958 bTransparentGrfWithNoFillBackgrd ); 1959 1960 // --> OD 2008-06-02 #i75614# 1961 // reset draw mode in high contrast mode in order to get fill color set 1962 const sal_uLong nOldDrawMode = pOutDev->GetDrawMode(); 1963 if ( pGlobalShell->GetWin() && 1964 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 1965 { 1966 pOutDev->SetDrawMode( 0 ); 1967 } 1968 // <-- 1969 1970 /// OD 06.08.2002 #99657# - if background region have to be drawn 1971 /// transparent, set only the RGB values of the background color as 1972 /// the fill color for the output device. 1973 if ( bDrawTransparent ) 1974 { 1975 if( pOutDev->GetFillColor() != aColor.GetRGBColor() ) 1976 pOutDev->SetFillColor( aColor.GetRGBColor() ); 1977 } 1978 else 1979 { 1980 if( pOutDev->GetFillColor() != aColor ) 1981 pOutDev->SetFillColor( aColor ); 1982 } 1983 1984 // --> OD 2008-06-02 #i75614# 1985 // restore draw mode 1986 pOutDev->SetDrawMode( nOldDrawMode ); 1987 // <-- 1988 1989 /// OD 02.09.2002 #99657# 1990 if ( bDrawTransparent ) 1991 { 1992 /// background region have to be drawn transparent. 1993 /// Thus, create a poly-polygon from the region and draw it with 1994 /// the corresponding transparency precent. 1995 PolyPolygon aDrawPoly( rOut.SVRect() ); 1996 if ( aGrf.HasArea() ) 1997 { 1998 if ( !bGrfIsTransparent ) 1999 { 2000 /// subtract area of background graphic from draw area 2001 /// OD 08.10.2002 #103898# - consider only that part of the 2002 /// graphic area that is overlapping with draw area. 2003 SwRect aTmpGrf = aGrf; 2004 aTmpGrf.Intersection( rOut ); 2005 if ( aTmpGrf.HasArea() ) 2006 { 2007 Polygon aGrfPoly( aTmpGrf.SVRect() ); 2008 aDrawPoly.Insert( aGrfPoly ); 2009 } 2010 } 2011 else 2012 bGrfBackgrdAlreadyDrawn = true; 2013 } 2014 /// calculate transparency percent: 2015 /// ( <transparency value[0x01..0xFF]>*100 + 0x7F ) / 0xFF 2016 /// If there is a background graphic with a background color "no fill"/"auto fill", 2017 /// the transparency value is taken from the background graphic, 2018 /// otherwise take the transparency value from the color. 2019 sal_Int8 nTransparencyPercent = static_cast<sal_Int8>( 2020 (( bTransparentGrfWithNoFillBackgrd ? nGrfTransparency : aColor.GetTransparency() 2021 )*100 + 0x7F)/0xFF); 2022 /// draw poly-polygon transparent 2023 pOutDev->DrawTransparent( aDrawPoly, nTransparencyPercent ); 2024 } 2025 else 2026 { 2027 SwRegionRects aRegion( rOut, 4 ); 2028 if ( !bGrfIsTransparent ) 2029 aRegion -= aGrf; 2030 else 2031 bGrfBackgrdAlreadyDrawn = true; 2032 /// loop rectangles of background region, which has to be drawn 2033 for( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 2034 { 2035 pOutDev->DrawRect( aRegion[i].SVRect() ); 2036 } 2037 } 2038 pOutDev ->Pop(); 2039 } 2040 2041 if( bDraw && aGrf.IsOver( rOut ) ) 2042 /// OD 02.09.2002 #99657# 2043 /// add parameter <bGrfBackgrdAlreadyDrawn> 2044 lcl_DrawGraphic( *pBrush, pOutDev, rSh, aGrf, rOut, true, bGrfNum, 2045 bGrfBackgrdAlreadyDrawn ); 2046 2047 if( bReplaceGrfNum ) 2048 { 2049 const BitmapEx& rBmp = ViewShell::GetReplacementBitmap( false ); 2050 Font aTmp( pOutDev->GetFont() ); 2051 Graphic::DrawEx( pOutDev, aEmptyStr, aTmp, rBmp, rOrg.Pos(), rOrg.SSize() ); 2052 } 2053 } 2054 2055 //------------------------------------------------------------------------ 2056 2057 /** local help method for SwRootFrm::Paint(..) - Adjust given rectangle to pixel size 2058 2059 By OD at 27.09.2002 for #103636# 2060 In order to avoid paint errors caused by multiple alignments - e.g. method 2061 ::SwAlignRect(..) - and other changes to the rectangle to be painted, 2062 this method is called for the rectangle to be painted in order to 2063 adjust it to the pixel it is overlapping. 2064 2065 @author OD 2066 */ 2067 void lcl_AdjustRectToPixelSize( SwRect& io_aSwRect, const OutputDevice &aOut ) 2068 { 2069 /// local constant object of class <Size> to determine number of Twips 2070 /// representing a pixel. 2071 const Size aTwipToPxSize( aOut.PixelToLogic( Size( 1,1 )) ); 2072 2073 /// local object of class <Rectangle> in Twip coordinates 2074 /// calculated from given rectangle aligned to pixel centers. 2075 const Rectangle aPxCenterRect = aOut.PixelToLogic( 2076 aOut.LogicToPixel( io_aSwRect.SVRect() ) ); 2077 2078 /// local constant object of class <Rectangle> representing given rectangle 2079 /// in pixel. 2080 const Rectangle aOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() ); 2081 2082 /// calculate adjusted rectangle from pixel centered rectangle. 2083 /// Due to rounding differences <aPxCenterRect> doesn't exactly represents 2084 /// the Twip-centers. Thus, adjust borders by half of pixel width/height plus 1. 2085 /// Afterwards, adjust calculated Twip-positions of the all borders. 2086 Rectangle aSizedRect = aPxCenterRect; 2087 aSizedRect.Left() -= (aTwipToPxSize.Width()/2 + 1); 2088 aSizedRect.Right() += (aTwipToPxSize.Width()/2 + 1); 2089 aSizedRect.Top() -= (aTwipToPxSize.Height()/2 + 1); 2090 aSizedRect.Bottom() += (aTwipToPxSize.Height()/2 + 1); 2091 2092 /// adjust left() 2093 while ( (aOut.LogicToPixel(aSizedRect)).Left() < aOrgPxRect.Left() ) 2094 { 2095 ++aSizedRect.Left(); 2096 } 2097 /// adjust right() 2098 while ( (aOut.LogicToPixel(aSizedRect)).Right() > aOrgPxRect.Right() ) 2099 { 2100 --aSizedRect.Right(); 2101 } 2102 /// adjust top() 2103 while ( (aOut.LogicToPixel(aSizedRect)).Top() < aOrgPxRect.Top() ) 2104 { 2105 ++aSizedRect.Top(); 2106 } 2107 /// adjust bottom() 2108 while ( (aOut.LogicToPixel(aSizedRect)).Bottom() > aOrgPxRect.Bottom() ) 2109 { 2110 --aSizedRect.Bottom(); 2111 } 2112 2113 io_aSwRect = SwRect( aSizedRect ); 2114 2115 #ifdef DBG_UTIL 2116 Rectangle aTestOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() ); 2117 Rectangle aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2118 ASSERT( aTestOrgPxRect == aTestNewPxRect, 2119 "Error in lcl_AlignRectToPixelSize(..): Adjusted rectangle has incorrect position or size"); 2120 #if OSL_DEBUG_LEVEL > 1 2121 Rectangle aTestNewRect( aSizedRect ); 2122 /// check Left() 2123 --aSizedRect.Left(); 2124 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2125 ASSERT( aTestOrgPxRect.Left() >= (aTestNewPxRect.Left()+1), 2126 "Error in lcl_AlignRectToPixelSize(..): Left() not correct adjusted"); 2127 ++aSizedRect.Left(); 2128 /// check Right() 2129 ++aSizedRect.Right(); 2130 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2131 ASSERT( aTestOrgPxRect.Right() <= (aTestNewPxRect.Right()-1), 2132 "Error in lcl_AlignRectToPixelSize(..): Right() not correct adjusted"); 2133 --aSizedRect.Right(); 2134 /// check Top() 2135 --aSizedRect.Top(); 2136 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2137 ASSERT( aTestOrgPxRect.Top() >= (aTestNewPxRect.Top()+1), 2138 "Error in lcl_AlignRectToPixelSize(..): Top() not correct adjusted"); 2139 ++aSizedRect.Top(); 2140 /// check Bottom() 2141 ++aSizedRect.Bottom(); 2142 aTestNewPxRect = aOut.LogicToPixel( aSizedRect ); 2143 ASSERT( aTestOrgPxRect.Bottom() <= (aTestNewPxRect.Bottom()-1), 2144 "Error in lcl_AlignRectToPixelSize(..): Bottom() not correct adjusted"); 2145 --aSizedRect.Bottom(); 2146 #endif 2147 #endif 2148 } 2149 2150 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES START 2151 2152 struct SwLineEntry 2153 { 2154 SwTwips mnKey; 2155 SwTwips mnStartPos; 2156 SwTwips mnEndPos; 2157 2158 svx::frame::Style maAttribute; 2159 2160 enum OverlapType { NO_OVERLAP, OVERLAP1, OVERLAP2, OVERLAP3 }; 2161 2162 public: 2163 SwLineEntry( SwTwips nKey, 2164 SwTwips nStartPos, 2165 SwTwips nEndPos, 2166 const svx::frame::Style& rAttribute ); 2167 2168 OverlapType Overlaps( const SwLineEntry& rComp ) const; 2169 }; 2170 2171 SwLineEntry::SwLineEntry( SwTwips nKey, 2172 SwTwips nStartPos, 2173 SwTwips nEndPos, 2174 const svx::frame::Style& rAttribute ) 2175 : mnKey( nKey ), 2176 mnStartPos( nStartPos ), 2177 mnEndPos( nEndPos ), 2178 maAttribute( rAttribute ) 2179 { 2180 } 2181 2182 /* 2183 2184 1. ---------- rOld 2185 ---------- rNew 2186 2187 2. ---------- rOld 2188 ------------- rNew 2189 2190 3. ------- rOld 2191 ------------- rNew 2192 2193 4. ------------- rOld 2194 ---------- rNew 2195 2196 5. ---------- rOld 2197 ---- rNew 2198 2199 6. ---------- rOld 2200 ---------- rNew 2201 2202 7. ------------- rOld 2203 ---------- rNew 2204 2205 8. ---------- rOld 2206 ------------- rNew 2207 2208 9. ---------- rOld 2209 ---------- rNew 2210 */ 2211 2212 SwLineEntry::OverlapType SwLineEntry::Overlaps( const SwLineEntry& rNew ) const 2213 { 2214 SwLineEntry::OverlapType eRet = OVERLAP3; 2215 2216 if ( mnStartPos >= rNew.mnEndPos || mnEndPos <= rNew.mnStartPos ) 2217 eRet = NO_OVERLAP; 2218 2219 // 1, 2, 3 2220 else if ( mnEndPos < rNew.mnEndPos ) 2221 eRet = OVERLAP1; 2222 2223 // 4, 5, 6, 7 2224 else if ( mnStartPos <= rNew.mnStartPos && mnEndPos >= rNew.mnEndPos ) 2225 eRet = OVERLAP2; 2226 2227 // 8, 9 2228 return eRet; 2229 } 2230 2231 struct lt_SwLineEntry 2232 { 2233 bool operator()( const SwLineEntry& e1, const SwLineEntry& e2 ) const 2234 { 2235 return e1.mnStartPos < e2.mnStartPos; 2236 } 2237 }; 2238 2239 typedef std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet; 2240 typedef std::set< SwLineEntry, lt_SwLineEntry >::iterator SwLineEntrySetIter; 2241 typedef std::set< SwLineEntry, lt_SwLineEntry >::const_iterator SwLineEntrySetConstIter; 2242 typedef std::map< SwTwips, SwLineEntrySet > SwLineEntryMap; 2243 typedef std::map< SwTwips, SwLineEntrySet >::iterator SwLineEntryMapIter; 2244 typedef std::map< SwTwips, SwLineEntrySet >::const_iterator SwLineEntryMapConstIter; 2245 2246 class SwTabFrmPainter 2247 { 2248 SwLineEntryMap maVertLines; 2249 SwLineEntryMap maHoriLines; 2250 const SwTabFrm& mrTabFrm; 2251 2252 void Insert( SwLineEntry&, bool bHori ); 2253 void Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem ); 2254 void HandleFrame( const SwLayoutFrm& rFrm ); 2255 void FindStylesForLine( const Point&, 2256 const Point&, 2257 svx::frame::Style*, 2258 bool bHori ) const; 2259 2260 public: 2261 SwTabFrmPainter( const SwTabFrm& rTabFrm ); 2262 2263 void PaintLines( OutputDevice& rDev, const SwRect& rRect ) const; 2264 }; 2265 2266 SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm ) 2267 : mrTabFrm( rTabFrm ) 2268 { 2269 HandleFrame( rTabFrm ); 2270 } 2271 2272 void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm ) 2273 { 2274 // Add border lines of cell frames. Skip covered cells. Skip cells 2275 // in special row span row, which do not have a negative row span: 2276 if ( rLayoutFrm.IsCellFrm() && !rLayoutFrm.IsCoveredCell() ) 2277 { 2278 const SwCellFrm* pThisCell = static_cast<const SwCellFrm*>(&rLayoutFrm); 2279 const SwRowFrm* pRowFrm = static_cast<const SwRowFrm*>(pThisCell->GetUpper()); 2280 const long nRowSpan = pThisCell->GetTabBox()->getRowSpan(); 2281 if ( !pRowFrm->IsRowSpanLine() || nRowSpan > 1 || nRowSpan < -1 ) 2282 { 2283 SwBorderAttrAccess aAccess( SwFrm::GetCache(), &rLayoutFrm ); 2284 const SwBorderAttrs& rAttrs = *aAccess.Get(); 2285 const SvxBoxItem& rBox = rAttrs.GetBox(); 2286 Insert( rLayoutFrm, rBox ); 2287 } 2288 } 2289 2290 // Recurse into lower layout frames, but do not recurse into lower tabframes. 2291 const SwFrm* pLower = rLayoutFrm.Lower(); 2292 while ( pLower ) 2293 { 2294 const SwLayoutFrm* pLowerLayFrm = dynamic_cast<const SwLayoutFrm*>(pLower); 2295 if ( pLowerLayFrm && !pLowerLayFrm->IsTabFrm() ) 2296 HandleFrame( *pLowerLayFrm ); 2297 2298 pLower = pLower->GetNext(); 2299 } 2300 } 2301 2302 void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) const 2303 { 2304 // --> FME 2004-06-24 #i16816# tagged pdf support 2305 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev ); 2306 // <-- 2307 2308 const SwFrm* pTmpFrm = &mrTabFrm; 2309 const bool bVert = pTmpFrm->IsVertical(); 2310 2311 SwLineEntryMapConstIter aIter = maHoriLines.begin(); 2312 bool bHori = true; 2313 2314 // color for subsidiary lines: 2315 const Color& rCol( SwViewOption::GetTableBoundariesColor() ); 2316 2317 // high contrast mode: 2318 // overrides the color of non-subsidiary lines. 2319 const Color* pHCColor = 0; 2320 sal_uLong nOldDrawMode = rDev.GetDrawMode(); 2321 if( pGlobalShell->GetWin() && 2322 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 2323 { 2324 pHCColor = &SwViewOption::GetFontColor(); 2325 rDev.SetDrawMode( 0 ); 2326 } 2327 2328 // set clip region: 2329 rDev.Push( PUSH_CLIPREGION ); 2330 Size aSize( rRect.SSize() ); 2331 // Hack! Necessary, because the layout is not pixel aligned! 2332 aSize.Width() += nPixelSzW; aSize.Height() += nPixelSzH; 2333 rDev.SetClipRegion( Rectangle( rRect.Pos(), aSize ) ); 2334 2335 // The following stuff if necessary to have the new table borders fit 2336 // into a ::SwAlignRect adjusted world. 2337 const SwTwips nTwipXCorr = bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-) 2338 const SwTwips nTwipYCorr = !bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-) 2339 const SwFrm* pUpper = mrTabFrm.GetUpper(); 2340 SwRect aUpper( pUpper->Prt() ); 2341 aUpper.Pos() += pUpper->Frm().Pos(); 2342 SwRect aUpperAligned( aUpper ); 2343 ::SwAlignRect( aUpperAligned, pGlobalShell ); 2344 2345 while ( true ) 2346 { 2347 if ( bHori && aIter == maHoriLines.end() ) 2348 { 2349 aIter = maVertLines.begin(); 2350 bHori = false; 2351 } 2352 2353 if ( !bHori && aIter == maVertLines.end() ) 2354 break; 2355 2356 const SwLineEntrySet& rEntrySet = (*aIter).second; 2357 SwLineEntrySetConstIter aSetIter = rEntrySet.begin(); 2358 while ( aSetIter != rEntrySet.end() ) 2359 { 2360 const SwLineEntry& rEntry = *aSetIter; 2361 const svx::frame::Style& rEntryStyle( (*aSetIter).maAttribute ); 2362 2363 Point aStart, aEnd; 2364 if ( bHori ) 2365 { 2366 aStart.X() = rEntry.mnStartPos; 2367 aStart.Y() = rEntry.mnKey; 2368 aEnd.X() = rEntry.mnEndPos; 2369 aEnd.Y() = rEntry.mnKey; 2370 } 2371 else 2372 { 2373 aStart.X() = rEntry.mnKey; 2374 aStart.Y() = rEntry.mnStartPos; 2375 aEnd.X() = rEntry.mnKey; 2376 aEnd.Y() = rEntry.mnEndPos; 2377 } 2378 2379 SwRect aRepaintRect( aStart, aEnd ); 2380 2381 // the repaint rectangle has to be moved a bit for the centered lines: 2382 SwTwips nRepaintRectSize = !rEntryStyle.GetWidth() ? 1 : rEntryStyle.GetWidth(); 2383 if ( bHori ) 2384 { 2385 aRepaintRect.Height( 2 * nRepaintRectSize ); 2386 aRepaintRect.Pos().Y() -= nRepaintRectSize; 2387 } 2388 else 2389 { 2390 aRepaintRect.Width( 2 * nRepaintRectSize ); 2391 aRepaintRect.Pos().X() -= nRepaintRectSize; 2392 } 2393 2394 if ( rRect.IsOver( aRepaintRect ) ) 2395 { 2396 svx::frame::Style aStyles[ 7 ]; 2397 aStyles[ 0 ] = rEntryStyle; 2398 FindStylesForLine( aStart, aEnd, aStyles, bHori ); 2399 2400 // subsidiary lines 2401 const Color* pTmpColor = 0; 2402 if ( 0 == aStyles[ 0 ].GetWidth() ) 2403 { 2404 if ( IS_SUBS_TABLE && pGlobalShell->GetWin() ) 2405 aStyles[ 0 ].Set( rCol, 1, 0, 0 ); 2406 } 2407 else 2408 pTmpColor = pHCColor; 2409 2410 // The line sizes stored in the line style have to be adjusted as well. 2411 // This will guarantee that lines with the same twip size will have the 2412 // same pixel size. 2413 for ( int i = 0; i < 7; ++i ) 2414 { 2415 sal_uInt16 nPrim = aStyles[ i ].Prim(); 2416 sal_uInt16 nDist = aStyles[ i ].Dist(); 2417 sal_uInt16 nSecn = aStyles[ i ].Secn(); 2418 2419 if ( nPrim > 0 ) 2420 nPrim = (sal_uInt16)( Max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) ); 2421 if ( nDist > 0 ) 2422 nDist = (sal_uInt16)( Max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) ); 2423 if ( nSecn > 0 ) 2424 nSecn = (sal_uInt16)( Max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) ); 2425 2426 aStyles[ i ].Set( nPrim, nDist, nSecn ); 2427 } 2428 2429 // The (twip) positions will be adjusted to meet these requirements: 2430 // 1. The y coordinates are located in the middle of the pixel grid 2431 // 2. The x coordinated are located at the beginning of the pixel grid 2432 // This is done, because the horizontal lines are painted "at beginning", 2433 // whereas the vertical lines are painted "centered". By making the line 2434 // sizes a multiple of one pixel size, we can assure, that all lines having 2435 // the same twip size have the same pixel size, independent of their position 2436 // on the screen. 2437 Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel( aStart ) ); 2438 Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel( aEnd ) ); 2439 2440 if( pGlobalShell->GetWin() ) 2441 { 2442 // The table borders do not use SwAlignRect, but all the other frames do. 2443 // Therefore we tweak the outer borders a bit to achieve that the outer 2444 // borders match the subsidiary lines of the upper: 2445 if ( aStart.X() == aUpper.Left() ) 2446 aPaintStart.X() = aUpperAligned.Left(); 2447 else if ( aStart.X() == aUpper._Right() ) 2448 aPaintStart.X() = aUpperAligned._Right(); 2449 if ( aStart.Y() == aUpper.Top() ) 2450 aPaintStart.Y() = aUpperAligned.Top(); 2451 else if ( aStart.Y() == aUpper._Bottom() ) 2452 aPaintStart.Y() = aUpperAligned._Bottom(); 2453 2454 if ( aEnd.X() == aUpper.Left() ) 2455 aPaintEnd.X() = aUpperAligned.Left(); 2456 else if ( aEnd.X() == aUpper._Right() ) 2457 aPaintEnd.X() = aUpperAligned._Right(); 2458 if ( aEnd.Y() == aUpper.Top() ) 2459 aPaintEnd.Y() = aUpperAligned.Top(); 2460 else if ( aEnd.Y() == aUpper._Bottom() ) 2461 aPaintEnd.Y() = aUpperAligned._Bottom(); 2462 } 2463 2464 aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel 2465 aPaintEnd.X() -= nTwipXCorr; 2466 aPaintStart.Y() -= nTwipYCorr; 2467 aPaintEnd.Y() -= nTwipYCorr; 2468 2469 // Here comes the painting stuff: Thank you, DR, great job!!! 2470 if ( bHori ) 2471 { 2472 svx::frame::DrawHorFrameBorder 2473 ( 2474 rDev, 2475 aPaintStart, 2476 aPaintEnd, 2477 aStyles[ 0 ], // current style 2478 aStyles[ 1 ], // aLFromT 2479 aStyles[ 2 ], // aLFromL 2480 aStyles[ 3 ], // aLFromB 2481 aStyles[ 4 ], // aRFromT 2482 aStyles[ 5 ], // aRFromR 2483 aStyles[ 6 ], // aRFromB 2484 pTmpColor 2485 ); 2486 } 2487 else 2488 { 2489 svx::frame::DrawVerFrameBorder 2490 ( 2491 rDev, 2492 aPaintStart, 2493 aPaintEnd, 2494 aStyles[ 0 ], // current style 2495 aStyles[ 1 ], // aTFromL 2496 aStyles[ 2 ], // aTFromT 2497 aStyles[ 3 ], // aTFromR 2498 aStyles[ 4 ], // aBFromL 2499 aStyles[ 5 ], // aBFromB 2500 aStyles[ 6 ], // aBFromR 2501 pTmpColor 2502 ); 2503 } 2504 } 2505 2506 ++aSetIter; 2507 } 2508 2509 ++aIter; 2510 } 2511 2512 // restore output device: 2513 rDev.Pop(); 2514 rDev.SetDrawMode( nOldDrawMode ); 2515 } 2516 2517 // Finds the lines that join the line defined by (StartPoint, EndPoint) in either 2518 // StartPoint or Endpoint. The styles of these lines are required for DR's magic 2519 // line painting functions. 2520 void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint, 2521 const Point& rEndPoint, 2522 svx::frame::Style* pStyles, 2523 bool bHori ) const 2524 { 2525 // pStyles[ 1 ] = bHori ? aLFromT : TFromL 2526 // pStyles[ 2 ] = bHori ? aLFromL : TFromT, 2527 // pStyles[ 3 ] = bHori ? aLFromB : TFromR, 2528 // pStyles[ 4 ] = bHori ? aRFromT : BFromL, 2529 // pStyles[ 5 ] = bHori ? aRFromR : BFromB, 2530 // pStyles[ 6 ] = bHori ? aRFromB : BFromR, 2531 2532 SwLineEntryMapConstIter aMapIter = maVertLines.find( rStartPoint.X() ); 2533 ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" ) 2534 const SwLineEntrySet& rVertSet = (*aMapIter).second; 2535 SwLineEntrySetConstIter aIter = rVertSet.begin(); 2536 2537 while ( aIter != rVertSet.end() ) 2538 { 2539 const SwLineEntry& rEntry = *aIter; 2540 if ( bHori ) 2541 { 2542 if ( rStartPoint.Y() == rEntry.mnStartPos ) 2543 pStyles[ 3 ] = rEntry.maAttribute; 2544 else if ( rStartPoint.Y() == rEntry.mnEndPos ) 2545 pStyles[ 1 ] = rEntry.maAttribute; 2546 } 2547 else 2548 { 2549 if ( rStartPoint.Y() == rEntry.mnEndPos ) 2550 pStyles[ 2 ] = rEntry.maAttribute; 2551 else if ( rEndPoint.Y() == rEntry.mnStartPos ) 2552 pStyles[ 5 ] = rEntry.maAttribute; 2553 } 2554 ++aIter; 2555 } 2556 2557 aMapIter = maHoriLines.find( rStartPoint.Y() ); 2558 ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" ) 2559 const SwLineEntrySet& rHoriSet = (*aMapIter).second; 2560 aIter = rHoriSet.begin(); 2561 2562 while ( aIter != rHoriSet.end() ) 2563 { 2564 const SwLineEntry& rEntry = *aIter; 2565 if ( bHori ) 2566 { 2567 if ( rStartPoint.X() == rEntry.mnEndPos ) 2568 pStyles[ 2 ] = rEntry.maAttribute; 2569 else if ( rEndPoint.X() == rEntry.mnStartPos ) 2570 pStyles[ 5 ] = rEntry.maAttribute; 2571 } 2572 else 2573 { 2574 if ( rStartPoint.X() == rEntry.mnEndPos ) 2575 pStyles[ 1 ] = rEntry.maAttribute; 2576 else if ( rStartPoint.X() == rEntry.mnStartPos ) 2577 pStyles[ 3 ] = rEntry.maAttribute; 2578 } 2579 ++aIter; 2580 } 2581 2582 if ( bHori ) 2583 { 2584 aMapIter = maVertLines.find( rEndPoint.X() ); 2585 ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" ) 2586 const SwLineEntrySet& rVertSet2 = (*aMapIter).second; 2587 aIter = rVertSet2.begin(); 2588 2589 while ( aIter != rVertSet2.end() ) 2590 { 2591 const SwLineEntry& rEntry = *aIter; 2592 if ( rEndPoint.Y() == rEntry.mnStartPos ) 2593 pStyles[ 6 ] = rEntry.maAttribute; 2594 else if ( rEndPoint.Y() == rEntry.mnEndPos ) 2595 pStyles[ 4 ] = rEntry.maAttribute; 2596 ++aIter; 2597 } 2598 } 2599 else 2600 { 2601 aMapIter = maHoriLines.find( rEndPoint.Y() ); 2602 ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" ) 2603 const SwLineEntrySet& rHoriSet2 = (*aMapIter).second; 2604 aIter = rHoriSet2.begin(); 2605 2606 while ( aIter != rHoriSet2.end() ) 2607 { 2608 const SwLineEntry& rEntry = *aIter; 2609 if ( rEndPoint.X() == rEntry.mnEndPos ) 2610 pStyles[ 4 ] = rEntry.maAttribute; 2611 else if ( rEndPoint.X() == rEntry.mnStartPos ) 2612 pStyles[ 6 ] = rEntry.maAttribute; 2613 ++aIter; 2614 } 2615 } 2616 } 2617 2618 void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem ) 2619 { 2620 std::vector< const SwFrm* > aTestVec; 2621 aTestVec.push_back( &rFrm ); 2622 aTestVec.push_back( &rFrm ); 2623 aTestVec.push_back( &rFrm ); 2624 2625 // build 4 line entries for the 4 borders: 2626 SwRect aBorderRect = rFrm.Frm(); 2627 if ( rFrm.IsTabFrm() ) 2628 { 2629 aBorderRect = rFrm.Prt(); 2630 aBorderRect.Pos() += rFrm.Frm().Pos(); 2631 } 2632 2633 const SwTwips nLeft = aBorderRect._Left(); 2634 const SwTwips nRight = aBorderRect._Right(); 2635 const SwTwips nTop = aBorderRect._Top(); 2636 const SwTwips nBottom = aBorderRect._Bottom(); 2637 2638 svx::frame::Style aL( rBoxItem.GetLeft() ); 2639 svx::frame::Style aR( rBoxItem.GetRight() ); 2640 svx::frame::Style aT( rBoxItem.GetTop() ); 2641 svx::frame::Style aB( rBoxItem.GetBottom() ); 2642 2643 aR.MirrorSelf(); 2644 aB.MirrorSelf(); 2645 2646 bool bVert = mrTabFrm.IsVertical(); 2647 bool bR2L = mrTabFrm.IsRightToLeft(); 2648 2649 aL.SetRefMode( svx::frame::REFMODE_CENTERED ); 2650 aR.SetRefMode( svx::frame::REFMODE_CENTERED ); 2651 aT.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END ); 2652 aB.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END ); 2653 2654 SwLineEntry aLeft ( nLeft, nTop, nBottom, bVert ? aB : ( bR2L ? aR : aL ) ); 2655 SwLineEntry aRight ( nRight, nTop, nBottom, bVert ? aT : ( bR2L ? aL : aR ) ); 2656 SwLineEntry aTop ( nTop, nLeft, nRight, bVert ? aL : aT ); 2657 SwLineEntry aBottom( nBottom, nLeft, nRight, bVert ? aR : aB ); 2658 2659 Insert( aLeft, false ); 2660 Insert( aRight, false ); 2661 Insert( aTop, true ); 2662 Insert( aBottom, true ); 2663 2664 const SwRowFrm* pThisRowFrm = dynamic_cast<const SwRowFrm*>(rFrm.GetUpper()); 2665 2666 // special case: #i9860# 2667 // first line in follow table without repeated headlines 2668 if ( pThisRowFrm && 2669 pThisRowFrm->GetUpper() == &mrTabFrm && 2670 mrTabFrm.IsFollow() && 2671 !mrTabFrm.GetTable()->GetRowsToRepeat() && 2672 (!pThisRowFrm->GetPrev() || static_cast<const SwRowFrm*>(pThisRowFrm->GetPrev())->IsRowSpanLine()) && 2673 !rBoxItem.GetTop() && 2674 rBoxItem.GetBottom() ) 2675 { 2676 SwLineEntry aFollowTop( !bVert ? nTop : nRight, !bVert ? nLeft : nTop, !bVert ? nRight : nBottom, aB ); 2677 Insert( aFollowTop, !bVert ); 2678 } 2679 } 2680 2681 void SwTabFrmPainter::Insert( SwLineEntry& rNew, bool bHori ) 2682 { 2683 // get all lines from structure, that have key entry of pLE 2684 SwLineEntryMap* pLine2 = bHori ? &maHoriLines : &maVertLines; 2685 const SwTwips nKey = rNew.mnKey; 2686 SwLineEntryMapIter aMapIter = pLine2->find( nKey ); 2687 2688 SwLineEntrySet* pLineSet = aMapIter != pLine2->end() ? &((*aMapIter).second) : 0; 2689 if ( !pLineSet ) 2690 { 2691 SwLineEntrySet aNewSet; 2692 (*pLine2)[ nKey ] = aNewSet; 2693 pLineSet = &(*pLine2)[ nKey ]; 2694 } 2695 SwLineEntrySetIter aIter = pLineSet->begin(); 2696 2697 while ( pLineSet && aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos ) 2698 { 2699 const SwLineEntry& rOld = *aIter; 2700 const SwLineEntry::OverlapType nOverlapType = rOld.Overlaps( rNew ); 2701 2702 const svx::frame::Style& rOldAttr = rOld.maAttribute; 2703 const svx::frame::Style& rNewAttr = rNew.maAttribute; 2704 const svx::frame::Style& rCmpAttr = rNewAttr > rOldAttr ? rNewAttr : rOldAttr; 2705 2706 if ( SwLineEntry::OVERLAP1 == nOverlapType ) 2707 { 2708 ASSERT( rNew.mnStartPos >= rOld.mnStartPos, "Overlap type 3? How this?" ) 2709 2710 // new left segment 2711 const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr ); 2712 2713 // new middle segment 2714 const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rOld.mnEndPos, rCmpAttr ); 2715 2716 // new right segment 2717 rNew.mnStartPos = rOld.mnEndPos; 2718 2719 // update current lines set 2720 pLineSet->erase( aIter ); 2721 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft ); 2722 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle ); 2723 2724 aIter = pLineSet->begin(); 2725 2726 continue; // start over 2727 } 2728 else if ( SwLineEntry::OVERLAP2 == nOverlapType ) 2729 { 2730 // new left segment 2731 const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr ); 2732 2733 // new middle segment 2734 const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rNew.mnEndPos, rCmpAttr ); 2735 2736 // new right segment 2737 const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr ); 2738 2739 // update current lines set 2740 pLineSet->erase( aIter ); 2741 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft ); 2742 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle ); 2743 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight ); 2744 2745 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted! 2746 2747 break; // we are finished 2748 } 2749 else if ( SwLineEntry::OVERLAP3 == nOverlapType ) 2750 { 2751 // new left segment 2752 const SwLineEntry aLeft( nKey, rNew.mnStartPos, rOld.mnStartPos, rNewAttr ); 2753 2754 // new middle segment 2755 const SwLineEntry aMiddle( nKey, rOld.mnStartPos, rNew.mnEndPos, rCmpAttr ); 2756 2757 // new right segment 2758 const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr ); 2759 2760 // update current lines set 2761 pLineSet->erase( aIter ); 2762 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft ); 2763 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle ); 2764 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight ); 2765 2766 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted! 2767 2768 break; // we are finished 2769 } 2770 2771 ++aIter; 2772 } 2773 2774 if ( rNew.mnStartPos < rNew.mnEndPos ) // insert rest 2775 pLineSet->insert( rNew ); 2776 } 2777 2778 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES END 2779 2780 // --> OD #i76669# 2781 namespace 2782 { 2783 class SwViewObjectContactRedirector : public ::sdr::contact::ViewObjectContactRedirector 2784 { 2785 private: 2786 const ViewShell& mrViewShell; 2787 2788 public: 2789 SwViewObjectContactRedirector( const ViewShell& rSh ) 2790 : mrViewShell( rSh ) 2791 {}; 2792 2793 virtual ~SwViewObjectContactRedirector() 2794 {} 2795 2796 virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence( 2797 const sdr::contact::ViewObjectContact& rOriginal, 2798 const sdr::contact::DisplayInfo& rDisplayInfo) 2799 { 2800 sal_Bool bPaint( sal_True ); 2801 2802 SdrObject* pObj = rOriginal.GetViewContact().TryToGetSdrObject(); 2803 if ( pObj ) 2804 { 2805 bPaint = SwFlyFrm::IsPaint( pObj, &mrViewShell ); 2806 } 2807 2808 if ( !bPaint ) 2809 { 2810 return drawinglayer::primitive2d::Primitive2DSequence(); 2811 } 2812 2813 return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( 2814 rOriginal, rDisplayInfo ); 2815 } 2816 }; 2817 2818 } // end of anonymous namespace 2819 // <-- 2820 2821 /************************************************************************* 2822 |* SwRootFrm::Paint() 2823 |* 2824 |* Beschreibung 2825 |* Fuer jede sichtbare Seite, die von Rect berührt wird einmal Painten. 2826 |* 1. Umrandungen und Hintergruende Painten. 2827 |* 2. Den Draw Layer (Rahmen und Zeichenobjekte) der unter dem Dokument 2828 |* liegt painten (Hoelle). 2829 |* 3. Den Dokumentinhalt (Text) Painten. 2830 |* 4. Den Drawlayer der über dem Dokument liegt painten. 2831 |* 2832 |* Ersterstellung MA 01. Jun. 92 2833 |* Letzte Änderung MA 10. Oct. 97 2834 |*************************************************************************/ 2835 2836 void 2837 SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const 2838 { 2839 ASSERT( Lower() && Lower()->IsPageFrm(), "Lower der Root keine Seite." ); 2840 2841 PROTOCOL( this, PROT_FILE_INIT, 0, 0) 2842 2843 sal_Bool bResetRootPaint = sal_False; 2844 ViewShell *pSh = pCurrShell; 2845 2846 if ( pSh->GetWin() ) 2847 { 2848 if ( pSh->GetOut() == pSh->GetWin() && !pSh->GetWin()->IsVisible() ) 2849 { 2850 return; 2851 } 2852 if ( SwRootFrm::bInPaint ) 2853 { 2854 SwPaintQueue::Add( pSh, rRect ); 2855 return; 2856 } 2857 } 2858 else 2859 SwRootFrm::bInPaint = bResetRootPaint = sal_True; 2860 2861 SwSavePaintStatics *pStatics = 0; 2862 if ( pGlobalShell ) 2863 pStatics = new SwSavePaintStatics(); 2864 pGlobalShell = pSh; 2865 2866 if( !pSh->GetWin() ) 2867 pProgress = SfxProgress::GetActiveProgress( (SfxObjectShell*) pSh->GetDoc()->GetDocShell() ); 2868 2869 ::SwCalcPixStatics( pSh->GetOut() ); 2870 aGlobalRetoucheColor = pSh->Imp()->GetRetoucheColor(); 2871 2872 //Ggf. eine Aktion ausloesen um klare Verhaeltnisse zu schaffen. 2873 //Durch diesen Kunstgriff kann in allen Paints davon ausgegangen werden, 2874 //das alle Werte gueltigt sind - keine Probleme, keine Sonderbehandlung(en). 2875 // --> OD 2008-10-07 #i92745# 2876 // Extend check on certain states of the 'current' <ViewShell> instance to 2877 // all existing <ViewShell> instances. 2878 bool bPerformLayoutAction( true ); 2879 { 2880 ViewShell* pTmpViewShell = pSh; 2881 do { 2882 if ( pTmpViewShell->IsInEndAction() || 2883 pTmpViewShell->IsPaintInProgress() || 2884 ( pTmpViewShell->Imp()->IsAction() && 2885 pTmpViewShell->Imp()->GetLayAction().IsActionInProgress() ) ) 2886 { 2887 bPerformLayoutAction = false; 2888 } 2889 2890 pTmpViewShell = static_cast<ViewShell*>(pTmpViewShell->GetNext()); 2891 } while ( bPerformLayoutAction && pTmpViewShell != pSh ); 2892 } 2893 if ( bPerformLayoutAction ) 2894 // <-- 2895 { 2896 ((SwRootFrm*)this)->ResetTurbo(); 2897 SwLayAction aAction( (SwRootFrm*)this, pSh->Imp() ); 2898 aAction.SetPaint( sal_False ); 2899 aAction.SetComplete( sal_False ); 2900 aAction.SetReschedule( pProgress ? sal_True : sal_False ); 2901 aAction.Action(); 2902 ((SwRootFrm*)this)->ResetTurboFlag(); 2903 if ( !pSh->ActionPend() ) 2904 pSh->Imp()->DelRegion(); 2905 } 2906 2907 SwRect aRect( rRect ); 2908 aRect.Intersection( pSh->VisArea() ); 2909 2910 const sal_Bool bExtraData = ::IsExtraData( GetFmt()->GetDoc() ); 2911 2912 pLines = new SwLineRects; //Sammler fuer Umrandungen. 2913 2914 // #104289#. During painting, something (OLE) can 2915 // load the linguistic, which in turn can cause a reformat 2916 // of the document. Dangerous! We better set this flag to 2917 // avoid the reformat. 2918 const sal_Bool bOldAction = IsCallbackActionEnabled(); 2919 ((SwRootFrm*)this)->SetCallbackActionEnabled( sal_False ); 2920 2921 const SwPageFrm *pPage = pSh->Imp()->GetFirstVisPage(); 2922 2923 const bool bBookMode = pGlobalShell->GetViewOptions()->IsViewLayoutBookMode(); 2924 if ( bBookMode && pPage->GetPrev() && static_cast<const SwPageFrm*>(pPage->GetPrev())->IsEmptyPage() ) 2925 pPage = static_cast<const SwPageFrm*>(pPage->GetPrev()); 2926 2927 const bool bLTR = IsLeftToRightViewLayout(); 2928 2929 // #i68597# 2930 const bool bGridPainting(pSh->GetWin() && pSh->Imp()->HasDrawView() && pSh->Imp()->GetDrawView()->IsGridVisible()); 2931 2932 // --> OD #i76669# 2933 SwViewObjectContactRedirector aSwRedirector( *pSh ); 2934 // <-- 2935 2936 while ( pPage ) 2937 { 2938 const bool bRightSidebar = pPage->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT; 2939 2940 if ( !pPage->IsEmptyPage() ) 2941 { 2942 SwRect aPaintRect; 2943 SwPageFrm::GetBorderAndShadowBoundRect( pPage->Frm(), pSh, aPaintRect, bRightSidebar ); 2944 2945 if ( aRect.IsOver( aPaintRect ) ) 2946 { 2947 if ( pSh->GetWin() ) 2948 { 2949 pSubsLines = new SwSubsRects; 2950 pSpecSubsLines = new SwSubsRects; 2951 } 2952 2953 aPaintRect._Intersection( aRect ); 2954 2955 // --> OD 2007-11-14 #i82616# 2956 // Invalidate area for extra data (line numbers or change tracking 2957 // marks), if painting on a window and the paint is trigger by an 2958 // end action. The inefficient and simple enlargement of the 2959 // paint area is replaced by this invalidation. 2960 if ( bExtraData && 2961 pSh->GetWin() && pSh->IsInEndAction() ) 2962 { 2963 // enlarge paint rectangle to complete page width, subtract 2964 // current paint area and invalidate the resulting region. 2965 SWRECTFN( pPage ) 2966 SwRect aPageRectTemp( aPaintRect ); 2967 (aPageRectTemp.*fnRect->fnSetLeftAndWidth)( 2968 (pPage->Frm().*fnRect->fnGetLeft)(), 2969 (pPage->Frm().*fnRect->fnGetWidth)() ); 2970 aPageRectTemp._Intersection( pSh->VisArea() ); 2971 Region aPageRectRegion( aPageRectTemp.SVRect() ); 2972 aPageRectRegion.Exclude( aPaintRect.SVRect() ); 2973 pSh->GetWin()->Invalidate( aPageRectRegion, INVALIDATE_CHILDREN ); 2974 } 2975 // <-- 2976 2977 // --> OD 2007-08-20 #i80793# 2978 // enlarge paint rectangle for objects overlapping the same pixel 2979 // in all cases and before the DrawingLayer overlay is initialized. 2980 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) ); 2981 // <-- 2982 2983 // #i68597# 2984 // moved paint pre-process for DrawingLayer overlay here since the above 2985 // code dependent from bExtraData may expand the PaintRect 2986 { 2987 // #i75172# if called from ViewShell::ImplEndAction it should no longer 2988 // really be used but handled by ViewShell::ImplEndAction already 2989 const Region aDLRegion(aPaintRect.SVRect()); 2990 pSh->DLPrePaint2(aDLRegion); 2991 } 2992 2993 if(OUTDEV_WINDOW == pGlobalShell->GetOut()->GetOutDevType()) 2994 { 2995 /// OD 27.09.2002 #103636# - changed method SwLayVout::Enter(..) 2996 /// 2nd parameter is no longer <const> and will be set to the 2997 /// rectangle the virtual output device is calculated from <aPaintRect>, 2998 /// if the virtual output is used. 2999 pVout->Enter( pSh, aPaintRect, !bNoVirDev ); 3000 3001 /// OD 27.09.2002 #103636# - adjust paint rectangle to pixel size 3002 /// Thus, all objects overlapping on pixel level with the unadjusted 3003 /// paint rectangle will be considered in the paint. 3004 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) ); 3005 } 3006 3007 // maybe this can be put in the above scope. Since we are not sure, just leave it ATM 3008 pVout->SetOrgRect( aPaintRect ); 3009 3010 /// OD 29.08.2002 #102450# 3011 /// determine background color of page for <PaintLayer> method 3012 /// calls, paint <hell> or <heaven> 3013 const Color aPageBackgrdColor(pPage->GetDrawBackgrdColor()); 3014 3015 pPage->PaintBaBo( aPaintRect, pPage, sal_True ); 3016 3017 if ( pSh->Imp()->HasDrawView() ) 3018 { 3019 pLines->LockLines( sal_True ); 3020 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 3021 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 3022 pPrintData, 3023 aPaintRect, 3024 &aPageBackgrdColor, 3025 (pPage->IsRightToLeft() ? true : false), 3026 &aSwRedirector ); 3027 pLines->PaintLines( pSh->GetOut() ); 3028 pLines->LockLines( sal_False ); 3029 } 3030 3031 if( pSh->GetWin() ) 3032 { 3033 // collect sub-lines 3034 pPage->RefreshSubsidiary( aPaintRect ); 3035 // paint special sub-lines 3036 pSpecSubsLines->PaintSubsidiary( pSh->GetOut(), NULL ); 3037 } 3038 3039 pPage->Paint( aPaintRect ); 3040 3041 // no paint of page border if writer is in place mode. 3042 if( pSh->GetWin() && pSh->GetDoc()->GetDocShell() && 3043 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() ) 3044 { 3045 SwPageFrm::PaintPageBorder( pPage->Frm(), pSh, bRightSidebar ); 3046 SwPageFrm::PaintNotesSidebar( pPage->Frm(), pSh, pPage->GetPhyPageNum(), bRightSidebar); 3047 } 3048 3049 pLines->PaintLines( pSh->GetOut() ); 3050 3051 if ( pSh->Imp()->HasDrawView() ) 3052 { 3053 /// OD 29.08.2002 #102450# - add 3rd parameter 3054 // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction. 3055 pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(), 3056 pPrintData, 3057 aPaintRect, 3058 &aPageBackgrdColor, 3059 (pPage->IsRightToLeft() ? true : false), 3060 &aSwRedirector ); 3061 } 3062 3063 if ( bExtraData ) 3064 pPage->RefreshExtraData( aPaintRect ); 3065 3066 if ( pSh->GetWin() ) 3067 { 3068 pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines ); 3069 DELETEZ( pSubsLines ); 3070 DELETEZ( pSpecSubsLines ); 3071 } 3072 pVout->Leave(); 3073 3074 // #i68597# 3075 // needed to move grid painting inside Begin/EndDrawLayer bounds and to change 3076 // output rect for it accordingly 3077 if(bGridPainting) 3078 { 3079 SdrPaintView* pPaintView = pSh->Imp()->GetDrawView(); 3080 SdrPageView* pPageView = pPaintView->GetSdrPageView(); 3081 pPageView->DrawPageViewGrid(*pSh->GetOut(), aPaintRect.SVRect(), SwViewOption::GetTextGridColor() ); 3082 } 3083 3084 // #i68597# 3085 // moved paint post-process for DrawingLayer overlay here, see above 3086 { 3087 pSh->DLPostPaint2(true); 3088 } 3089 } 3090 } 3091 else if ( bBookMode && pSh->GetWin() && !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() ) 3092 { 3093 // paint empty page 3094 SwRect aPaintRect; 3095 SwRect aEmptyPageRect( pPage->Frm() ); 3096 3097 // code from vprint.cxx 3098 const SwPageFrm& rFormatPage = pPage->GetFormatPage(); 3099 aEmptyPageRect.SSize() = rFormatPage.Frm().SSize(); 3100 3101 SwPageFrm::GetBorderAndShadowBoundRect( aEmptyPageRect, pSh, aPaintRect, bRightSidebar ); 3102 aPaintRect._Intersection( aRect ); 3103 3104 if ( aRect.IsOver( aEmptyPageRect ) ) 3105 { 3106 // #i75172# if called from ViewShell::ImplEndAction it should no longer 3107 // really be used but handled by ViewShell::ImplEndAction already 3108 { 3109 const Region aDLRegion(aPaintRect.SVRect()); 3110 pSh->DLPrePaint2(aDLRegion); 3111 } 3112 3113 if( pSh->GetOut()->GetFillColor() != aGlobalRetoucheColor ) 3114 pSh->GetOut()->SetFillColor( aGlobalRetoucheColor ); 3115 3116 pSh->GetOut()->SetLineColor(); // OD 20.02.2003 #107369# - no line color 3117 // OD 20.02.2003 #107369# - use aligned page rectangle 3118 { 3119 SwRect aTmpPageRect( aEmptyPageRect ); 3120 ::SwAlignRect( aTmpPageRect, pSh ); 3121 aEmptyPageRect = aTmpPageRect; 3122 } 3123 3124 pSh->GetOut()->DrawRect( aEmptyPageRect.SVRect() ); 3125 3126 // paint empty page text 3127 const Font& rEmptyPageFont = SwPageFrm::GetEmptyPageFont(); 3128 const Font aOldFont( pSh->GetOut()->GetFont() ); 3129 3130 pSh->GetOut()->SetFont( rEmptyPageFont ); 3131 pSh->GetOut()->DrawText( aEmptyPageRect.SVRect(), SW_RESSTR( STR_EMPTYPAGE ), 3132 TEXT_DRAW_VCENTER | 3133 TEXT_DRAW_CENTER | 3134 TEXT_DRAW_CLIP ); 3135 3136 pSh->GetOut()->SetFont( aOldFont ); 3137 // paint border for empty page (shadow removed now) 3138 // OD 19.02.2003 #107369# - use new method to paint page border 3139 SwPageFrm::PaintPageBorder( aEmptyPageRect, pSh, bRightSidebar ); 3140 SwPageFrm::PaintNotesSidebar( aEmptyPageRect, pSh, pPage->GetPhyPageNum(), bRightSidebar); 3141 3142 { 3143 pSh->DLPostPaint2(true); 3144 } 3145 } 3146 } 3147 3148 ASSERT( !pPage->GetNext() || pPage->GetNext()->IsPageFrm(), 3149 "Nachbar von Seite keine Seite." ); 3150 pPage = (SwPageFrm*)pPage->GetNext(); 3151 } 3152 3153 DELETEZ( pLines ); 3154 3155 #ifdef FRANK_TEST 3156 if ( pSh->GetWin() ) 3157 { 3158 Rectangle aRect( aFrm.SVRect() ); 3159 pSh->GetWin()->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 3160 pSh->GetWin()->SetFillColor(); 3161 pSh->GetWin()->SetLineColor( COL_LIGHTRED ); 3162 pSh->GetWin()->DrawRect( aRect ); 3163 pSh->GetWin()->Pop(); 3164 } 3165 #endif 3166 3167 if ( bResetRootPaint ) 3168 SwRootFrm::bInPaint = sal_False; 3169 if ( pStatics ) 3170 delete pStatics; 3171 else 3172 { 3173 pProgress = 0; 3174 pGlobalShell = 0; 3175 } 3176 3177 ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction ); 3178 } 3179 3180 #ifdef LONG_TABLE_HACK 3181 3182 /************************************************************************* 3183 |* SwRootFrm::HackPrepareLongTblPaint() 3184 |* 3185 |* Ersterstellung MA 27. Sep. 96 3186 |* Letzte Änderung MA 18. Nov. 97 3187 |*************************************************************************/ 3188 3189 void SwRootFrm::HackPrepareLongTblPaint( int nMode ) 3190 { 3191 switch ( nMode ) 3192 { 3193 case HACK_TABLEMODE_INIT : ASSERT( !pLines, "HackPrepare: already prepared" ); 3194 pLines = new SwLineRects; 3195 ASSERT( !pGlobalShell, "old GlobalShell lost" ); 3196 pGlobalShell = GetCurrShell(); 3197 bTableHack = sal_True; 3198 break; 3199 case HACK_TABLEMODE_LOCKLINES : pLines->LockLines( sal_True ); break; 3200 case HACK_TABLEMODE_PAINTLINES : pLines->PaintLines( GetShell()->GetOut() ); 3201 break; 3202 case HACK_TABLEMODE_UNLOCKLINES: pLines->LockLines( sal_False ); break; 3203 case HACK_TABLEMODE_EXIT : pLines->PaintLines( GetCurrShell()->GetOut() ); 3204 DELETEZ( pLines ); 3205 pGlobalShell = 0; 3206 bTableHack = sal_False; 3207 break; 3208 } 3209 } 3210 3211 #endif 3212 3213 /************************************************************************* 3214 |* SwLayoutFrm::Paint() 3215 |* 3216 |* Ersterstellung MA 19. May. 92 3217 |* Letzte Änderung MA 19. Apr. 95 3218 |*************************************************************************/ 3219 3220 void MA_FASTCALL lcl_EmergencyFormatFtnCont( SwFtnContFrm *pCont ) 3221 { 3222 //Es kann sein, dass der Cont vernichtet wird. 3223 SwCntntFrm *pCnt = pCont->ContainsCntnt(); 3224 while ( pCnt && pCnt->IsInFtn() ) 3225 { 3226 pCnt->Calc(); 3227 pCnt = pCnt->GetNextCntntFrm(); 3228 } 3229 } 3230 3231 class SwShortCut 3232 { 3233 SwRectDist fnCheck; 3234 long nLimit; 3235 public: 3236 SwShortCut( const SwFrm& rFrm, const SwRect& rRect ); 3237 sal_Bool Stop( const SwRect& rRect ) const 3238 { return (rRect.*fnCheck)( nLimit ) > 0; } 3239 }; 3240 3241 SwShortCut::SwShortCut( const SwFrm& rFrm, const SwRect& rRect ) 3242 { 3243 sal_Bool bVert = rFrm.IsVertical(); 3244 sal_Bool bR2L = rFrm.IsRightToLeft(); 3245 if( rFrm.IsNeighbourFrm() && bVert == bR2L ) 3246 { 3247 if( bVert ) 3248 { 3249 fnCheck = &SwRect::GetBottomDistance; 3250 nLimit = rRect.Top(); 3251 } 3252 else 3253 { 3254 fnCheck = &SwRect::GetLeftDistance; 3255 nLimit = rRect.Left() + rRect.Width(); 3256 } 3257 } 3258 else if( bVert == rFrm.IsNeighbourFrm() ) 3259 { 3260 fnCheck = &SwRect::GetTopDistance; 3261 nLimit = rRect.Top() + rRect.Height(); 3262 } 3263 else 3264 { 3265 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 3266 if ( rFrm.IsVertLR() ) 3267 { 3268 fnCheck = &SwRect::GetLeftDistance; 3269 nLimit = rRect.Right(); 3270 } 3271 else 3272 { 3273 fnCheck = &SwRect::GetRightDistance; 3274 nLimit = rRect.Left(); 3275 } 3276 } 3277 } 3278 3279 void SwLayoutFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3280 { 3281 ViewShell *pSh = getRootFrm()->GetCurrShell(); 3282 3283 // --> FME 2004-06-24 #i16816# tagged pdf support 3284 Frm_Info aFrmInfo( *this ); 3285 SwTaggedPDFHelper aTaggedPDFHelper( 0, &aFrmInfo, 0, *pSh->GetOut() ); 3286 // <-- 3287 3288 const SwFrm *pFrm = Lower(); 3289 if ( !pFrm ) 3290 return; 3291 3292 SwShortCut aShortCut( *pFrm, rRect ); 3293 sal_Bool bCnt; 3294 if ( sal_True == (bCnt = pFrm->IsCntntFrm()) ) 3295 pFrm->Calc(); 3296 3297 if ( pFrm->IsFtnContFrm() ) 3298 { 3299 ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm ); 3300 pFrm = Lower(); 3301 } 3302 3303 const SwPageFrm *pPage = 0; 3304 const sal_Bool bWin = pGlobalShell->GetWin() ? sal_True : sal_False; 3305 3306 while ( IsAnLower( pFrm ) ) 3307 { 3308 SwRect aPaintRect( pFrm->PaintArea() ); 3309 if( aShortCut.Stop( aPaintRect ) ) 3310 break; 3311 if ( bCnt && pProgress ) 3312 pProgress->Reschedule(); 3313 3314 //Wenn ein Frm es explizit will muss retouchiert werden. 3315 //Erst die Retouche, denn selbige koennte die aligned'en Raender 3316 //plaetten. 3317 if ( pFrm->IsRetouche() ) 3318 { 3319 if ( pFrm->IsRetoucheFrm() && bWin && !pFrm->GetNext() ) 3320 { if ( !pPage ) 3321 pPage = FindPageFrm(); 3322 pFrm->Retouche( pPage, rRect ); 3323 } 3324 pFrm->ResetRetouche(); 3325 } 3326 3327 if ( rRect.IsOver( aPaintRect ) ) 3328 { 3329 if ( bCnt && pFrm->IsCompletePaint() && 3330 !rRect.IsInside( aPaintRect ) && GetpApp()->AnyInput( INPUT_KEYBOARD ) ) 3331 { 3332 //fix(8104): Es kann vorkommen, dass die Verarbeitung nicht 3333 //vollstaendig war, aber trotzdem Teile des Absatzes gepaintet 3334 //werden. In der Folge werden dann evtl. wiederum andere Teile 3335 //des Absatzes garnicht mehr gepaintet. Einziger Ausweg scheint 3336 //hier ein Invalidieren der Windows zu sein. 3337 //Um es nicht alzu Heftig werden zu lassen versuche ich hier 3338 //das Rechteck zu begrenzen indem der gewuenschte Teil gepaintet 3339 //und nur die uebrigen Absatzanteile invalidiert werden. 3340 if ( aPaintRect.Left() == rRect.Left() && 3341 aPaintRect.Right() == rRect.Right() ) 3342 { 3343 aPaintRect.Bottom( rRect.Top() - 1 ); 3344 if ( aPaintRect.Height() > 0 ) 3345 pGlobalShell->InvalidateWindows(aPaintRect); 3346 aPaintRect.Top( rRect.Bottom() + 1 ); 3347 aPaintRect.Bottom( pFrm->Frm().Bottom() ); 3348 if ( aPaintRect.Height() > 0 ) 3349 pGlobalShell->InvalidateWindows(aPaintRect); 3350 aPaintRect.Top( pFrm->Frm().Top() ); 3351 aPaintRect.Bottom( pFrm->Frm().Bottom() ); 3352 } 3353 else 3354 { 3355 pGlobalShell->InvalidateWindows( aPaintRect ); 3356 pFrm = pFrm->GetNext(); 3357 if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) ) 3358 pFrm->Calc(); 3359 continue; 3360 } 3361 } 3362 pFrm->ResetCompletePaint(); 3363 aPaintRect._Intersection( rRect ); 3364 3365 pFrm->Paint( aPaintRect ); 3366 3367 if ( Lower() && Lower()->IsColumnFrm() ) 3368 { 3369 //Ggf. die Spaltentrennlinien malen. Fuer den Seitenbody ist 3370 //nicht der Upper sondern die Seite Zustaendig. 3371 const SwFrmFmt *pFmt = GetUpper() && GetUpper()->IsPageFrm() 3372 ? GetUpper()->GetFmt() 3373 : GetFmt(); 3374 const SwFmtCol &rCol = pFmt->GetCol(); 3375 if ( rCol.GetLineAdj() != COLADJ_NONE ) 3376 { 3377 if ( !pPage ) 3378 pPage = pFrm->FindPageFrm(); 3379 3380 PaintColLines( aPaintRect, rCol, pPage ); 3381 } 3382 } 3383 } 3384 if ( !bCnt && pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() ) 3385 ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm->GetNext() ); 3386 3387 pFrm = pFrm->GetNext(); 3388 if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) ) 3389 pFrm->Calc(); 3390 } 3391 } 3392 3393 /** FlyFrm::IsBackgroundTransparent - for feature #99657# 3394 3395 OD 12.08.2002 3396 determines, if background of fly frame has to be drawn transparent 3397 declaration found in /core/inc/flyfrm.cxx 3398 OD 08.10.2002 #103898# - If the background of the fly frame itself is not 3399 transparent and the background is inherited from its parent/grandparent, 3400 the background brush, used for drawing, has to be investigated for transparency. 3401 3402 @author OD 3403 3404 @return true, if background is transparent drawn. 3405 */ 3406 sal_Bool SwFlyFrm::IsBackgroundTransparent() const 3407 { 3408 sal_Bool bBackgroundTransparent = GetFmt()->IsBackgroundTransparent(); 3409 if ( !bBackgroundTransparent && 3410 static_cast<const SwFlyFrmFmt*>(GetFmt())->IsBackgroundBrushInherited() ) 3411 { 3412 const SvxBrushItem* pBackgrdBrush = 0; 3413 const Color* pSectionTOXColor = 0; 3414 SwRect aDummyRect; 3415 3416 //UUUU 3417 drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes; 3418 3419 if ( GetBackgroundBrush( aFillAttributes, pBackgrdBrush, pSectionTOXColor, aDummyRect, false) ) 3420 { 3421 if ( pSectionTOXColor && 3422 (pSectionTOXColor->GetTransparency() != 0) && 3423 (pSectionTOXColor->GetColor() != COL_TRANSPARENT) ) 3424 { 3425 bBackgroundTransparent = sal_True; 3426 } 3427 else if(aFillAttributes.get() && aFillAttributes->isUsed()) //UUUU 3428 { 3429 bBackgroundTransparent = aFillAttributes->isTransparent(); 3430 } 3431 else if ( pBackgrdBrush ) 3432 { 3433 if ( (pBackgrdBrush->GetColor().GetTransparency() != 0) && 3434 (pBackgrdBrush->GetColor() != COL_TRANSPARENT) ) 3435 { 3436 bBackgroundTransparent = sal_True; 3437 } 3438 else 3439 { 3440 const GraphicObject *pTmpGrf = 3441 static_cast<const GraphicObject*>(pBackgrdBrush->GetGraphicObject()); 3442 if ( (pTmpGrf) && 3443 (pTmpGrf->GetAttr().GetTransparency() != 0) 3444 ) 3445 { 3446 bBackgroundTransparent = sal_True; 3447 } 3448 } 3449 } 3450 } 3451 } 3452 3453 return bBackgroundTransparent; 3454 }; 3455 3456 /** FlyFrm::IsShadowTransparent - for feature #99657# 3457 3458 OD 13.08.2002 3459 determine, if shadow color of fly frame has to be drawn transparent 3460 declaration found in /core/inc/flyfrm.cxx 3461 3462 @author OD 3463 3464 @return true, if shadow color is transparent. 3465 */ 3466 sal_Bool SwFlyFrm::IsShadowTransparent() const 3467 { 3468 return GetFmt()->IsShadowTransparent(); 3469 }; 3470 3471 /************************************************************************* 3472 |* SwFlyFrm::IsPaint() 3473 |* 3474 |* Ersterstellung MA 16. Jan. 97 3475 |* Letzte Änderung MA 16. Jan. 97 3476 |*************************************************************************/ 3477 3478 sal_Bool SwFlyFrm::IsPaint( SdrObject *pObj, const ViewShell *pSh ) 3479 { 3480 SdrObjUserCall *pUserCall; 3481 3482 if ( 0 == ( pUserCall = GetUserCall(pObj) ) ) 3483 return sal_True; 3484 3485 //Attributabhaengig nicht fuer Drucker oder PreView painten 3486 sal_Bool bPaint = pFlyOnlyDraw || 3487 ((SwContact*)pUserCall)->GetFmt()->GetPrint().GetValue(); 3488 if ( !bPaint ) 3489 bPaint = pSh->GetWin() && !pSh->IsPreView(); 3490 3491 if ( bPaint ) 3492 { 3493 //Das Paint kann evtl. von von uebergeordneten Flys verhindert werden. 3494 SwFrm *pAnch = 0; 3495 // --> OD #i117962# 3496 if ( pObj->ISA(SwFlyDrawObj) ) 3497 { 3498 bPaint = false; 3499 } 3500 // <-- 3501 else if ( pObj->ISA(SwVirtFlyDrawObj) ) 3502 { 3503 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); 3504 if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly ) 3505 return sal_True; 3506 3507 //Die Anzeige eines Zwischenstadiums vermeiden, Flys die nicht mit 3508 //der Seite auf der sie verankert sind ueberlappen werden auch 3509 //nicht gepaintet. 3510 //HACK: Ausnahme: Drucken von Rahmen in Tabellen, diese koennen 3511 //bei uebergrossen Tabellen (HTML) schon mal auserhalb der Seite 3512 //stehen. 3513 SwPageFrm *pPage = pFly->FindPageFrm(); 3514 if ( pPage ) 3515 { 3516 if ( pPage->Frm().IsOver( pFly->Frm() ) ) 3517 pAnch = pFly->AnchorFrm(); 3518 else if ( bTableHack && 3519 pFly->Frm().Top() >= pFly->GetAnchorFrm()->Frm().Top() && 3520 pFly->Frm().Top() < pFly->GetAnchorFrm()->Frm().Bottom() && 3521 long(pSh->GetOut()) == 3522 long(pSh->getIDocumentDeviceAccess()->getPrinter( false ) ) ) 3523 { 3524 pAnch = pFly->AnchorFrm(); 3525 } 3526 } 3527 3528 } 3529 else 3530 { 3531 // OD 13.10.2003 #i19919# - consider 'virtual' drawing objects 3532 // OD 2004-03-29 #i26791# 3533 pAnch = ((SwDrawContact*)pUserCall)->GetAnchorFrm( pObj ); 3534 if ( pAnch ) 3535 { 3536 if ( !pAnch->GetValidPosFlag() ) 3537 pAnch = 0; 3538 else if ( long(pSh->GetOut()) == long(pSh->getIDocumentDeviceAccess()->getPrinter( false ))) 3539 { 3540 //HACK: fuer das Drucken muessen wir ein paar Objekte 3541 //weglassen, da diese sonst doppelt gedruckt werden. 3542 //Die Objekte sollen gedruckt werden, wenn der TableHack 3543 //gerade greift. In der Folge duerfen sie nicht gedruckt werden 3544 //wenn sie mit der Seite dran sind, ueber der sie von der 3545 //Position her gerade schweben. 3546 const SwPageFrm *pPage = pAnch->FindPageFrm(); 3547 if ( !bTableHack && 3548 !pPage->Frm().IsOver( pObj->GetCurrentBoundRect() ) ) 3549 pAnch = 0; 3550 } 3551 } 3552 else 3553 { 3554 // OD 02.07.2003 #108784# - debug assert 3555 if ( !pObj->ISA(SdrObjGroup) ) 3556 { 3557 ASSERT( false, "<SwFlyFrm::IsPaint(..)> - paint of drawing object without anchor frame!?" ); 3558 } 3559 } 3560 } 3561 if ( pAnch ) 3562 { 3563 if ( pAnch->IsInFly() ) 3564 bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(), 3565 pSh ); 3566 else if ( pFlyOnlyDraw ) 3567 bPaint = sal_False; 3568 } 3569 else 3570 bPaint = sal_False; 3571 } 3572 return bPaint; 3573 } 3574 3575 /************************************************************************* 3576 |* SwCellFrm::Paint( const SwRect& ) const 3577 |*************************************************************************/ 3578 void SwCellFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3579 { 3580 if ( GetLayoutRowSpan() >= 1 ) 3581 SwLayoutFrm::Paint( rRect ); 3582 } 3583 3584 /************************************************************************* 3585 |* SwFlyFrm::Paint() 3586 |* 3587 |* Ersterstellung MA ?? 3588 |* Letzte Änderung MA 16. Jan. 97 3589 |*************************************************************************/ 3590 3591 //Weiter unten definiert 3592 void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay, 3593 const SwRect &rRect, const SwPageFrm *pPage ); 3594 3595 void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3596 { 3597 //begin:optimize thumbnail generate and store procedure to improve odt saving performance, i120030 3598 ViewShell *pShell = getRootFrm()->GetCurrShell(); 3599 if (pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocShell()) 3600 { 3601 sal_Bool bInGenerateThumbnail = pShell->GetDoc()->GetDocShell()->IsInGenerateAndStoreThumbnail(); 3602 if (bInGenerateThumbnail) 3603 { 3604 SwRect aVisRect = pShell->VisArea(); 3605 if (!aVisRect.IsOver(Frm())) 3606 return; 3607 } 3608 } 3609 //end:i120030 3610 3611 //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die 3612 //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben. 3613 //z.B. #33066# 3614 pLines->LockLines(sal_True); 3615 3616 SwRect aRect( rRect ); 3617 aRect._Intersection( Frm() ); 3618 3619 OutputDevice* pOut = pGlobalShell->GetOut(); 3620 pOut->Push( PUSH_CLIPREGION ); 3621 pOut->SetClipRegion(); 3622 const SwPageFrm* pPage = FindPageFrm(); 3623 3624 const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm() 3625 ? (SwNoTxtFrm*)Lower() : 0; 3626 3627 bool bIsChart = false; //#i102950# don't paint additional borders for charts 3628 //check whether we have a chart 3629 if(pNoTxt) 3630 { 3631 const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode()); 3632 if( pNoTNd ) 3633 { 3634 SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode()); 3635 if( pOLENd && ChartHelper::IsChart( pOLENd->GetOLEObj().GetObject() ) ) 3636 bIsChart = true; 3637 } 3638 } 3639 3640 { 3641 bool bContour = GetFmt()->GetSurround().IsContour(); 3642 PolyPolygon aPoly; 3643 if ( bContour ) 3644 { 3645 // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True> 3646 // to indicate that method is called for paint in order to avoid 3647 // load of the intrinsic graphic. 3648 bContour = GetContour( aPoly, sal_True ); 3649 } 3650 3651 // --> OD 2005-06-08 #i47804# - distinguish complete background paint 3652 // and margin paint. 3653 // paint complete background for Writer text fly frames 3654 bool bPaintCompleteBack( !pNoTxt ); 3655 // <-- 3656 // paint complete background for transparent graphic and contour, 3657 // if own background color exists. 3658 const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false; 3659 if ( !bPaintCompleteBack && 3660 ( bIsGraphicTransparent|| bContour ) ) 3661 { 3662 const SwFrmFmt* pSwFrmFmt = dynamic_cast< const SwFrmFmt* >(GetFmt()); 3663 3664 if(pSwFrmFmt && pSwFrmFmt->supportsFullDrawingLayerFillAttributeSet()) 3665 { 3666 //UUUU check for transparency 3667 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(pSwFrmFmt->getSdrAllFillAttributesHelper()); 3668 3669 // check if the new fill attributes are used 3670 if(aFillAttributes.get() && aFillAttributes->isUsed()) 3671 { 3672 bPaintCompleteBack = true; 3673 } 3674 } 3675 else 3676 { 3677 const SvxBrushItem &rBack = GetFmt()->GetBackground(); 3678 // OD 07.08.2002 #99657# #GetTransChg# 3679 // to determine, if background has to be painted, by checking, if 3680 // background color is not COL_TRANSPARENT ("no fill"/"auto fill") 3681 // or a background graphic exists. 3682 bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) || 3683 rBack.GetGraphicPos() != GPOS_NONE; 3684 } 3685 } 3686 // paint of margin needed. 3687 const bool bPaintMarginOnly( !bPaintCompleteBack && 3688 Prt().SSize() != Frm().SSize() ); 3689 3690 // --> OD 2005-06-08 #i47804# - paint background of parent fly frame 3691 // for transparent graphics in layer Hell, if parent fly frame isn't 3692 // in layer Hell. It's only painted the intersection between the 3693 // parent fly frame area and the paint area <aRect> 3694 const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess(); 3695 3696 if ( bIsGraphicTransparent && 3697 GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() && 3698 GetAnchorFrm()->FindFlyFrm() ) 3699 { 3700 const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm(); 3701 if ( pParentFlyFrm->GetDrawObj()->GetLayer() != 3702 pIDDMA->GetHellId() ) 3703 { 3704 SwFlyFrm* pOldRet = pRetoucheFly2; 3705 pRetoucheFly2 = const_cast<SwFlyFrm*>(this); 3706 3707 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm ); 3708 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3709 SwRect aPaintRect( aRect ); 3710 aPaintRect._Intersection( pParentFlyFrm->Frm() ); 3711 pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False ); 3712 3713 pRetoucheFly2 = pOldRet; 3714 } 3715 } 3716 3717 if ( bPaintCompleteBack || bPaintMarginOnly ) 3718 { 3719 //#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder 3720 //das orig. Rect bekommt, aber PaintBackground das begrenzte. 3721 3722 // OD 2004-04-23 #116347# 3723 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 3724 pOut->SetLineColor(); 3725 3726 pPage = FindPageFrm(); 3727 3728 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 3729 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3730 3731 // OD 06.08.2002 #99657# - paint border before painting background 3732 // paint border 3733 { 3734 SwRect aTmp( rRect ); 3735 PaintBorder( aTmp, pPage, rAttrs ); 3736 } 3737 3738 // paint background 3739 { 3740 SwRegionRects aRegion( aRect ); 3741 // --> OD 2007-12-13 #i80822# 3742 // suppress painting of background in printing area for 3743 // non-transparent graphics. 3744 // if ( bPaintMarginOnly ) 3745 if ( bPaintMarginOnly || 3746 ( pNoTxt && !bIsGraphicTransparent ) ) 3747 // <-- 3748 { 3749 //Was wir eigentlich Painten wollen ist der schmale Streifen 3750 //zwischen PrtArea und aeusserer Umrandung. 3751 SwRect aTmp( Prt() ); aTmp += Frm().Pos(); 3752 aRegion -= aTmp; 3753 } 3754 if ( bContour ) 3755 { 3756 pOut->Push(); 3757 // --> OD 2007-12-13 #i80822# 3758 // apply clip region under the same conditions, which are 3759 // used in <SwNoTxtFrm::Paint(..)> to set the clip region 3760 // for painting the graphic/OLE. Thus, the clip region is 3761 // also applied for the PDF export. 3762 // if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER ) 3763 ViewShell *pSh = getRootFrm()->GetCurrShell(); 3764 if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() ) 3765 // <-- 3766 { 3767 pOut->SetClipRegion( aPoly ); 3768 } 3769 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 3770 PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True ); 3771 pOut->Pop(); 3772 } 3773 else 3774 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 3775 PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True ); 3776 } 3777 3778 pOut->Pop(); 3779 } 3780 } 3781 3782 // OD 19.12.2002 #106318# - fly frame will paint its subsidiary lines and 3783 // the subsidiary lines of its lowers on its own, due to overlapping with 3784 // other fly frames or other objects. 3785 if( pGlobalShell->GetWin() 3786 && !bIsChart ) //#i102950# don't paint additional borders for charts 3787 { 3788 bool bSubsLineRectsCreated; 3789 if ( pSubsLines ) 3790 { 3791 // Lock already existing subsidiary lines 3792 pSubsLines->LockLines( sal_True ); 3793 bSubsLineRectsCreated = false; 3794 } 3795 else 3796 { 3797 // create new subsidiardy lines 3798 pSubsLines = new SwSubsRects; 3799 bSubsLineRectsCreated = true; 3800 } 3801 3802 bool bSpecSubsLineRectsCreated; 3803 if ( pSpecSubsLines ) 3804 { 3805 // Lock already existing special subsidiary lines 3806 pSpecSubsLines->LockLines( sal_True ); 3807 bSpecSubsLineRectsCreated = false; 3808 } 3809 else 3810 { 3811 // create new special subsidiary lines 3812 pSpecSubsLines = new SwSubsRects; 3813 bSpecSubsLineRectsCreated = true; 3814 } 3815 // Add subsidiary lines of fly frame and its lowers 3816 RefreshLaySubsidiary( pPage, aRect ); 3817 // paint subsidiary lines of fly frame and its lowers 3818 pSpecSubsLines->PaintSubsidiary( pOut, NULL ); 3819 pSubsLines->PaintSubsidiary( pOut, pLines ); 3820 if ( !bSubsLineRectsCreated ) 3821 // unlock subsidiary lines 3822 pSubsLines->LockLines( sal_False ); 3823 else 3824 // delete created subsidiary lines container 3825 DELETEZ( pSubsLines ); 3826 3827 if ( !bSpecSubsLineRectsCreated ) 3828 // unlock special subsidiary lines 3829 pSpecSubsLines->LockLines( sal_False ); 3830 else 3831 { 3832 // delete created special subsidiary lines container 3833 DELETEZ( pSpecSubsLines ); 3834 } 3835 } 3836 3837 SwLayoutFrm::Paint( aRect ); 3838 3839 Validate(); 3840 3841 // OD 19.12.2002 #106318# - first paint lines added by fly frame paint 3842 // and then unlock other lines. 3843 pLines->PaintLines( pOut ); 3844 pLines->LockLines( sal_False ); 3845 3846 pOut->Pop(); 3847 3848 if ( pProgress && pNoTxt ) 3849 pProgress->Reschedule(); 3850 } 3851 /************************************************************************* 3852 |* SwTabFrm::Paint() 3853 |* 3854 |* Ersterstellung MA 11. May. 93 3855 |* Letzte Änderung MA 23. Mar. 95 3856 |*************************************************************************/ 3857 3858 void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 3859 { 3860 if ( pGlobalShell->GetViewOptions()->IsTable() ) 3861 { 3862 // --> collapsing borders FME 2005-05-27 #i29550# 3863 if ( IsCollapsingBorders() ) 3864 { 3865 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 3866 const SwBorderAttrs &rAttrs = *aAccess.Get(); 3867 3868 // paint shadow 3869 if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE ) 3870 { 3871 SwRect aRect; 3872 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True ); 3873 PaintShadow( rRect, aRect, rAttrs ); 3874 } 3875 3876 // paint lines 3877 SwTabFrmPainter aHelper( *this ); 3878 aHelper.PaintLines( *pGlobalShell->GetOut(), rRect ); 3879 } 3880 // <-- collapsing 3881 3882 SwLayoutFrm::Paint( rRect ); 3883 } 3884 // OD 10.01.2003 #i6467# - no light grey rectangle for page preview 3885 else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() ) 3886 { 3887 // OD 10.01.2003 #i6467# - intersect output rectangle with table frame 3888 SwRect aTabRect( Prt() ); 3889 aTabRect.Pos() += Frm().Pos(); 3890 SwRect aTabOutRect( rRect ); 3891 aTabOutRect.Intersection( aTabRect ); 3892 pGlobalShell->GetViewOptions()-> 3893 DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY ); 3894 } 3895 ((SwTabFrm*)this)->ResetComplete(); 3896 } 3897 3898 /************************************************************************* 3899 |* SwFrm::PaintShadow() 3900 |* 3901 |* Beschreibung Malt einen Schatten wenns das FrmFormat fordert. 3902 |* Der Schatten wird immer an den auesseren Rand des OutRect gemalt. 3903 |* Das OutRect wird ggf. so verkleinert, dass auf diesem das 3904 |* malen der Umrandung stattfinden kann. 3905 |* Ersterstellung MA 21. Dec. 92 3906 |* Letzte Änderung MA 29. May. 97 3907 |*************************************************************************/ 3908 /// OD 23.08.2002 #99657# 3909 /// draw full shadow rectangle for frames with transparent drawn backgrounds. 3910 void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect, 3911 const SwBorderAttrs &rAttrs ) const 3912 { 3913 const SvxShadowItem &rShadow = rAttrs.GetShadow(); 3914 const long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth() ); 3915 const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() ); 3916 3917 SwRects aRegion( 2, 2 ); 3918 SwRect aOut( rOutRect ); 3919 3920 const sal_Bool bCnt = IsCntntFrm(); 3921 const sal_Bool bTop = !bCnt || rAttrs.GetTopLine ( *(this) ) ? sal_True : sal_False; 3922 const sal_Bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? sal_True : sal_False; 3923 3924 SvxShadowLocation eLoc = rShadow.GetLocation(); 3925 3926 SWRECTFN( this ) 3927 if( IsVertical() ) 3928 { 3929 switch( eLoc ) 3930 { 3931 case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break; 3932 case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break; 3933 case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break; 3934 case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_TOPLEFT; break; 3935 default: break; 3936 } 3937 } 3938 3939 /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to 3940 /// be drawn or only two shadow rectangles beside the frame. 3941 /// draw full shadow rectangle, if frame background is drawn transparent. 3942 /// Status Quo: 3943 /// SwLayoutFrm can have transparent drawn backgrounds. Thus, 3944 /// "asked" their frame format. 3945 sal_Bool bDrawFullShadowRectangle = 3946 ( IsLayoutFrm() && 3947 (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent() 3948 ); 3949 switch ( eLoc ) 3950 { 3951 case SVX_SHADOW_BOTTOMRIGHT: 3952 { 3953 if ( bDrawFullShadowRectangle ) 3954 { 3955 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3956 aOut.Top( aOut.Top() + nHeight ); 3957 aOut.Left( aOut.Left() + nWidth ); 3958 aRegion.Insert( aOut, aRegion.Count() ); 3959 } 3960 else 3961 { 3962 aOut.Top ( aOut.Bottom() - nHeight ); 3963 aOut.Left( aOut.Left() + nWidth ); 3964 if ( bBottom ) 3965 aRegion.Insert( aOut, aRegion.Count() ); 3966 aOut.Left( aOut.Right() - nWidth ); 3967 aOut.Top ( rOutRect.Top() + nHeight ); 3968 if ( bBottom ) 3969 aOut.Bottom( aOut.Bottom() - nHeight ); 3970 if ( bCnt && (!bTop || !bBottom) ) 3971 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 3972 aRegion.Insert( aOut, aRegion.Count() ); 3973 } 3974 3975 rOutRect.Right ( rOutRect.Right() - nWidth ); 3976 rOutRect.Bottom( rOutRect.Bottom()- nHeight ); 3977 } 3978 break; 3979 case SVX_SHADOW_TOPLEFT: 3980 { 3981 if ( bDrawFullShadowRectangle ) 3982 { 3983 /// OD 06.08.2002 #99657# - draw full shadow rectangle 3984 aOut.Bottom( aOut.Bottom() - nHeight ); 3985 aOut.Right( aOut.Right() - nWidth ); 3986 aRegion.Insert( aOut, aRegion.Count() ); 3987 } 3988 else 3989 { 3990 aOut.Bottom( aOut.Top() + nHeight ); 3991 aOut.Right ( aOut.Right() - nWidth ); 3992 if ( bTop ) 3993 aRegion.Insert( aOut, aRegion.Count() ); 3994 aOut.Right ( aOut.Left() + nWidth ); 3995 aOut.Bottom( rOutRect.Bottom() - nHeight ); 3996 if ( bTop ) 3997 aOut.Top( aOut.Top() + nHeight ); 3998 if ( bCnt && (!bBottom || !bTop) ) 3999 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 4000 aRegion.Insert( aOut, aRegion.Count() ); 4001 } 4002 4003 rOutRect.Left( rOutRect.Left() + nWidth ); 4004 rOutRect.Top( rOutRect.Top() + nHeight ); 4005 } 4006 break; 4007 case SVX_SHADOW_TOPRIGHT: 4008 { 4009 if ( bDrawFullShadowRectangle ) 4010 { 4011 /// OD 06.08.2002 #99657# - draw full shadow rectangle 4012 aOut.Bottom( aOut.Bottom() - nHeight); 4013 aOut.Left( aOut.Left() + nWidth ); 4014 aRegion.Insert( aOut, aRegion.Count() ); 4015 } 4016 else 4017 { 4018 aOut.Bottom( aOut.Top() + nHeight ); 4019 aOut.Left ( aOut.Left()+ nWidth ); 4020 if ( bTop ) 4021 aRegion.Insert( aOut, aRegion.Count() ); 4022 aOut.Left ( aOut.Right() - nWidth ); 4023 aOut.Bottom( rOutRect.Bottom() - nHeight ); 4024 if ( bTop ) 4025 aOut.Top( aOut.Top() + nHeight ); 4026 if ( bCnt && (!bBottom || bTop) ) 4027 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 4028 aRegion.Insert( aOut, aRegion.Count() ); 4029 } 4030 4031 rOutRect.Right( rOutRect.Right() - nWidth ); 4032 rOutRect.Top( rOutRect.Top() + nHeight ); 4033 } 4034 break; 4035 case SVX_SHADOW_BOTTOMLEFT: 4036 { 4037 if ( bDrawFullShadowRectangle ) 4038 { 4039 /// OD 06.08.2002 #99657# - draw full shadow rectangle 4040 aOut.Top( aOut.Top() + nHeight ); 4041 aOut.Right( aOut.Right() - nWidth ); 4042 aRegion.Insert( aOut, aRegion.Count() ); 4043 } 4044 else 4045 { 4046 aOut.Top ( aOut.Bottom()- nHeight ); 4047 aOut.Right( aOut.Right() - nWidth ); 4048 if ( bBottom ) 4049 aRegion.Insert( aOut, aRegion.Count() ); 4050 aOut.Right( aOut.Left() + nWidth ); 4051 aOut.Top( rOutRect.Top() + nHeight ); 4052 if ( bBottom ) 4053 aOut.Bottom( aOut.Bottom() - nHeight ); 4054 if ( bCnt && (!bTop || !bBottom) ) 4055 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect ); 4056 aRegion.Insert( aOut, aRegion.Count() ); 4057 } 4058 4059 rOutRect.Left( rOutRect.Left() + nWidth ); 4060 rOutRect.Bottom( rOutRect.Bottom() - nHeight ); 4061 } 4062 break; 4063 default: 4064 ASSERT( sal_False, "new ShadowLocation() ?" ) 4065 break; 4066 } 4067 4068 OutputDevice *pOut = pGlobalShell->GetOut(); 4069 4070 sal_uLong nOldDrawMode = pOut->GetDrawMode(); 4071 Color aShadowColor( rShadow.GetColor() ); 4072 if( aRegion.Count() && pGlobalShell->GetWin() && 4073 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 4074 { 4075 // In high contrast mode, the output device has already set the 4076 // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function 4077 // to ignore the setting of a new color. Therefore we have to reset 4078 // the drawing mode 4079 pOut->SetDrawMode( 0 ); 4080 aShadowColor = SwViewOption::GetFontColor(); 4081 } 4082 4083 if ( pOut->GetFillColor() != aShadowColor ) 4084 pOut->SetFillColor( aShadowColor ); 4085 4086 pOut->SetDrawMode( nOldDrawMode ); 4087 4088 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 4089 { 4090 SwRect &rOut = aRegion[i]; 4091 aOut = rOut; 4092 // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle 4093 // no alignment necessary, because (1) <rRect> is already aligned 4094 // and because (2) paint of border and background will occur later. 4095 // Thus, (1) assures that no conflicts with neighbour object will occur 4096 // and (2) assures that border and background is not affected by the 4097 // shadow paint. 4098 /* 4099 ::SwAlignRect( aOut, pGlobalShell ); 4100 */ 4101 if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 ) 4102 { 4103 aOut._Intersection( rRect ); 4104 pOut->DrawRect( aOut.SVRect() ); 4105 } 4106 } 4107 } 4108 4109 /************************************************************************* 4110 |* SwFrm::PaintBorderLine() 4111 |* 4112 |* Ersterstellung MA 22. Dec. 92 4113 |* Letzte Änderung MA 22. Jan. 95 4114 |*************************************************************************/ 4115 4116 void SwFrm::PaintBorderLine( const SwRect& rRect, 4117 const SwRect& rOutRect, 4118 const SwPageFrm* /*pPage*/, 4119 const Color *pColor ) const 4120 { 4121 if ( !rOutRect.IsOver( rRect ) ) 4122 return; 4123 4124 SwRect aOut( rOutRect ); 4125 aOut._Intersection( rRect ); 4126 4127 const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0; 4128 sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB : 4129 ( IsInSct() ? SUBCOL_SECT : 4130 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) ); 4131 if( pColor && pGlobalShell->GetWin() && 4132 Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 4133 { 4134 pColor = &SwViewOption::GetFontColor(); 4135 } 4136 4137 //if ( pPage->GetSortedObjs() ) 4138 //{ 4139 // SwRegionRects aRegion( aOut, 4, 1 ); 4140 // ::lcl_SubtractFlys( this, pPage, aOut, aRegion ); 4141 // for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 4142 // pLines->AddLineRect( aRegion[i], pColor, pTab, nSubCol ); 4143 //} 4144 //else 4145 pLines->AddLineRect( aOut, pColor, pTab, nSubCol ); 4146 } 4147 4148 /************************************************************************* 4149 |* SwFrm::PaintBorderLines() 4150 |* 4151 |* Beschreibung Nur alle Linien einfach oder alle Linien doppelt!!!! 4152 |* Ersterstellung MA 22. Dec. 92 4153 |* Letzte Änderung MA 22. Mar. 95 4154 |*************************************************************************/ 4155 4156 // OD 29.04.2003 #107169# - method called for left and right border rectangles. 4157 // For a printer output device perform adjustment for non-overlapping top and 4158 // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate 4159 // printer output device. 4160 // NOTE: For printer output device left/right border rectangle <_iorRect> 4161 // has to be already non-overlapping the outer top/bottom border rectangle. 4162 void MA_FASTCALL lcl_SubTopBottom( SwRect& _iorRect, 4163 const SvxBoxItem& _rBox, 4164 const SwBorderAttrs& _rAttrs, 4165 const SwFrm& _rFrm, 4166 const SwRectFn& _rRectFn, 4167 const sal_Bool _bPrtOutputDev ) 4168 { 4169 const sal_Bool bCnt = _rFrm.IsCntntFrm(); 4170 if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() && 4171 ( !bCnt || _rAttrs.GetTopLine( _rFrm ) ) 4172 ) 4173 { 4174 // subtract distance between outer and inner line. 4175 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() ); 4176 // OD 19.05.2003 #109667# - non-overlapping border rectangles: 4177 // adjust x-/y-position, if inner top line is a hair line (width = 1) 4178 sal_Bool bIsInnerTopLineHairline = sal_False; 4179 if ( !_bPrtOutputDev ) 4180 { 4181 // additionally subtract width of top outer line 4182 // --> left/right inner/outer line doesn't overlap top outer line. 4183 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() ); 4184 } 4185 else 4186 { 4187 // OD 29.04.2003 #107169# - additionally subtract width of top inner line 4188 // --> left/right inner/outer line doesn't overlap top inner line. 4189 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() ); 4190 bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1; 4191 } 4192 (_iorRect.*_rRectFn->fnSubTop)( -nDist ); 4193 // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line 4194 // is a hair line 4195 if ( bIsInnerTopLineHairline ) 4196 { 4197 if ( _rFrm.IsVertical() ) 4198 { 4199 // right of border rectangle has to be checked and adjusted 4200 Point aCompPt( _iorRect.Right(), 0 ); 4201 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() ); 4202 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4203 aRefPt, aCompPt, 4204 sal_True, -1 ); 4205 _iorRect.Right( aCompPt.X() ); 4206 } 4207 else 4208 { 4209 // top of border rectangle has to be checked and adjusted 4210 Point aCompPt( 0, _iorRect.Top() ); 4211 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 ); 4212 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4213 aRefPt, aCompPt, 4214 sal_False, +1 ); 4215 _iorRect.Top( aCompPt.Y() ); 4216 } 4217 } 4218 } 4219 4220 if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() && 4221 ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) ) 4222 ) 4223 { 4224 // subtract distance between outer and inner line. 4225 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() ); 4226 // OD 19.05.2003 #109667# - non-overlapping border rectangles: 4227 // adjust x-/y-position, if inner bottom line is a hair line (width = 1) 4228 sal_Bool bIsInnerBottomLineHairline = sal_False; 4229 if ( !_bPrtOutputDev ) 4230 { 4231 // additionally subtract width of bottom outer line 4232 // --> left/right inner/outer line doesn't overlap bottom outer line. 4233 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() ); 4234 } 4235 else 4236 { 4237 // OD 29.04.2003 #107169# - additionally subtract width of bottom inner line 4238 // --> left/right inner/outer line doesn't overlap bottom inner line. 4239 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() ); 4240 bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1; 4241 } 4242 (_iorRect.*_rRectFn->fnAddBottom)( -nDist ); 4243 // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner 4244 // bottom line is a hair line. 4245 if ( bIsInnerBottomLineHairline ) 4246 { 4247 if ( _rFrm.IsVertical() ) 4248 { 4249 // left of border rectangle has to be checked and adjusted 4250 Point aCompPt( _iorRect.Left(), 0 ); 4251 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() ); 4252 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4253 aRefPt, aCompPt, 4254 sal_True, +1 ); 4255 _iorRect.Left( aCompPt.X() ); 4256 } 4257 else 4258 { 4259 // bottom of border rectangle has to be checked and adjusted 4260 Point aCompPt( 0, _iorRect.Bottom() ); 4261 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 ); 4262 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4263 aRefPt, aCompPt, 4264 sal_False, -1 ); 4265 _iorRect.Bottom( aCompPt.Y() ); 4266 } 4267 } 4268 } 4269 } 4270 4271 // method called for top and bottom border rectangles. 4272 void MA_FASTCALL lcl_SubLeftRight( SwRect& rRect, 4273 const SvxBoxItem& rBox, 4274 const SwRectFn& rRectFn ) 4275 { 4276 if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() ) 4277 { 4278 const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() ) 4279 + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() ); 4280 (rRect.*rRectFn->fnSubLeft)( -nDist ); 4281 } 4282 4283 if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() ) 4284 { 4285 const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() ) 4286 + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() ); 4287 (rRect.*rRectFn->fnAddRight)( -nDist ); 4288 } 4289 } 4290 4291 // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine> 4292 // into new method <lcl_PaintLeftRightLine(..)> 4293 void lcl_PaintLeftRightLine( const sal_Bool _bLeft, 4294 const SwFrm& _rFrm, 4295 const SwPageFrm& _rPage, 4296 const SwRect& _rOutRect, 4297 const SwRect& _rRect, 4298 const SwBorderAttrs& _rAttrs, 4299 const SwRectFn& _rRectFn ) 4300 { 4301 const SvxBoxItem& rBox = _rAttrs.GetBox(); 4302 const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft(); 4303 const SvxBorderLine* pLeftRightBorder = 0; 4304 if ( _bLeft ) 4305 { 4306 pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft(); 4307 } 4308 else 4309 { 4310 pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight(); 4311 } 4312 // OD 06.05.2003 #107169# - init boolean indicating printer output device. 4313 const sal_Bool bPrtOutputDev = 4314 ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() ); 4315 4316 if ( !pLeftRightBorder ) 4317 { 4318 return; 4319 } 4320 4321 SwRect aRect( _rOutRect ); 4322 if ( _bLeft ) 4323 { 4324 (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) - 4325 (aRect.*_rRectFn->fnGetWidth)() ); 4326 } 4327 else 4328 { 4329 (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) - 4330 (aRect.*_rRectFn->fnGetWidth)() ); 4331 } 4332 4333 const sal_Bool bCnt = _rFrm.IsCntntFrm(); 4334 4335 if ( bCnt ) 4336 { 4337 ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn ); 4338 } 4339 4340 // OD 06.05.2003 #107169# - adjustments for printer output device 4341 if ( bPrtOutputDev ) 4342 { 4343 // subtract width of outer top line. 4344 if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) ) 4345 { 4346 long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() ); 4347 (aRect.*_rRectFn->fnSubTop)( -nDist ); 4348 // OD 19.05.2003 #109667# - If outer top line is hair line, calculated 4349 // top has to be adjusted. 4350 if ( nDist == 1 ) 4351 { 4352 if ( _rFrm.IsVertical() ) 4353 { 4354 // right of border rectangle has to be checked and adjusted 4355 Point aCompPt( aRect.Right(), 0 ); 4356 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() ); 4357 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4358 aRefPt, aCompPt, 4359 sal_True, -1 ); 4360 aRect.Right( aCompPt.X() ); 4361 } 4362 else 4363 { 4364 // top of border rectangle has to be checked and adjusted 4365 Point aCompPt( 0, aRect.Top() ); 4366 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 ); 4367 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4368 aRefPt, aCompPt, 4369 sal_False, +1 ); 4370 aRect.Top( aCompPt.Y() ); 4371 } 4372 } 4373 } 4374 // subtract width of outer bottom line. 4375 if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) ) 4376 { 4377 long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth()); 4378 (aRect.*_rRectFn->fnAddBottom)( -nDist ); 4379 // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated 4380 // top has to be adjusted. 4381 if ( nDist == 1 ) 4382 { 4383 if ( _rFrm.IsVertical() ) 4384 { 4385 // left of border rectangle has to be checked and adjusted 4386 Point aCompPt( aRect.Left(), 0 ); 4387 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() ); 4388 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4389 aRefPt, aCompPt, 4390 sal_True, +1 ); 4391 aRect.Left( aCompPt.X() ); 4392 } 4393 else 4394 { 4395 // bottom of border rectangle has to be checked and adjusted 4396 Point aCompPt( 0, aRect.Bottom() ); 4397 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 ); 4398 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()), 4399 aRefPt, aCompPt, 4400 sal_False, -1 ); 4401 aRect.Bottom( aCompPt.Y() ); 4402 } 4403 } 4404 } 4405 } 4406 4407 if ( !pLeftRightBorder->GetInWidth() ) 4408 { 4409 // OD 06.05.2003 #107169# - add 6th parameter 4410 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev ); 4411 } 4412 4413 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4414 { 4415 SwRect aPaintRect( aRect ); 4416 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4417 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle 4418 // to the prior left position with width of one twip. 4419 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 ) 4420 { 4421 if ( _bLeft ) 4422 { 4423 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() ); 4424 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() ); 4425 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4426 } 4427 else 4428 { 4429 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4430 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4431 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4432 } 4433 } 4434 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() ); 4435 } 4436 4437 if ( pLeftRightBorder->GetInWidth() ) 4438 { 4439 const long nDist = ::lcl_MinWidthDist( pLeftRightBorder->GetDistance() ); 4440 long nWidth = ::lcl_AlignWidth( pLeftRightBorder->GetInWidth() ); 4441 if ( _bLeft ) 4442 { 4443 (aRect.*_rRectFn->fnAddRight)( nDist + nWidth ); 4444 (aRect.*_rRectFn->fnSubLeft)( nWidth - (aRect.*_rRectFn->fnGetWidth)() ); 4445 } 4446 else 4447 { 4448 (aRect.*_rRectFn->fnSubLeft)( nDist + nWidth ); 4449 (aRect.*_rRectFn->fnAddRight)( nWidth - (aRect.*_rRectFn->fnGetWidth)() ); 4450 } 4451 // OD 06.05.2003 #107169# - add 6th parameter 4452 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev ); 4453 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4454 { 4455 SwRect aPaintRect( aRect ); 4456 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4457 // if <SwAlignRect> reveals rectangle with no width, adjust 4458 // rectangle to the prior left position with width of one twip. 4459 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 ) 4460 { 4461 if ( _bLeft ) 4462 { 4463 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() ); 4464 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() ); 4465 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4466 } 4467 else 4468 { 4469 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4470 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 ); 4471 (aPaintRect.*_rRectFn->fnAddRight)( 1 ); 4472 } 4473 } 4474 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() ); 4475 } 4476 } 4477 } 4478 4479 // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine> 4480 // into <lcl_PaintTopLine> 4481 void lcl_PaintTopBottomLine( const sal_Bool _bTop, 4482 const SwFrm& _rFrm, 4483 const SwPageFrm& _rPage, 4484 const SwRect& _rOutRect, 4485 const SwRect& _rRect, 4486 const SwBorderAttrs& _rAttrs, 4487 const SwRectFn& _rRectFn ) 4488 { 4489 const SvxBoxItem& rBox = _rAttrs.GetBox(); 4490 const SvxBorderLine* pTopBottomBorder = 0; 4491 if ( _bTop ) 4492 { 4493 pTopBottomBorder = rBox.GetTop(); 4494 } 4495 else 4496 { 4497 pTopBottomBorder = rBox.GetBottom(); 4498 } 4499 4500 if ( !pTopBottomBorder ) 4501 { 4502 return; 4503 } 4504 4505 SwRect aRect( _rOutRect ); 4506 if ( _bTop ) 4507 { 4508 (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) - 4509 (aRect.*_rRectFn->fnGetHeight)() ); 4510 } 4511 else 4512 { 4513 (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) - 4514 (aRect.*_rRectFn->fnGetHeight)() ); 4515 } 4516 4517 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4518 { 4519 SwRect aPaintRect( aRect ); 4520 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4521 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle 4522 // to the prior top position with width of one twip. 4523 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 ) 4524 { 4525 if ( _bTop ) 4526 { 4527 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() ); 4528 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() ); 4529 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4530 } 4531 else 4532 { 4533 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4534 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4535 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4536 } 4537 } 4538 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() ); 4539 } 4540 4541 if ( pTopBottomBorder->GetInWidth() ) 4542 { 4543 const long nDist = ::lcl_MinHeightDist( pTopBottomBorder->GetDistance() ); 4544 const long nHeight = ::lcl_AlignHeight( pTopBottomBorder->GetInWidth() ); 4545 if ( _bTop ) 4546 { 4547 (aRect.*_rRectFn->fnAddBottom)( nDist + nHeight ); 4548 (aRect.*_rRectFn->fnSubTop)( nHeight - (aRect.*_rRectFn->fnGetHeight)() ); 4549 } 4550 else 4551 { 4552 (aRect.*_rRectFn->fnSubTop)( nDist + nHeight ); 4553 (aRect.*_rRectFn->fnAddBottom)( nHeight -(aRect.*_rRectFn->fnGetHeight)() ); 4554 } 4555 ::lcl_SubLeftRight( aRect, rBox, _rRectFn ); 4556 // OD 29.04.2003 #107169# - paint SwAligned-rectangle 4557 { 4558 SwRect aPaintRect( aRect ); 4559 ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() ); 4560 // if <SwAlignRect> reveals rectangle with no width, adjust 4561 // rectangle to the prior top position with width of one twip. 4562 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 ) 4563 { 4564 if ( _bTop ) 4565 { 4566 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() ); 4567 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() ); 4568 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4569 } 4570 else 4571 { 4572 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4573 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 ); 4574 (aPaintRect.*_rRectFn->fnAddBottom)( 1 ); 4575 } 4576 } 4577 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() ); 4578 } 4579 } 4580 } 4581 4582 /************************************************************************* 4583 |* const SwFrm* lcl_HasNextCell( const SwFrm& rFrm ) 4584 |* 4585 |* No comment. #i15844# 4586 |*************************************************************************/ 4587 4588 const SwFrm* lcl_HasNextCell( const SwFrm& rFrm ) 4589 { 4590 ASSERT( rFrm.IsCellFrm(), 4591 "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" ) 4592 4593 const SwFrm* pTmpFrm = &rFrm; 4594 do 4595 { 4596 if ( pTmpFrm->GetNext() ) 4597 return pTmpFrm->GetNext(); 4598 4599 pTmpFrm = pTmpFrm->GetUpper()->GetUpper(); 4600 } 4601 while ( pTmpFrm->IsCellFrm() ); 4602 4603 return 0; 4604 } 4605 4606 /************************************************************************* 4607 |* SwFrm::PaintBorder() 4608 |* 4609 |* Beschreibung Malt Schatten und Umrandung 4610 |* Ersterstellung MA 23.01.92 4611 |* Letzte Änderung MA 29. Jul. 96 4612 |*************************************************************************/ 4613 4614 /** local method to determine cell frame, from which the border attributes 4615 for paint of top/bottom border has to be used. 4616 4617 OD 21.02.2003 #b4779636#, #107692# 4618 4619 @author OD 4620 4621 @param _pCellFrm 4622 input parameter - constant pointer to cell frame for which the cell frame 4623 for the border attributes has to be determined. 4624 4625 @param _rCellBorderAttrs 4626 input parameter - constant reference to the border attributes of cell frame 4627 <_pCellFrm>. 4628 4629 @param _bTop 4630 input parameter - boolean, that controls, if cell frame for top border or 4631 for bottom border has to be determined. 4632 4633 @return constant pointer to cell frame, for which the border attributes has 4634 to be used 4635 */ 4636 const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm* _pCellFrm, 4637 const SwBorderAttrs& _rCellBorderAttrs, 4638 const bool _bTop ) 4639 { 4640 ASSERT( _pCellFrm, "No cell frame available, dying soon" ) 4641 4642 // determine, if cell frame is at bottom/top border of a table frame and 4643 // the table frame has/is a follow. 4644 const SwFrm* pTmpFrm = _pCellFrm; 4645 bool bCellAtBorder = true; 4646 bool bCellAtLeftBorder = !_pCellFrm->GetPrev(); 4647 bool bCellAtRightBorder = !_pCellFrm->GetNext(); 4648 while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() ) 4649 { 4650 pTmpFrm = pTmpFrm->GetUpper(); 4651 if ( pTmpFrm->IsRowFrm() && 4652 (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext()) 4653 ) 4654 { 4655 bCellAtBorder = false; 4656 } 4657 if ( pTmpFrm->IsCellFrm() ) 4658 { 4659 if ( pTmpFrm->GetPrev() ) 4660 { 4661 bCellAtLeftBorder = false; 4662 } 4663 if ( pTmpFrm->GetNext() ) 4664 { 4665 bCellAtRightBorder = false; 4666 } 4667 } 4668 } 4669 ASSERT( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" ); 4670 4671 const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm); 4672 const SwTabFrm* pParentTabFrm = 4673 static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper()); 4674 4675 const bool bCellNeedsAttribute = bCellAtBorder && 4676 ( _bTop ? 4677 // bCellInFirstRowWithMaster 4678 ( !pParentRowFrm->GetPrev() && 4679 pParentTabFrm->IsFollow() && 4680 0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) : 4681 // bCellInLastRowWithFollow 4682 ( !pParentRowFrm->GetNext() && 4683 pParentTabFrm->GetFollow() ) 4684 ); 4685 4686 const SwFrm* pRet = _pCellFrm; 4687 if ( bCellNeedsAttribute ) 4688 { 4689 // determine, if cell frame has no borders inside the table. 4690 const SwFrm* pNextCell = 0; 4691 bool bNoBordersInside = false; 4692 4693 if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) ) 4694 { 4695 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell ); 4696 const SwBorderAttrs &rBorderAttrs = *aAccess.Get(); 4697 const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox(); 4698 bCellAtRightBorder = !lcl_HasNextCell( *pNextCell ); 4699 bNoBordersInside = 4700 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) && 4701 !rBorderBox.GetLeft() && 4702 ( !rBorderBox.GetRight() || bCellAtRightBorder ) && 4703 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() ); 4704 } 4705 else 4706 { 4707 const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox(); 4708 bNoBordersInside = 4709 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) && 4710 ( !rBorderBox.GetLeft() || bCellAtLeftBorder ) && 4711 ( !rBorderBox.GetRight() || bCellAtRightBorder ) && 4712 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() ); 4713 } 4714 4715 if ( bNoBordersInside ) 4716 { 4717 if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() ) 4718 { 4719 // #b4779636#-hack: 4720 // Cell frame has no top border and no border inside the table, but 4721 // it is at the top border of a table frame, which is a follow. 4722 // Thus, use border attributes of cell frame in first row of complete table. 4723 // First, determine first table frame of complete table. 4724 SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true ); 4725 // determine first row of complete table. 4726 const SwFrm* pFirstRow = pMasterTabFrm->GetLower(); 4727 // return first cell in first row 4728 SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower()); 4729 while ( !pLowerCell->IsCellFrm() || 4730 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() ) 4731 ) 4732 { 4733 pLowerCell = pLowerCell->GetLower(); 4734 } 4735 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" ); 4736 pRet = pLowerCell; 4737 } 4738 else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() ) 4739 { 4740 // #b4779636#-hack: 4741 // Cell frame has no bottom border and no border inside the table, 4742 // but it is at the bottom border of a table frame, which has a follow. 4743 // Thus, use border attributes of cell frame in last row of complete table. 4744 // First, determine last table frame of complete table. 4745 SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow()); 4746 while ( pLastTabFrm->GetFollow() ) 4747 { 4748 pLastTabFrm = pLastTabFrm->GetFollow(); 4749 } 4750 // determine last row of complete table. 4751 SwFrm* pLastRow = pLastTabFrm->GetLastLower(); 4752 // return first bottom border cell in last row 4753 SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower()); 4754 while ( !pLowerCell->IsCellFrm() || 4755 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() ) 4756 ) 4757 { 4758 if ( pLowerCell->IsRowFrm() ) 4759 { 4760 while ( pLowerCell->GetNext() ) 4761 { 4762 pLowerCell = pLowerCell->GetNext(); 4763 } 4764 } 4765 pLowerCell = pLowerCell->GetLower(); 4766 } 4767 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" ); 4768 pRet = pLowerCell; 4769 } 4770 } 4771 } 4772 4773 return pRet; 4774 } 4775 4776 void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage, 4777 const SwBorderAttrs &rAttrs ) const 4778 { 4779 //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun 4780 if ( (GetType() & 0x90C5) || (Prt().SSize() == Frm().SSize()) ) 4781 return; 4782 4783 if ( (GetType() & 0x2000) && //Cell 4784 !pGlobalShell->GetViewOptions()->IsTable() ) 4785 return; 4786 4787 // --> collapsing borders FME 2005-05-27 #i29550# 4788 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() ) 4789 { 4790 const SwTabFrm* pTabFrm = FindTabFrm(); 4791 if ( pTabFrm->IsCollapsingBorders() ) 4792 return; 4793 4794 if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) ) 4795 return; 4796 } 4797 // <-- 4798 4799 const bool bLine = rAttrs.IsLine() ? true : false; 4800 const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE; 4801 4802 // OD 24.02.2003 #b4779636#, #107692# - flag to control, 4803 // if #b4779636#-hack has to be used. 4804 const bool bb4779636HackActive = true; 4805 // OD 21.02.2003 #b4779636#, #107692# 4806 const SwFrm* pCellFrmForBottomBorderAttrs = 0; 4807 const SwFrm* pCellFrmForTopBorderAttrs = 0; 4808 bool bFoundCellForTopOrBorderAttrs = false; 4809 if ( bb4779636HackActive && IsCellFrm() ) 4810 { 4811 pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false ); 4812 if ( pCellFrmForBottomBorderAttrs != this ) 4813 bFoundCellForTopOrBorderAttrs = true; 4814 pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true ); 4815 if ( pCellFrmForTopBorderAttrs != this ) 4816 bFoundCellForTopOrBorderAttrs = true; 4817 } 4818 4819 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs> 4820 // for #b4779636#-hack 4821 if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs ) 4822 { 4823 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, 4824 //so braucht kein Rand gepaintet werden. 4825 //Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden, 4826 //anderfalls wuerden u.U. Teile nicht verarbeitet. 4827 SwRect aRect( Prt() ); 4828 aRect += Frm().Pos(); 4829 ::SwAlignRect( aRect, pGlobalShell ); 4830 // OD 27.09.2002 #103636# - new local boolean variable in order to 4831 // suspend border paint under special cases - see below. 4832 // NOTE: This is a fix for the implementation of feature #99657#. 4833 bool bDrawOnlyShadowForTransparentFrame = false; 4834 if ( aRect.IsInside( rRect ) ) 4835 { 4836 // OD 27.09.2002 #103636# - paint shadow, if background is transparent. 4837 // Because of introduced transparent background for fly frame #99657#, 4838 // the shadow has to be drawn if the background is transparent, 4839 // in spite the fact that the paint rectangle <rRect> lies fully 4840 // in the printing area. 4841 // NOTE to chosen solution: 4842 // On transparent background, continue processing, but suspend 4843 // drawing of border by setting <bDrawOnlyShadowForTransparentFrame> 4844 // to true. 4845 if ( IsLayoutFrm() && 4846 static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() ) 4847 { 4848 bDrawOnlyShadowForTransparentFrame = true; 4849 } 4850 else 4851 { 4852 return; 4853 } 4854 } 4855 4856 if ( !pPage ) 4857 pPage = FindPageFrm(); 4858 4859 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True ); 4860 rAttrs.SetGetCacheLine( sal_True ); 4861 if ( bShadow ) 4862 PaintShadow( rRect, aRect, rAttrs ); 4863 // OD 27.09.2002 #103636# - suspend drawing of border 4864 // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above 4865 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs> 4866 // for #b4779636#-hack. 4867 if ( ( bLine || bFoundCellForTopOrBorderAttrs ) && 4868 !bDrawOnlyShadowForTransparentFrame ) 4869 { 4870 const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this; 4871 SWRECTFN( pDirRefFrm ) 4872 // OD 19.05.2003 #109667# - use new method <lcl_PaintLeftRightLine(..)> 4873 //::lcl_PaintLeftLine ( this, pPage, aRect, rRect, rAttrs, fnRect ); 4874 //::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs, fnRect ); 4875 ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4876 ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4877 if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) ) 4878 { 4879 // OD 21.02.2003 #b4779636#, #107692# - 4880 // #b4779636#-hack: If another cell frame for top border 4881 // paint is found, paint its top border. 4882 if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this ) 4883 { 4884 SwBorderAttrAccess aAccess( SwFrm::GetCache(), 4885 pCellFrmForTopBorderAttrs ); 4886 const SwBorderAttrs &rTopAttrs = *aAccess.Get(); 4887 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4888 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rTopAttrs, fnRect ); 4889 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect ); 4890 } 4891 else 4892 { 4893 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4894 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs, fnRect ); 4895 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect ); 4896 } 4897 } 4898 if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) ) 4899 { 4900 // OD 21.02.2003 #b4779636#, #107692# - 4901 // #b4779636#-hack: If another cell frame for bottom border 4902 // paint is found, paint its bottom border. 4903 if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this ) 4904 { 4905 SwBorderAttrAccess aAccess( SwFrm::GetCache(), 4906 pCellFrmForBottomBorderAttrs ); 4907 const SwBorderAttrs &rBottomAttrs = *aAccess.Get(); 4908 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4909 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rBottomAttrs, fnRect); 4910 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect); 4911 } 4912 else 4913 { 4914 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)> 4915 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rAttrs, fnRect); 4916 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect); 4917 } 4918 } 4919 } 4920 rAttrs.SetGetCacheLine( sal_False ); 4921 } 4922 } 4923 /************************************************************************* 4924 |* SwFtnContFrm::PaintBorder() 4925 |* 4926 |* Beschreibung Spezialimplementierung wg. der Fussnotenlinie. 4927 |* Derzeit braucht nur der obere Rand berücksichtigt werden. 4928 |* Auf andere Linien und Schatten wird verzichtet. 4929 |* Ersterstellung MA 27. Feb. 93 4930 |* Letzte Änderung MA 08. Sep. 93 4931 |*************************************************************************/ 4932 4933 void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage, 4934 const SwBorderAttrs & ) const 4935 { 4936 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es 4937 //keinen Rand zu painten. 4938 SwRect aRect( Prt() ); 4939 aRect.Pos() += Frm().Pos(); 4940 if ( !aRect.IsInside( rRect ) ) 4941 PaintLine( rRect, pPage ); 4942 } 4943 /************************************************************************* 4944 |* SwFtnContFrm::PaintLine() 4945 |* 4946 |* Beschreibung Fussnotenline malen. 4947 |* Ersterstellung MA 02. Mar. 93 4948 |* Letzte Änderung MA 28. Mar. 94 4949 |*************************************************************************/ 4950 4951 void SwFtnContFrm::PaintLine( const SwRect& rRect, 4952 const SwPageFrm *pPage ) const 4953 { 4954 // Länge der Linie ergibt sich aus der prozentualen Angabe am PageDesc. 4955 // Die Position ist ebenfalls am PageDesc angegeben. 4956 // Der Pen steht direkt im PageDesc. 4957 4958 if ( !pPage ) 4959 pPage = FindPageFrm(); 4960 const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo(); 4961 4962 SWRECTFN( this ) 4963 SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)(); 4964 Fraction aFract( nPrtWidth, 1 ); 4965 const SwTwips nWidth = (long)(aFract *= rInf.GetWidth()); 4966 4967 SwTwips nX = (this->*fnRect->fnGetPrtLeft)(); 4968 switch ( rInf.GetAdj() ) 4969 { 4970 case FTNADJ_CENTER: 4971 nX += nPrtWidth/2 - nWidth/2; break; 4972 case FTNADJ_RIGHT: 4973 nX += nPrtWidth - nWidth; break; 4974 case FTNADJ_LEFT: 4975 /* do nothing */; break; 4976 default: 4977 ASSERT( sal_False, "New adjustment for footnote line?" ); 4978 } 4979 SwTwips nLineWidth = rInf.GetLineWidth(); 4980 const SwRect aLineRect = bVert ? 4981 SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth, 4982 nX), Size( nLineWidth, nWidth ) ) 4983 : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ), 4984 Size( nWidth, rInf.GetLineWidth())); 4985 if ( aLineRect.HasArea() ) 4986 PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() ); 4987 } 4988 4989 /************************************************************************* 4990 |* SwLayoutFrm::PaintColLines() 4991 |* 4992 |* Beschreibung Painted die Trennlinien für die innenliegenden 4993 |* Spalten. 4994 |* Ersterstellung MA 21. Jun. 93 4995 |* Letzte Änderung MA 28. Mar. 94 4996 |*************************************************************************/ 4997 4998 void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol, 4999 const SwPageFrm *pPage ) const 5000 { 5001 const SwFrm *pCol = Lower(); 5002 if ( !pCol || !pCol->IsColumnFrm() ) 5003 return; 5004 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 5005 SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 5006 5007 SwRect aLineRect = Prt(); 5008 aLineRect += Frm().Pos(); 5009 5010 SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight()) 5011 / 100 - (aLineRect.*fnRect->fnGetHeight)(); 5012 SwTwips nBottom = 0; 5013 5014 switch ( rFmtCol.GetLineAdj() ) 5015 { 5016 case COLADJ_CENTER: 5017 nBottom = nTop / 2; nTop -= nBottom; break; 5018 case COLADJ_TOP: 5019 nBottom = nTop; nTop = 0; break; 5020 case COLADJ_BOTTOM: 5021 break; 5022 default: 5023 ASSERT( sal_False, "New adjustment for column line?" ); 5024 } 5025 5026 if( nTop ) 5027 (aLineRect.*fnRect->fnSubTop)( nTop ); 5028 if( nBottom ) 5029 (aLineRect.*fnRect->fnAddBottom)( nBottom ); 5030 5031 SwTwips nPenHalf = rFmtCol.GetLineWidth(); 5032 (aLineRect.*fnRect->fnSetWidth)( nPenHalf ); 5033 nPenHalf /= 2; 5034 5035 // Damit uns nichts verloren geht müssen wir hier etwas großzügiger sein. 5036 SwRect aRect( rRect ); 5037 (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW ); 5038 (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW ); 5039 SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight; 5040 while ( pCol->GetNext() ) 5041 { 5042 (aLineRect.*fnRect->fnSetPosX) 5043 ( (pCol->Frm().*fnGetX)() - nPenHalf ); 5044 if ( aRect.IsOver( aLineRect ) ) 5045 PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor()); 5046 pCol = pCol->GetNext(); 5047 } 5048 } 5049 5050 void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const 5051 { 5052 if( !bHasGrid || pRetoucheFly || pRetoucheFly2 ) 5053 return; 5054 GETGRID( this ) 5055 if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ? 5056 pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) ) 5057 { 5058 const SwLayoutFrm* pBody = FindBodyCont(); 5059 if( pBody ) 5060 { 5061 SwRect aGrid( pBody->Prt() ); 5062 aGrid += pBody->Frm().Pos(); 5063 5064 SwRect aInter( aGrid ); 5065 aInter.Intersection( rRect ); 5066 if( aInter.HasArea() ) 5067 { 5068 sal_Bool bGrid = pGrid->GetRubyTextBelow(); 5069 sal_Bool bCell = GRID_LINES_CHARS == pGrid->GetGridType(); 5070 long nGrid = pGrid->GetBaseHeight(); 5071 const SwDoc* pDoc = GetFmt()->GetDoc(); 5072 long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor 5073 long nRuby = pGrid->GetRubyHeight(); 5074 long nSum = nGrid + nRuby; 5075 const Color *pCol = &pGrid->GetColor(); 5076 5077 SwTwips nRight = aInter.Left() + aInter.Width(); 5078 SwTwips nBottom = aInter.Top() + aInter.Height(); 5079 if( IsVertical() ) 5080 { 5081 SwTwips nOrig = aGrid.Left() + aGrid.Width(); 5082 SwTwips nY = nOrig + nSum * 5083 ( ( nOrig - aInter.Left() ) / nSum ); 5084 SwRect aTmp( Point( nY, aInter.Top() ), 5085 Size( 1, aInter.Height() ) ); 5086 SwTwips nX = aGrid.Top() + nGrid * 5087 ( ( aInter.Top() - aGrid.Top() )/ nGrid ); 5088 if( nX < aInter.Top() ) 5089 nX += nGrid; 5090 SwTwips nGridBottom = aGrid.Top() + aGrid.Height(); 5091 sal_Bool bLeft = aGrid.Top() >= aInter.Top(); 5092 sal_Bool bRight = nGridBottom <= nBottom; 5093 sal_Bool bBorder = bLeft || bRight; 5094 while( nY > nRight ) 5095 { 5096 aTmp.Pos().X() = nY; 5097 if( bGrid ) 5098 { 5099 nY -= nGrid; 5100 SwTwips nPosY = Max( aInter.Left(), nY ); 5101 SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY; 5102 if( nHeight > 0 ) 5103 { 5104 if( bCell ) 5105 { 5106 SwRect aVert( Point( nPosY, nX ), 5107 Size( nHeight, 1 ) ); 5108 while( aVert.Top() <= nBottom ) 5109 { 5110 PaintBorderLine(rRect,aVert,this,pCol); 5111 aVert.Pos().Y() += nGrid; 5112 } 5113 } 5114 else if( bBorder ) 5115 { 5116 SwRect aVert( Point( nPosY, aGrid.Top() ), 5117 Size( nHeight, 1 ) ); 5118 if( bLeft ) 5119 PaintBorderLine(rRect,aVert,this,pCol); 5120 if( bRight ) 5121 { 5122 aVert.Pos().Y() = nGridBottom; 5123 PaintBorderLine(rRect,aVert,this,pCol); 5124 } 5125 } 5126 } 5127 } 5128 else 5129 { 5130 nY -= nRuby; 5131 if( bBorder ) 5132 { 5133 SwTwips nPos = Max( aInter.Left(), nY ); 5134 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos; 5135 SwRect aVert( Point( nPos, aGrid.Top() ), 5136 Size( nW, 1 ) ); 5137 if( nW > 0 ) 5138 { 5139 if( bLeft ) 5140 PaintBorderLine(rRect,aVert,this,pCol); 5141 if( bRight ) 5142 { 5143 aVert.Pos().Y() = nGridBottom; 5144 PaintBorderLine(rRect,aVert,this,pCol); 5145 } 5146 } 5147 } 5148 } 5149 bGrid = !bGrid; 5150 } 5151 while( nY >= aInter.Left() ) 5152 { 5153 aTmp.Pos().X() = nY; 5154 PaintBorderLine( rRect, aTmp, this, pCol); 5155 if( bGrid ) 5156 { 5157 nY -= nGrid; 5158 SwTwips nHeight = aTmp.Pos().X() 5159 - Max(aInter.Left(), nY ); 5160 if( nHeight > 0 ) 5161 { 5162 if( bCell ) 5163 { 5164 SwRect aVert( Point(aTmp.Pos().X()-nHeight, 5165 nX ), Size( nHeight, 1 ) ); 5166 while( aVert.Top() <= nBottom ) 5167 { 5168 PaintBorderLine(rRect,aVert,this,pCol); 5169 aVert.Pos().Y() += nGrid; 5170 } 5171 } 5172 else if( bBorder ) 5173 { 5174 SwRect aVert( Point(aTmp.Pos().X()-nHeight, 5175 aGrid.Top() ), Size( nHeight, 1 ) ); 5176 if( bLeft ) 5177 PaintBorderLine(rRect,aVert,this,pCol); 5178 if( bRight ) 5179 { 5180 aVert.Pos().Y() = nGridBottom; 5181 PaintBorderLine(rRect,aVert,this,pCol); 5182 } 5183 } 5184 } 5185 } 5186 else 5187 { 5188 nY -= nRuby; 5189 if( bBorder ) 5190 { 5191 SwTwips nPos = Max( aInter.Left(), nY ); 5192 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos; 5193 SwRect aVert( Point( nPos, aGrid.Top() ), 5194 Size( nW, 1 ) ); 5195 if( nW > 0 ) 5196 { 5197 if( bLeft ) 5198 PaintBorderLine(rRect,aVert,this,pCol); 5199 if( bRight ) 5200 { 5201 aVert.Pos().Y() = nGridBottom; 5202 PaintBorderLine(rRect,aVert,this,pCol); 5203 } 5204 } 5205 } 5206 } 5207 bGrid = !bGrid; 5208 } 5209 } 5210 else 5211 { 5212 SwTwips nOrig = aGrid.Top(); 5213 SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum ); 5214 SwRect aTmp( Point( aInter.Left(), nY ), 5215 Size( aInter.Width(), 1 ) ); 5216 //for textgrid refactor 5217 SwTwips nX = aGrid.Left() + nGridWidth * 5218 ( ( aInter.Left() - aGrid.Left() )/ nGridWidth ); 5219 if( nX < aInter.Left() ) 5220 nX += nGridWidth; 5221 SwTwips nGridRight = aGrid.Left() + aGrid.Width(); 5222 sal_Bool bLeft = aGrid.Left() >= aInter.Left(); 5223 sal_Bool bRight = nGridRight <= nRight; 5224 sal_Bool bBorder = bLeft || bRight; 5225 while( nY < aInter.Top() ) 5226 { 5227 aTmp.Pos().Y() = nY; 5228 if( bGrid ) 5229 { 5230 nY += nGrid; 5231 SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() ); 5232 SwTwips nHeight = Min(nBottom, nY ) - nPosY; 5233 if( nHeight ) 5234 { 5235 if( bCell ) 5236 { 5237 SwRect aVert( Point( nX, nPosY ), 5238 Size( 1, nHeight ) ); 5239 while( aVert.Left() <= nRight ) 5240 { 5241 PaintBorderLine(rRect,aVert,this,pCol); 5242 aVert.Pos().X() += nGridWidth; //for textgrid refactor 5243 } 5244 } 5245 else if ( bBorder ) 5246 { 5247 SwRect aVert( Point( aGrid.Left(), nPosY ), 5248 Size( 1, nHeight ) ); 5249 if( bLeft ) 5250 PaintBorderLine(rRect,aVert,this,pCol); 5251 if( bRight ) 5252 { 5253 aVert.Pos().X() = nGridRight; 5254 PaintBorderLine(rRect,aVert,this,pCol); 5255 } 5256 } 5257 } 5258 } 5259 else 5260 { 5261 nY += nRuby; 5262 if( bBorder ) 5263 { 5264 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y()); 5265 SwTwips nH = Min( nBottom, nY ) - nPos; 5266 SwRect aVert( Point( aGrid.Left(), nPos ), 5267 Size( 1, nH ) ); 5268 if( nH > 0 ) 5269 { 5270 if( bLeft ) 5271 PaintBorderLine(rRect,aVert,this,pCol); 5272 if( bRight ) 5273 { 5274 aVert.Pos().X() = nGridRight; 5275 PaintBorderLine(rRect,aVert,this,pCol); 5276 } 5277 } 5278 } 5279 } 5280 bGrid = !bGrid; 5281 } 5282 while( nY <= nBottom ) 5283 { 5284 aTmp.Pos().Y() = nY; 5285 PaintBorderLine( rRect, aTmp, this, pCol); 5286 if( bGrid ) 5287 { 5288 nY += nGrid; 5289 SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y(); 5290 if( nHeight ) 5291 { 5292 if( bCell ) 5293 { 5294 SwRect aVert( Point( nX, aTmp.Pos().Y() ), 5295 Size( 1, nHeight ) ); 5296 while( aVert.Left() <= nRight ) 5297 { 5298 PaintBorderLine( rRect, aVert, this, pCol); 5299 aVert.Pos().X() += nGridWidth; //for textgrid refactor 5300 } 5301 } 5302 else if( bBorder ) 5303 { 5304 SwRect aVert( Point( aGrid.Left(), 5305 aTmp.Pos().Y() ), Size( 1, nHeight ) ); 5306 if( bLeft ) 5307 PaintBorderLine(rRect,aVert,this,pCol); 5308 if( bRight ) 5309 { 5310 aVert.Pos().X() = nGridRight; 5311 PaintBorderLine(rRect,aVert,this,pCol); 5312 } 5313 } 5314 } 5315 } 5316 else 5317 { 5318 nY += nRuby; 5319 if( bBorder ) 5320 { 5321 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y()); 5322 SwTwips nH = Min( nBottom, nY ) - nPos; 5323 SwRect aVert( Point( aGrid.Left(), nPos ), 5324 Size( 1, nH ) ); 5325 if( nH > 0 ) 5326 { 5327 if( bLeft ) 5328 PaintBorderLine(rRect,aVert,this,pCol); 5329 if( bRight ) 5330 { 5331 aVert.Pos().X() = nGridRight; 5332 PaintBorderLine(rRect,aVert,this,pCol); 5333 } 5334 } 5335 } 5336 } 5337 bGrid = !bGrid; 5338 } 5339 } 5340 } 5341 } 5342 } 5343 } 5344 5345 /** paint margin area of a page 5346 5347 OD 20.11.2002 for #104598#: 5348 implement paint of margin area; margin area will be painted for a 5349 view shell with a window and if the document is not in online layout. 5350 5351 @author OD 5352 5353 @param _rOutputRect 5354 input parameter - constant instance reference of the rectangle, for 5355 which an output has to be generated. 5356 5357 @param _pViewShell 5358 input parameter - instance of the view shell, on which the output 5359 has to be generated. 5360 */ 5361 void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect, 5362 ViewShell* _pViewShell ) const 5363 { 5364 if ( _pViewShell->GetWin() && !_pViewShell->GetViewOptions()->getBrowseMode() ) 5365 { 5366 //UUUU Simplified paint with DrawingLayer FillStyle 5367 SwRect aPgRect = Frm(); 5368 aPgRect._Intersection( _rOutputRect ); 5369 5370 if(!aPgRect.IsEmpty()) 5371 { 5372 OutputDevice *pOut = _pViewShell->GetOut(); 5373 5374 if(pOut->GetFillColor() != aGlobalRetoucheColor) 5375 { 5376 pOut->SetFillColor(aGlobalRetoucheColor); 5377 } 5378 5379 pOut->DrawRect(aPgRect.SVRect()); 5380 } 5381 } 5382 } 5383 5384 // OD 12.02.2003 for #i9719# and #105645# 5385 // ---------------------------------------------------------------------- 5386 5387 const sal_Int8 SwPageFrm::mnBorderPxWidth = 1; 5388 5389 /** determine rectangle for page border 5390 5391 OD 12.02.2003 for #i9719# and #105645# 5392 5393 @author OD 5394 */ 5395 /*static*/ void SwPageFrm::GetBorderRect( const SwRect& _rPageRect, 5396 ViewShell* _pViewShell, 5397 SwRect& _orBorderRect, 5398 bool bRightSidebar ) 5399 { 5400 SwRect aAlignedPageRect( _rPageRect ); 5401 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5402 Rectangle aBorderPxRect = 5403 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5404 5405 aBorderPxRect.Left() = aBorderPxRect.Left() - mnBorderPxWidth; 5406 aBorderPxRect.Top() = aBorderPxRect.Top() - mnBorderPxWidth; 5407 aBorderPxRect.Right() = aBorderPxRect.Right() + mnBorderPxWidth; 5408 aBorderPxRect.Bottom() = aBorderPxRect.Bottom() + mnBorderPxWidth; 5409 5410 AddSidebarBorders(aBorderPxRect,_pViewShell, bRightSidebar, true); 5411 5412 _orBorderRect = 5413 SwRect( _pViewShell->GetOut()->PixelToLogic( aBorderPxRect ) ); 5414 } 5415 5416 /** determine rectangle for right page shadow 5417 5418 OD 12.02.2003 for #i9719# and #105645# 5419 5420 @author OD 5421 */ 5422 /*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect, 5423 ViewShell* _pViewShell, 5424 SwRect& _orRightShadowRect, 5425 bool bRightSidebar ) 5426 { 5427 SwRect aAlignedPageRect( _rPageRect ); 5428 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5429 Rectangle aPagePxRect = 5430 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5431 5432 Rectangle aRightShadowPxRect( 5433 aPagePxRect.Right(), 5434 aPagePxRect.Top() + 1, 5435 aPagePxRect.Right() + mnBorderPxWidth, 5436 aPagePxRect.Bottom() + mnBorderPxWidth ); 5437 5438 if ( bRightSidebar ) 5439 AddSidebarBorders(aRightShadowPxRect,_pViewShell, bRightSidebar, true); 5440 5441 _orRightShadowRect = 5442 SwRect( _pViewShell->GetOut()->PixelToLogic( aRightShadowPxRect ) ); 5443 } 5444 5445 /** determine rectangle for bottom page shadow 5446 5447 OD 12.02.2003 for #i9719# and #105645# 5448 5449 @author OD 5450 */ 5451 /*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect, 5452 ViewShell* _pViewShell, 5453 SwRect& _orBottomShadowRect, 5454 bool bRightSidebar ) 5455 { 5456 SwRect aAlignedPageRect( _rPageRect ); 5457 ::SwAlignRect( aAlignedPageRect, _pViewShell ); 5458 Rectangle aPagePxRect = 5459 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ); 5460 5461 Rectangle aBottomShadowPxRect( 5462 aPagePxRect.Left() + 1, 5463 aPagePxRect.Bottom(), 5464 aPagePxRect.Right() + mnBorderPxWidth, 5465 aPagePxRect.Bottom() + mnBorderPxWidth ); 5466 5467 AddSidebarBorders(aBottomShadowPxRect,_pViewShell, bRightSidebar, true); 5468 5469 _orBottomShadowRect = 5470 SwRect( _pViewShell->GetOut()->PixelToLogic( aBottomShadowPxRect ) ); 5471 } 5472 5473 /** paint page border (shadow removed now) 5474 5475 OD 12.02.2003 for #i9719# and #105645# 5476 implement paint of page border 5477 5478 @author OD 5479 */ 5480 /*static*/ void SwPageFrm::PaintPageBorder( const SwRect& _rPageRect, 5481 ViewShell* _pViewShell, 5482 bool bRightSidebar ) 5483 { 5484 // --> FME 2004-06-24 #i16816# tagged pdf support 5485 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() ); 5486 // <-- 5487 5488 // get color for page border 5489 const Color& rColor = SwViewOption::GetFontColor(); 5490 5491 // save current fill and line color of output device 5492 Color aFill( _pViewShell->GetOut()->GetFillColor() ); 5493 Color aLine( _pViewShell->GetOut()->GetLineColor() ); 5494 5495 // paint page border 5496 _pViewShell->GetOut()->SetFillColor(); // OD 20.02.2003 #107369# - no fill color 5497 _pViewShell->GetOut()->SetLineColor( rColor ); 5498 SwRect aPaintRect; 5499 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar ); 5500 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() ); 5501 } 5502 5503 //mod #i6193# paint sidebar for notes 5504 //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit 5505 /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight) 5506 { 5507 //TODO: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons 5508 if (!_pViewShell ) 5509 return; 5510 5511 SwRect aPageRect( _rPageRect ); 5512 SwAlignRect( aPageRect, _pViewShell ); 5513 5514 const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr(); 5515 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) // do not show anything in print preview 5516 { 5517 sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight(); 5518 const Rectangle &aVisRect = _pViewShell->VisArea().SVRect(); 5519 //draw border and sidepane 5520 _pViewShell->GetOut()->SetLineColor(); 5521 if (!bRight) 5522 { 5523 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER); 5524 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()))) ; 5525 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5526 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5527 else 5528 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE); 5529 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()))) ; 5530 } 5531 else 5532 { 5533 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER); 5534 SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height())); 5535 _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect()); 5536 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5537 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5538 else 5539 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE); 5540 SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height())); 5541 _pViewShell->GetOut()->DrawRect(aSidebar.SVRect()); 5542 } 5543 if (pMgr->ShowScrollbar(nPageNum)) 5544 { 5545 // draw scrollbar area and arrows 5546 Point aPointBottom; 5547 Point aPointTop; 5548 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()) : 5549 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height()); 5550 aPointTop = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) : 5551 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()); 5552 Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ; 5553 Rectangle aRectBottom(aPointBottom,aSize); 5554 Rectangle aRectTop(aPointTop,aSize); 5555 5556 if (aRectBottom.IsOver(aVisRect)) 5557 { 5558 5559 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5560 { 5561 _pViewShell->GetOut()->SetLineColor(COL_WHITE); 5562 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5563 } 5564 else 5565 { 5566 _pViewShell->GetOut()->SetLineColor(COL_BLACK); 5567 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA); 5568 } 5569 _pViewShell->GetOut()->DrawRect(aRectBottom); 5570 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height())); 5571 5572 _pViewShell->GetOut()->SetLineColor(); 5573 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5574 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5575 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum)); 5576 } 5577 if (aRectTop.IsOver(aVisRect)) 5578 { 5579 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 5580 { 5581 _pViewShell->GetOut()->SetLineColor(COL_WHITE); 5582 _pViewShell->GetOut()->SetFillColor(COL_BLACK); 5583 } 5584 else 5585 { 5586 _pViewShell->GetOut()->SetLineColor(COL_BLACK); 5587 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA); 5588 } 5589 _pViewShell->GetOut()->DrawRect(aRectTop); 5590 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height())); 5591 5592 _pViewShell->GetOut()->SetLineColor(); 5593 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5594 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2)); 5595 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum)); 5596 } 5597 } 5598 } 5599 } 5600 5601 /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown) 5602 { 5603 Polygon aTriangleUp(3); 5604 Polygon aTriangleDown(3); 5605 5606 aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0); 5607 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1); 5608 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2); 5609 5610 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0); 5611 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1); 5612 aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2); 5613 5614 _pViewShell->GetOut()->SetFillColor(aColorUp); 5615 _pViewShell->GetOut()->DrawPolygon(aTriangleUp); 5616 _pViewShell->GetOut()->SetFillColor(aColorDown); 5617 _pViewShell->GetOut()->DrawPolygon(aTriangleDown); 5618 } 5619 5620 /** get bound rectangle of border and shadow for repaints 5621 5622 OD 12.02.2003 for #i9719# and #105645# 5623 5624 author OD 5625 */ 5626 /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect, 5627 ViewShell* _pViewShell, 5628 SwRect& _orBorderAndShadowBoundRect, 5629 bool bRightSidebar ) 5630 { 5631 SwRect aTmpRect; 5632 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, _orBorderAndShadowBoundRect, bRightSidebar ); 5633 SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar ); 5634 _orBorderAndShadowBoundRect.Union( aTmpRect ); 5635 SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar ); 5636 _orBorderAndShadowBoundRect.Union( aTmpRect ); 5637 5638 AddSidebarBorders(_orBorderAndShadowBoundRect, _pViewShell, bRightSidebar, false); 5639 } 5640 5641 /*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx) 5642 { 5643 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5644 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) 5645 { 5646 if (!bRightSidebar) 5647 aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5648 else 5649 aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5650 } 5651 } 5652 5653 /*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx) 5654 { 5655 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5656 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) 5657 { 5658 if (!bRightSidebar) 5659 aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx)); 5660 else 5661 aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx); 5662 } 5663 } 5664 5665 /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell ) 5666 { 5667 const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0; 5668 const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0; 5669 return nRet; 5670 } 5671 5672 /************************************************************************* 5673 |* SwFrm::PaintBaBo() 5674 |* 5675 |* Ersterstellung MA 22. Oct. 93 5676 |* Letzte Änderung MA 19. Jun. 96 5677 |*************************************************************************/ 5678 5679 void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage, 5680 const sal_Bool bLowerBorder ) const 5681 { 5682 if ( !pPage ) 5683 pPage = FindPageFrm(); 5684 5685 OutputDevice *pOut = pGlobalShell->GetOut(); 5686 5687 // --> FME 2004-06-24 #i16816# tagged pdf support 5688 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut ); 5689 // <-- 5690 5691 // OD 2004-04-23 #116347# 5692 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 5693 pOut->SetLineColor(); 5694 5695 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this ); 5696 const SwBorderAttrs &rAttrs = *aAccess.Get(); 5697 5698 // OD 20.11.2002 #104598# - take care of page margin area 5699 // Note: code move from <SwFrm::PaintBackground(..)> to new method 5700 // <SwPageFrm::Paintmargin(..)>. 5701 if ( IsPageFrm() ) 5702 { 5703 static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell ); 5704 } 5705 5706 // OD 06.08.2002 #99657# - paint border before painting background 5707 // paint grid for page frame and paint border 5708 { 5709 SwRect aRect( rRect ); 5710 if( IsPageFrm() ) 5711 ((SwPageFrm*)this)->PaintGrid( pOut, aRect ); 5712 PaintBorder( aRect, pPage, rAttrs ); 5713 } 5714 5715 // paint background 5716 { 5717 PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder ); 5718 } 5719 5720 pOut->Pop(); 5721 } 5722 5723 /************************************************************************* 5724 |* SwFrm::PaintBackground() 5725 |* 5726 |* Ersterstellung MA 04. Jan. 93 5727 |* Letzte Änderung MA 06. Feb. 97 5728 |*************************************************************************/ 5729 /// OD 05.09.2002 #102912# 5730 /// Do not paint background for fly frames without a background brush by 5731 /// calling <PaintBaBo> at the page or at the fly frame its anchored 5732 void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage, 5733 const SwBorderAttrs & rAttrs, 5734 const sal_Bool bLowerMode, 5735 const sal_Bool bLowerBorder ) const 5736 { 5737 // OD 20.01.2003 #i1837# - no paint of table background, if corresponding 5738 // option is *not* set. 5739 if( IsTabFrm() && 5740 !pGlobalShell->GetViewOptions()->IsTable() ) 5741 { 5742 return; 5743 } 5744 5745 // nothing to do for covered table cells: 5746 if( IsCellFrm() && IsCoveredCell() ) 5747 return; 5748 5749 ViewShell *pSh = pGlobalShell; 5750 5751 // --> FME 2004-06-24 #i16816# tagged pdf support 5752 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); 5753 // <-- 5754 5755 const SvxBrushItem* pItem; 5756 /// OD 05.09.2002 #102912# 5757 /// temporary background brush for a fly frame without a background brush 5758 SvxBrushItem* pTmpBackBrush = 0; 5759 const Color* pCol; 5760 SwRect aOrigBackRect; 5761 const sal_Bool bPageFrm = IsPageFrm(); 5762 sal_Bool bLowMode = sal_True; 5763 5764 //UUUU 5765 drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes; 5766 5767 sal_Bool bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, bLowerMode ); 5768 5769 //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird. 5770 bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm(); 5771 if ( bNoFlyBackground ) 5772 { 5773 // OD 05.09.2002 #102912# - Fly frame has no background. 5774 // Try to find background brush at parents, if previous call of 5775 // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode> 5776 if ( bLowerMode ) 5777 { 5778 bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, false ); 5779 } 5780 // If still no background found for the fly frame, initialize the 5781 // background brush <pItem> with global retouche color and set <bBack> 5782 // to sal_True, that fly frame will paint its background using this color. 5783 if ( !bBack ) 5784 { 5785 // OD 10.01.2003 #i6467# - on print output, pdf output and 5786 // in embedded mode not editing color COL_WHITE is used instead of 5787 // the global retouche color. 5788 if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER || 5789 pSh->GetViewOptions()->IsPDFExport() || 5790 ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && 5791 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() 5792 ) 5793 ) 5794 { 5795 pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND ); 5796 5797 //UUU 5798 aFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(Color( COL_WHITE ))); 5799 } 5800 else 5801 { 5802 pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND); 5803 5804 //UUU 5805 aFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(aGlobalRetoucheColor)); 5806 } 5807 5808 pItem = pTmpBackBrush; 5809 bBack = true; 5810 } 5811 } 5812 5813 SwRect aPaintRect( Frm() ); 5814 if( IsTxtFrm() || IsSctFrm() ) 5815 aPaintRect = UnionFrm( sal_True ); 5816 5817 if ( aPaintRect.IsOver( rRect ) ) 5818 { 5819 if ( bBack || bPageFrm || !bLowerMode ) 5820 { 5821 const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode(); 5822 SwRect aRect; 5823 if ( (bPageFrm && bBrowse) || 5824 (IsTxtFrm() && Prt().SSize() == Frm().SSize()) ) 5825 { 5826 aRect = Frm(); 5827 ::SwAlignRect( aRect, pGlobalShell ); 5828 } 5829 else 5830 { 5831 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_False ); 5832 if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() ) 5833 { 5834 if ( GetPrev()->GetAttrSet()->GetBackground() == 5835 GetAttrSet()->GetBackground() ) 5836 { 5837 aRect.Top( Frm().Top() ); 5838 } 5839 } 5840 } 5841 aRect.Intersection( rRect ); 5842 5843 OutputDevice *pOut = pSh->GetOut(); 5844 5845 if ( aRect.HasArea() ) 5846 { 5847 SvxBrushItem* pNewItem = 0; 5848 //SwRegionRects aRegion( aRect ); 5849 5850 if( pCol ) 5851 { 5852 pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND ); 5853 pItem = pNewItem; 5854 5855 //UUUU 5856 aFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(*pCol)); 5857 } 5858 5859 //if ( pPage->GetSortedObjs() ) 5860 //{ 5861 // ::lcl_SubtractFlys( this, pPage, aRect, aRegion ); 5862 //} 5863 5864 { 5865 /// OD 06.08.2002 #99657# - determine, if background transparency 5866 /// have to be considered for drawing. 5867 /// --> Status Quo: background transparency have to be 5868 /// considered for fly frames 5869 const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm(); 5870 bool bDone(false); 5871 5872 // #i125189# We are also done when the new DrawingLayer FillAttributes are used 5873 // or the FillStyle is set (different from XFILL_NONE) 5874 if(pOut && aFillAttributes.get()) 5875 { 5876 if(aFillAttributes->isUsed()) 5877 { 5878 // check if really something is painted 5879 bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRect, *pOut); 5880 } 5881 5882 if(!bDone) 5883 { 5884 // if not, still a FillStyle could be set but the transparency is at 100%, 5885 // thus need to check the model data itself for FillStyle (do not rely on 5886 // SdrAllFillAttributesHelper since it already contains optimized information, 5887 // e.g. transparency leads to no fill) 5888 const XFillStyle eFillStyle(static_cast< const XFillStyleItem& >(GetAttrSet()->Get(XATTR_FILLSTYLE)).GetValue()); 5889 5890 if(XFILL_NONE != eFillStyle) 5891 { 5892 bDone = true; 5893 } 5894 } 5895 } 5896 5897 if(!bDone) 5898 { 5899 //for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 5900 //{ 5901 // if ( 1 < aRegion.Count() ) 5902 // { 5903 // ::SwAlignRect( aRegion[i], pGlobalShell ); 5904 // if( !aRegion[i].HasArea() ) 5905 // continue; 5906 // } 5907 /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if 5908 /// background transparency have to be considered 5909 /// Set missing 5th parameter to the default value GRFNUM_NO 5910 /// - see declaration in /core/inc/frmtool.hxx. 5911 ::DrawGraphic( 5912 pItem, 5913 pOut, 5914 aOrigBackRect, 5915 aRect, // aRegion[i], 5916 GRFNUM_NO, 5917 bConsiderBackgroundTransparency ); 5918 //} 5919 } 5920 } 5921 if( pCol ) 5922 delete pNewItem; 5923 } 5924 } 5925 else 5926 bLowMode = bLowerMode ? sal_True : sal_False; 5927 } 5928 5929 /// OD 05.09.2002 #102912# 5930 /// delete temporary background brush. 5931 delete pTmpBackBrush; 5932 5933 // Jetzt noch Lower und dessen Nachbarn. 5934 // Wenn ein Frm dabei die Kette verlässt also nicht mehr Lower von mir ist 5935 // so hört der Spass auf. 5936 const SwFrm *pFrm = GetLower(); 5937 if ( pFrm ) 5938 { 5939 SwRect aFrmRect; 5940 SwRect aRect( PaintArea() ); 5941 aRect._Intersection( rRect ); 5942 SwRect aBorderRect( aRect ); 5943 SwShortCut aShortCut( *pFrm, aBorderRect ); 5944 do 5945 { if ( pProgress ) 5946 pProgress->Reschedule(); 5947 5948 aFrmRect = pFrm->PaintArea(); 5949 if ( aFrmRect.IsOver( aBorderRect ) ) 5950 { 5951 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm ); 5952 const SwBorderAttrs &rTmpAttrs = *aAccess.Get(); 5953 /// OD 06.08.2002 #99657# - paint border before painting background 5954 if ( bLowerBorder ) 5955 pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs ); 5956 if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) || 5957 aFrmRect.IsOver( aRect ) ) 5958 pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode, 5959 bLowerBorder ); 5960 } 5961 pFrm = pFrm->GetNext(); 5962 } while ( pFrm && pFrm->GetUpper() == this && 5963 !aShortCut.Stop( aFrmRect ) ); 5964 } 5965 } 5966 5967 /************************************************************************* 5968 |* SwPageFrm::RefreshSubsidiary() 5969 |* 5970 |* Beschreibung Erneuert alle Hilfslinien der Seite. 5971 |* Ersterstellung MA 04. Nov. 92 5972 |* Letzte Änderung MA 10. May. 95 5973 |*************************************************************************/ 5974 5975 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const 5976 { 5977 if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS ) 5978 { 5979 SwRect aRect( rRect ); 5980 // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of 5981 // the output rectangle. 5982 //::SwAlignRect( aRect, pGlobalShell ); 5983 if ( aRect.HasArea() ) 5984 { 5985 // Beim Paint über die Root wird das Array von dort gesteuert. 5986 // Anderfalls kümmern wir uns selbst darum. 5987 sal_Bool bDelSubs = sal_False; 5988 if ( !pSubsLines ) 5989 { 5990 pSubsLines = new SwSubsRects; 5991 // OD 20.12.2002 #106318# - create container for special subsidiary lines 5992 pSpecSubsLines = new SwSubsRects; 5993 bDelSubs = sal_True; 5994 } 5995 5996 RefreshLaySubsidiary( this, aRect ); 5997 5998 if ( bDelSubs ) 5999 { 6000 // OD 20.12.2002 #106318# - paint special subsidiary lines 6001 // and delete its container 6002 pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL ); 6003 DELETEZ( pSpecSubsLines ); 6004 6005 pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines ); 6006 DELETEZ( pSubsLines ); 6007 } 6008 } 6009 } 6010 } 6011 6012 /************************************************************************* 6013 |* SwLayoutFrm::RefreshLaySubsidiary() 6014 |* 6015 |* Ersterstellung MA 04. Nov. 92 6016 |* Letzte Änderung MA 22. Jan. 95 6017 |*************************************************************************/ 6018 void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage, 6019 const SwRect &rRect ) const 6020 { 6021 const sal_Bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm(); 6022 const sal_Bool bSubsOpt = IS_SUBS; 6023 const sal_Bool bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE); 6024 const sal_Bool bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt; 6025 const sal_Bool bSubsSect = IsSctFrm() && 6026 bNoLowerColumn && 6027 IS_SUBS_SECTION; 6028 const sal_Bool bSubsFly = IS_SUBS_FLYS && 6029 (GetType() & FRM_FLY) && 6030 bNoLowerColumn && 6031 (!Lower() || !Lower()->IsNoTxtFrm() || 6032 !((SwNoTxtFrm*)Lower())->HasAnimation()); 6033 sal_Bool bSubsBody = sal_False; 6034 if ( GetType() & FRM_BODY ) 6035 { 6036 if ( IsPageBodyFrm() ) 6037 bSubsBody = bSubsOpt && bNoLowerColumn; //nur ohne Spalten 6038 else //Spaltenbody 6039 { 6040 if ( GetUpper()->GetUpper()->IsSctFrm() ) 6041 bSubsBody = IS_SUBS_SECTION; 6042 else 6043 bSubsBody = bSubsOpt; 6044 } 6045 } 6046 6047 if ( bSubsOther || bSubsSect || bSubsBody || bSubsTable || bSubsFly ) 6048 PaintSubsidiaryLines( pPage, rRect ); 6049 6050 const SwFrm *pLow = Lower(); 6051 if( !pLow ) 6052 return; 6053 SwShortCut aShortCut( *pLow, rRect ); 6054 while( pLow && !aShortCut.Stop( pLow->Frm() ) ) 6055 { 6056 if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() ) 6057 { 6058 if ( pLow->IsLayoutFrm() ) 6059 ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect); 6060 else if ( pLow->GetDrawObjs() ) 6061 { 6062 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs()); 6063 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i ) 6064 { 6065 const SwAnchoredObject* pAnchoredObj = rObjs[i]; 6066 if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId( 6067 pAnchoredObj->GetDrawObj()->GetLayer() ) && 6068 pAnchoredObj->ISA(SwFlyFrm) ) 6069 { 6070 const SwFlyFrm *pFly = 6071 static_cast<const SwFlyFrm*>(pAnchoredObj); 6072 if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) ) 6073 { 6074 if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() || 6075 !((SwNoTxtFrm*)pFly->Lower())->HasAnimation()) 6076 pFly->RefreshLaySubsidiary( pPage, rRect ); 6077 } 6078 } 6079 } 6080 } 6081 } 6082 pLow = pLow->GetNext(); 6083 } 6084 } 6085 6086 /************************************************************************* 6087 |* SwLayoutFrm::PaintSubsidiaryLines() 6088 |* 6089 |* Beschreibung Hilfslinien um die PrtAreas malen 6090 |* Nur die LayoutFrm's die direkt Cntnt enthalten. 6091 |* Ersterstellung MA 21. May. 92 6092 |* Letzte Änderung MA 22. Jan. 95 6093 |*************************************************************************/ 6094 6095 //Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden. 6096 6097 typedef long Size::* SizePtr; 6098 typedef long Point::* PointPtr; 6099 6100 PointPtr pX = &Point::nA; 6101 PointPtr pY = &Point::nB; 6102 SizePtr pWidth = &Size::nA; 6103 SizePtr pHeight = &Size::nB; 6104 6105 // OD 18.11.2002 #99672# - new parameter <_pSubsLines> 6106 void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay, 6107 const SwPageFrm *pPage, 6108 const Point &rP1, 6109 const Point &rP2, 6110 const sal_uInt8 nSubColor, 6111 SwLineRects* _pSubsLines ) 6112 { 6113 //In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein. 6114 ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())), 6115 "Schraege Hilfslinien sind nicht erlaubt." ); 6116 const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX; 6117 const PointPtr pOthPt = pDirPt == pX ? pY : pX; 6118 const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight; 6119 const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth; 6120 Point aP1( rP1 ), 6121 aP2( rP2 ); 6122 6123 while ( aP1.*pDirPt < aP2.*pDirPt ) 6124 { // Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt 6125 // hinter den Fly gesetzt. 6126 // Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt 6127 // ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen. 6128 // Auf diese Art und Weise wird eine Portion nach der anderen 6129 // ausgegeben. 6130 6131 // Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus, 6132 // die 'über' mir sitzen; d.h. die in dem Array hinter mir stehen. 6133 // Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche 6134 // ich keinem dieser Flys aus. 6135 SwOrderIter aIter( pPage ); 6136 const SwFlyFrm *pMyFly = pLay->FindFlyFrm(); 6137 if ( pMyFly ) 6138 { 6139 aIter.Current( pMyFly->GetVirtDrawObj() ); 6140 while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) ) 6141 { 6142 if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() ) 6143 aIter.Current( pMyFly->GetVirtDrawObj() ); 6144 } 6145 } 6146 else 6147 aIter.Bottom(); 6148 6149 while ( aIter() ) 6150 { 6151 const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter(); 6152 const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0; 6153 6154 //Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich 6155 //_in_ dem Fly sitze weiche ich nicht aus. 6156 if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) ) 6157 { 6158 aIter.Next(); 6159 continue; 6160 } 6161 6162 // OD 19.12.2002 #106318# - do *not* consider fly frames with 6163 // a transparent background. 6164 // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which 6165 // belongs to a invisible layer 6166 if ( pFly->IsBackgroundTransparent() || 6167 !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) ) 6168 { 6169 aIter.Next(); 6170 continue; 6171 } 6172 6173 //Sitzt das Obj auf der Linie 6174 const Rectangle &rBound = pObj->GetCurrentBoundRect(); 6175 const Point aDrPt( rBound.TopLeft() ); 6176 const Size aDrSz( rBound.GetSize() ); 6177 if ( rP1.*pOthPt >= aDrPt.*pOthPt && 6178 rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) ) 6179 { 6180 if ( aP1.*pDirPt >= aDrPt.*pDirPt && 6181 aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) ) 6182 aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz; 6183 6184 if ( aP2.*pDirPt >= aDrPt.*pDirPt && 6185 aP1.*pDirPt < (aDrPt.*pDirPt - 1) ) 6186 aP2.*pDirPt = aDrPt.*pDirPt - 1; 6187 } 6188 aIter.Next(); 6189 } 6190 6191 if ( aP1.*pDirPt < aP2.*pDirPt ) 6192 { 6193 SwRect aRect( aP1, aP2 ); 6194 // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of 6195 // global variable <pSubsLines>. 6196 _pSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6197 } 6198 aP1 = aP2; 6199 aP1.*pDirPt += 1; 6200 aP2 = rP2; 6201 } 6202 } 6203 6204 void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage, 6205 const SwRect &rRect ) const 6206 { 6207 bool bNewTableModel = false; 6208 6209 // --> collapsing borders FME 2005-05-27 #i29550# 6210 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() ) 6211 { 6212 const SwTabFrm* pTabFrm = FindTabFrm(); 6213 if ( pTabFrm->IsCollapsingBorders() ) 6214 return; 6215 6216 bNewTableModel = pTabFrm->GetTable()->IsNewModel(); 6217 // in the new table model, we have an early return for all cell-related 6218 // frames, except from non-covered table cells 6219 if ( bNewTableModel ) 6220 if ( IsTabFrm() || 6221 IsRowFrm() || 6222 ( IsCellFrm() && IsCoveredCell() ) ) 6223 return; 6224 } 6225 // <-- collapsing 6226 6227 const bool bFlys = pPage->GetSortedObjs() ? true : false; 6228 6229 const bool bCell = IsCellFrm() ? true : false; 6230 // use frame area for cells 6231 // OD 13.02.2003 #i3662# - for section use also frame area 6232 const bool bUseFrmArea = bCell || IsSctFrm(); 6233 SwRect aOriginal( bUseFrmArea ? Frm() : Prt() ); 6234 if ( !bUseFrmArea ) 6235 aOriginal.Pos() += Frm().Pos(); 6236 6237 // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area 6238 // in sections to top of section frame. 6239 const bool bColBodyInSection = IsBodyFrm() && 6240 !IsPageBodyFrm() && 6241 GetUpper()->GetUpper()->IsSctFrm(); 6242 if ( bColBodyInSection ) 6243 { 6244 if ( IsVertical() ) 6245 aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() ); 6246 else 6247 aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() ); 6248 } 6249 6250 ::SwAlignRect( aOriginal, pGlobalShell ); 6251 6252 if ( !aOriginal.IsOver( rRect ) ) 6253 return; 6254 6255 SwRect aOut( aOriginal ); 6256 aOut._Intersection( rRect ); 6257 // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's 6258 // printing area with the paint area of the body frame. Otherwise enlargement 6259 // will get lost. 6260 if ( !bColBodyInSection ) 6261 { 6262 aOut.Intersection( PaintArea() ); 6263 } 6264 6265 const SwTwips nRight = aOut.Right(); 6266 const SwTwips nBottom= aOut.Bottom(); 6267 6268 const Point aRT( nRight, aOut.Top() ); 6269 const Point aRB( nRight, nBottom ); 6270 const Point aLB( aOut.Left(), nBottom ); 6271 6272 sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB : 6273 ( IsInSct() ? SUBCOL_SECT : 6274 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) ); 6275 6276 // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks. 6277 sal_Bool bBreak = sal_False; 6278 if ( IsBodyFrm() ) 6279 { 6280 const SwCntntFrm *pCnt = ContainsCntnt(); 6281 if ( pCnt ) 6282 { 6283 // OD 05.11.2002 #102406# - adjust setting of <bBreak>. 6284 bBreak = pCnt->IsPageBreak( sal_True ) || 6285 ( IsColBodyFrm() && pCnt->IsColBreak( sal_True ) ); 6286 } 6287 } 6288 6289 // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section 6290 // sub-lines in <pSpecSubsLine> array. 6291 const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() || 6292 IsFtnFrm() || IsSctFrm(); 6293 SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines; 6294 6295 // NOTE: for cell frames only left and right (horizontal layout) respectively 6296 // top and bottom (vertical layout) lines painted. 6297 // NOTE2: this does not hold for the new table model!!! We paint the top border 6298 // of each non-covered table cell. 6299 const bool bVert = IsVertical() ? true : false; 6300 if ( bFlys ) 6301 { 6302 // OD 14.11.2002 #104822# - add control for drawing left and right lines 6303 if ( !bCell || bNewTableModel || !bVert ) 6304 { 6305 if ( aOriginal.Left() == aOut.Left() ) 6306 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor, 6307 pUsedSubsLines ); 6308 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right 6309 if ( aOriginal.Right() == nRight ) 6310 ::lcl_RefreshLine( this, pPage, aRT, aRB, 6311 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor, 6312 pUsedSubsLines ); 6313 } 6314 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines 6315 if ( !bCell || bNewTableModel || bVert ) 6316 { 6317 if ( aOriginal.Top() == aOut.Top() ) 6318 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top 6319 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT, 6320 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor, 6321 pUsedSubsLines ); 6322 if ( aOriginal.Bottom() == nBottom ) 6323 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor, 6324 pUsedSubsLines ); 6325 } 6326 } 6327 else 6328 { 6329 // OD 14.11.2002 #104822# - add control for drawing left and right lines 6330 if ( !bCell || bNewTableModel || !bVert ) 6331 { 6332 if ( aOriginal.Left() == aOut.Left() ) 6333 { 6334 const SwRect aRect( aOut.Pos(), aLB ); 6335 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6336 } 6337 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right 6338 if ( aOriginal.Right() == nRight ) 6339 { 6340 const SwRect aRect( aRT, aRB ); 6341 pUsedSubsLines->AddLineRect( aRect, 0, 0, 6342 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor ); 6343 } 6344 } 6345 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines 6346 if ( !bCell || bNewTableModel || bVert ) 6347 { 6348 if ( aOriginal.Top() == aOut.Top() ) 6349 { 6350 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top 6351 const SwRect aRect( aOut.Pos(), aRT ); 6352 pUsedSubsLines->AddLineRect( aRect, 0, 0, 6353 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor ); 6354 } 6355 if ( aOriginal.Bottom() == nBottom ) 6356 { 6357 const SwRect aRect( aLB, aRB ); 6358 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor ); 6359 } 6360 } 6361 } 6362 } 6363 6364 /************************************************************************* 6365 |* SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData() 6366 |* 6367 |* Beschreibung Erneuert alle Extradaten (Zeilennummern usw) der Seite. 6368 |* Grundsätzlich sind nur diejenigen Objekte berücksichtigt, 6369 |* die in die seitliche Ausdehnung des Rects ragen. 6370 |* Ersterstellung MA 20. Jan. 98 6371 |* Letzte Änderung MA 18. Feb. 98 6372 |*************************************************************************/ 6373 6374 void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const 6375 { 6376 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo(); 6377 sal_Bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys()) 6378 || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE; 6379 6380 SwRect aRect( rRect ); 6381 ::SwAlignRect( aRect, pGlobalShell ); 6382 if ( aRect.HasArea() ) 6383 { 6384 SwLayoutFrm::RefreshExtraData( aRect ); 6385 6386 if ( bLineInFly && GetSortedObjs() ) 6387 for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i ) 6388 { 6389 const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i]; 6390 if ( pAnchoredObj->ISA(SwFlyFrm) ) 6391 { 6392 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); 6393 if ( pFly->Frm().Top() <= aRect.Bottom() && 6394 pFly->Frm().Bottom() >= aRect.Top() ) 6395 pFly->RefreshExtraData( aRect ); 6396 } 6397 } 6398 } 6399 } 6400 6401 void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const 6402 { 6403 6404 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo(); 6405 sal_Bool bLineInBody = rInfo.IsPaintLineNumbers(), 6406 bLineInFly = bLineInBody && rInfo.IsCountInFlys(), 6407 bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE; 6408 6409 const SwCntntFrm *pCnt = ContainsCntnt(); 6410 while ( pCnt && IsAnLower( pCnt ) ) 6411 { 6412 if ( pCnt->IsTxtFrm() && ( bRedLine || 6413 ( !pCnt->IsInTab() && 6414 ((bLineInBody && pCnt->IsInDocBody()) || 6415 (bLineInFly && pCnt->IsInFly())) ) ) && 6416 pCnt->Frm().Top() <= rRect.Bottom() && 6417 pCnt->Frm().Bottom() >= rRect.Top() ) 6418 { 6419 ((SwTxtFrm*)pCnt)->PaintExtraData( rRect ); 6420 } 6421 if ( bLineInFly && pCnt->GetDrawObjs() ) 6422 for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i ) 6423 { 6424 const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i]; 6425 if ( pAnchoredObj->ISA(SwFlyFrm) ) 6426 { 6427 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); 6428 if ( pFly->IsFlyInCntFrm() && 6429 pFly->Frm().Top() <= rRect.Bottom() && 6430 pFly->Frm().Bottom() >= rRect.Top() ) 6431 pFly->RefreshExtraData( rRect ); 6432 } 6433 } 6434 pCnt = pCnt->GetNextCntntFrm(); 6435 } 6436 } 6437 6438 /** SwPageFrm::GetDrawBackgrdColor - for #102450# 6439 6440 determine the color, that is respectively will be drawn as background 6441 for the page frame. 6442 Using existing method SwFrm::GetBackgroundBrush to determine the color 6443 that is set at the page frame respectively is parent. If none is found 6444 return the global retouche color 6445 6446 @author OD 6447 6448 @return Color 6449 */ 6450 const Color SwPageFrm::GetDrawBackgrdColor() const 6451 { 6452 const SvxBrushItem* pBrushItem; 6453 const Color* pDummyColor; 6454 SwRect aDummyRect; 6455 6456 //UUUU 6457 drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes; 6458 6459 if ( GetBackgroundBrush( aFillAttributes, pBrushItem, pDummyColor, aDummyRect, true) ) 6460 { 6461 if(aFillAttributes.get() && aFillAttributes->isUsed()) //UUUU 6462 { 6463 // let SdrAllFillAttributesHelper do the average color calculation 6464 return Color(aFillAttributes->getAverageColor(aGlobalRetoucheColor.getBColor())); 6465 } 6466 else if(pBrushItem) 6467 { 6468 const Graphic* pGraphic = pBrushItem->GetGraphic(); 6469 6470 if(pGraphic) 6471 { 6472 // #29105# when a graphic is set, it may be possible to calculate a single 6473 // color which looks good in all places of the graphic. Since it is 6474 // planned to have text edit on the overlay one day and the fallback 6475 // to aGlobalRetoucheColor returns something useful, just use that 6476 // for now. 6477 } 6478 else 6479 { 6480 // not a graphic, use (hopefully) initialized color 6481 return pBrushItem->GetColor(); 6482 } 6483 } 6484 } 6485 6486 return aGlobalRetoucheColor; 6487 } 6488 6489 /************************************************************************* 6490 |* SwPageFrm::GetEmptyPageFont() 6491 |* 6492 |* create/return font used to paint the "empty page" string 6493 |*************************************************************************/ 6494 6495 const Font& SwPageFrm::GetEmptyPageFont() 6496 { 6497 static Font* pEmptyPgFont = 0; 6498 if ( 0 == pEmptyPgFont ) 6499 { 6500 pEmptyPgFont = new Font; 6501 pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt 6502 pEmptyPgFont->SetWeight( WEIGHT_BOLD ); 6503 pEmptyPgFont->SetStyleName( aEmptyStr ); 6504 pEmptyPgFont->SetName( String::CreateFromAscii( 6505 RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) ); 6506 pEmptyPgFont->SetFamily( FAMILY_SWISS ); 6507 pEmptyPgFont->SetTransparent( sal_True ); 6508 pEmptyPgFont->SetColor( COL_GRAY ); 6509 } 6510 6511 return *pEmptyPgFont; 6512 } 6513 6514 /************************************************************************* 6515 |* SwFrm::Retouche 6516 |* 6517 |* Beschreibung Retouche für einen Bereich. 6518 |* Retouche wird nur dann durchgeführt, wenn der Frm der letzte seiner 6519 |* Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird 6520 |* per PaintBackground gecleared. 6521 |* Ersterstellung MA 13. Apr. 93 6522 |* Letzte Änderung MA 25. Jul. 96 6523 |*************************************************************************/ 6524 6525 void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const 6526 { 6527 if ( bFlyMetafile ) 6528 return; 6529 6530 ASSERT( GetUpper(), "Retoucheversuch ohne Upper." ); 6531 ASSERT( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" ); 6532 6533 SwRect aRetouche( GetUpper()->PaintArea() ); 6534 aRetouche.Top( Frm().Top() + Frm().Height() ); 6535 aRetouche.Intersection( pGlobalShell->VisArea() ); 6536 6537 if ( aRetouche.HasArea() ) 6538 { 6539 // Übergebenes Rect aussparen. Dafür brauchen wir leider eine Region 6540 // zum ausstanzen. 6541 SwRegionRects aRegion( aRetouche ); 6542 aRegion -= rRect; 6543 ViewShell *pSh = getRootFrm()->GetCurrShell(); 6544 6545 // --> FME 2004-06-24 #i16816# tagged pdf support 6546 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() ); 6547 // <-- 6548 6549 for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 6550 { 6551 SwRect &rRetouche = aRegion[i]; 6552 6553 GetUpper()->PaintBaBo( rRetouche, pPage, sal_True ); 6554 6555 // Hölle und Himmel müssen auch refreshed werden. 6556 // Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst 6557 // zurückgesetzt werden! 6558 ResetRetouche(); 6559 SwRect aRetouchePart( rRetouche ); 6560 if ( aRetouchePart.HasArea() ) 6561 { 6562 const Color aPageBackgrdColor(pPage->GetDrawBackgrdColor()); 6563 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 6564 // --> OD #i76669# 6565 SwViewObjectContactRedirector aSwRedirector( *pSh ); 6566 // <-- 6567 6568 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0, 6569 aRetouchePart, &aPageBackgrdColor, 6570 (pPage->IsRightToLeft() ? true : false), 6571 &aSwRedirector ); 6572 pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0, 6573 aRetouchePart, &aPageBackgrdColor, 6574 (pPage->IsRightToLeft() ? true : false), 6575 &aSwRedirector ); 6576 } 6577 6578 SetRetouche(); 6579 6580 //Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier 6581 //leider die Hilfslinien erneuert werden. 6582 pPage->RefreshSubsidiary( aRetouchePart ); 6583 } 6584 } 6585 if ( ViewShell::IsLstEndAction() ) 6586 ResetRetouche(); 6587 } 6588 6589 /** SwFrm::GetBackgroundBrush 6590 6591 @descr 6592 determine the background brush for the frame: 6593 the background brush is taken from it-self or from its parent (anchor/upper). 6594 Normally, the background brush is taken, which has no transparent color or 6595 which has a background graphic. But there are some special cases: 6596 (1) No background brush is taken from a page frame, if view option "IsPageBack" 6597 isn't set. 6598 (2) Background brush from a index section is taken under special conditions. 6599 In this case parameter <rpCol> is set to the index shading color. 6600 (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing 6601 of the frame transparency is considered and its color is not "no fill"/"auto fill" 6602 ---- old description in german: 6603 Beschreibung Liefert die Backgroundbrush für den Bereich des 6604 des Frm. Die Brush wird entweder von ihm selbst oder von einem 6605 Upper vorgegeben, die erste Brush wird benutzt. 6606 Ist für keinen Frm eine Brush angegeben, so wird sal_False zurück- 6607 geliefert. 6608 Ersterstellung MA 23. Dec. 92 6609 Letzte Aenderung MA 04. Feb. 97 6610 6611 @param rpBrush 6612 output parameter - constant reference pointer the found background brush 6613 6614 @param rpCol 6615 output parameter - constant reference pointer to the color of the index shading 6616 set under special conditions, if background brush is taken from an index section. 6617 6618 @param rOrigRect 6619 in-/output parameter - reference to the rectangle the background brush is 6620 considered for - adjusted to the frame, from which the background brush is 6621 taken. 6622 6623 @parem bLowerMode 6624 input parameter - boolean indicating, if background brush should *not* be 6625 taken from parent. 6626 6627 @author MA 6628 @change 20.08.2002 by OD 6629 @docdate 20.08.2002 6630 6631 @return true, if a background brush for the frame is found 6632 */ 6633 sal_Bool SwFrm::GetBackgroundBrush( 6634 drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes, 6635 const SvxBrushItem* & rpBrush, 6636 const Color*& rpCol, 6637 SwRect &rOrigRect, 6638 sal_Bool bLowerMode ) const 6639 { 6640 const SwFrm *pFrm = this; 6641 ViewShell *pSh = getRootFrm()->GetCurrShell(); 6642 const SwViewOption *pOpt = pSh->GetViewOptions(); 6643 rpBrush = 0; 6644 rpCol = NULL; 6645 do 6646 { if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() ) 6647 return sal_False; 6648 6649 //UUUU 6650 rFillAttributes = pFrm->getSdrAllFillAttributesHelper(); 6651 const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground(); 6652 6653 if( pFrm->IsSctFrm() ) 6654 { 6655 const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection(); 6656 /// OD 20.08.2002 #99657# #GetTransChg# 6657 /// Note: If frame <pFrm> is a section of the index and 6658 /// it its background color is "no fill"/"auto fill" and 6659 /// it has no background graphic and 6660 /// we are not in the page preview and 6661 /// we are not in read-only mode and 6662 /// option "index shadings" is set and 6663 /// the output is not the printer 6664 /// then set <rpCol> to the color of the index shading 6665 if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() || 6666 TOX_CONTENT_SECTION == pSection->GetType() ) && 6667 (rBack.GetColor() == COL_TRANSPARENT) && 6668 ///rBack.GetColor().GetTransparency() && 6669 rBack.GetGraphicPos() == GPOS_NONE && 6670 !pOpt->IsPagePreview() && 6671 !pOpt->IsReadonly() && 6672 // --> FME 2004-06-29 #114856# Formular view 6673 !pOpt->IsFormView() && 6674 // <-- 6675 SwViewOption::IsIndexShadings() && 6676 !pOpt->IsPDFExport() && 6677 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER ) 6678 { 6679 rpCol = &SwViewOption::GetIndexShadingsColor(); 6680 } 6681 } 6682 6683 /// OD 20.08.2002 #99657# 6684 /// determine, if background draw of frame <pFrm> considers transparency 6685 /// --> Status Quo: background transparency have to be 6686 /// considered for fly frames 6687 const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm(); 6688 6689 // #i125189# Do not base the decision for using the parent's fill style for this 6690 // frame when the new DrawingLayer FillAttributes are used on the SdrAllFillAttributesHelper 6691 // information. There the data is already optimized to no fill in the case that the 6692 // transparency is at 100% while no fill is the criteria for derivation 6693 bool bNewDrawingLayerFillStyleIsUsedAndNotNoFill(false); 6694 6695 if(rFillAttributes.get()) 6696 { 6697 // the new DrawingLayer FillStyle is used 6698 if(rFillAttributes->isUsed()) 6699 { 6700 // it's not XFILL_NONE 6701 bNewDrawingLayerFillStyleIsUsedAndNotNoFill = true; 6702 } 6703 else 6704 { 6705 // maybe optimized already when 100% transparency is used somewhere, need to test 6706 // XFillStyleItem directly from the model data 6707 const XFillStyle eFillStyle(static_cast< const XFillStyleItem& >(pFrm->GetAttrSet()->Get(XATTR_FILLSTYLE)).GetValue()); 6708 6709 if(XFILL_NONE != eFillStyle) 6710 { 6711 bNewDrawingLayerFillStyleIsUsedAndNotNoFill = true; 6712 } 6713 } 6714 } 6715 6716 /// OD 20.08.2002 #99657# 6717 /// add condition: 6718 /// If <bConsiderBackgroundTransparency> is set - see above -, 6719 /// return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill" 6720 if ( 6721 // #i125189# Done when the new DrawingLayer FillAttributes are used and 6722 // not XFILL_NONE (see above) 6723 bNewDrawingLayerFillStyleIsUsedAndNotNoFill || 6724 6725 // done when SvxBrushItem is used 6726 !rBack.GetColor().GetTransparency() || rBack.GetGraphicPos() != GPOS_NONE || 6727 6728 // done when direct color is forced 6729 rpCol || 6730 6731 // done when consider BG transparency and color is not completely transparent 6732 (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT)) 6733 ) 6734 { 6735 rpBrush = &rBack; 6736 6737 if ( pFrm->IsPageFrm() && pSh->GetViewOptions()->getBrowseMode() ) 6738 { 6739 rOrigRect = pFrm->Frm(); 6740 } 6741 else 6742 { 6743 if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() ) 6744 { 6745 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); 6746 const SwBorderAttrs &rAttrs = *aAccess.Get(); 6747 ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, sal_False ); 6748 } 6749 else 6750 { 6751 rOrigRect = pFrm->Prt(); 6752 rOrigRect += pFrm->Frm().Pos(); 6753 } 6754 } 6755 6756 return sal_True; 6757 } 6758 6759 if ( bLowerMode ) 6760 { 6761 /// Do not try to get background brush from parent (anchor/upper) 6762 return sal_False; 6763 } 6764 6765 /// get parent frame - anchor or upper - for next loop 6766 if ( pFrm->IsFlyFrm() ) 6767 { 6768 /// OD 20.08.2002 - use "static_cast" instead of "old C-cast" 6769 pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm(); 6770 ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor(); 6771 } 6772 else 6773 { 6774 pFrm = pFrm->GetUpper(); 6775 } 6776 } while ( pFrm ); 6777 6778 return sal_False; 6779 } 6780 6781 /************************************************************************* 6782 |* SwFrmFmt::GetGraphic() 6783 |* 6784 |* Ersterstellung MA 23. Jul. 96 6785 |* Letzte Änderung MA 23. Jul. 96 6786 |*************************************************************************/ 6787 6788 void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO, 6789 Window *pW, sal_uInt16 nZoom ) 6790 { 6791 pSh->pOut = pO; 6792 pSh->pWin = pW; 6793 pSh->pOpt->SetZoom( nZoom ); 6794 } 6795 6796 Graphic SwFrmFmt::MakeGraphic( ImageMap* ) 6797 { 6798 return Graphic(); 6799 } 6800 6801 Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap ) 6802 { 6803 Graphic aRet; 6804 //irgendeinen Fly suchen! 6805 SwIterator<SwFrm,SwFmt> aIter( *this ); 6806 SwFrm *pFirst = aIter.First(); 6807 ViewShell *pSh; 6808 if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) ) 6809 { 6810 ViewShell *pOldGlobal = pGlobalShell; 6811 pGlobalShell = pSh; 6812 6813 sal_Bool bNoteURL = pMap && 6814 SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, sal_True ); 6815 if( bNoteURL ) 6816 { 6817 ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " ); 6818 pNoteURL = new SwNoteURL; 6819 } 6820 SwFlyFrm *pFly = (SwFlyFrm*)pFirst; 6821 6822 OutputDevice *pOld = pSh->GetOut(); 6823 VirtualDevice aDev( *pOld ); 6824 aDev.EnableOutput( sal_False ); 6825 6826 GDIMetaFile aMet; 6827 MapMode aMap( pOld->GetMapMode().GetMapUnit() ); 6828 aDev.SetMapMode( aMap ); 6829 aMet.SetPrefMapMode( aMap ); 6830 6831 ::SwCalcPixStatics( pSh->GetOut() ); 6832 aMet.SetPrefSize( pFly->Frm().SSize() ); 6833 6834 aMet.Record( &aDev ); 6835 aDev.SetLineColor(); 6836 aDev.SetFillColor(); 6837 aDev.SetFont( pOld->GetFont() ); 6838 6839 //Rechteck ggf. ausdehnen, damit die Umrandungen mit aufgezeichnet werden. 6840 SwRect aOut( pFly->Frm() ); 6841 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly ); 6842 const SwBorderAttrs &rAttrs = *aAccess.Get(); 6843 if ( rAttrs.CalcRightLine() ) 6844 aOut.SSize().Width() += 2*nPixelSzW; 6845 if ( rAttrs.CalcBottomLine() ) 6846 aOut.SSize().Height()+= 2*nPixelSzH; 6847 6848 // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev 6849 const Region aRepaintRegion(aOut.SVRect()); 6850 pSh->DLPrePaint2(aRepaintRegion); 6851 6852 Window *pWin = pSh->GetWin(); 6853 sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom(); 6854 ::SetOutDevAndWin( pSh, &aDev, 0, 100 ); 6855 bFlyMetafile = sal_True; 6856 pFlyMetafileOut = pWin; 6857 6858 SwViewImp *pImp = pSh->Imp(); 6859 pFlyOnlyDraw = pFly; 6860 pLines = new SwLineRects; 6861 6862 // OD 09.12.2002 #103045# - determine page, fly frame is on 6863 const SwPageFrm* pFlyPage = pFly->FindPageFrm(); 6864 const Color aPageBackgrdColor(pFlyPage->GetDrawBackgrdColor()); 6865 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess(); 6866 // --> OD #i76669# 6867 SwViewObjectContactRedirector aSwRedirector( *pSh ); 6868 // <-- 6869 pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor, 6870 (pFlyPage->IsRightToLeft() ? true : false), 6871 &aSwRedirector ); 6872 pLines->PaintLines( &aDev ); 6873 if ( pFly->IsFlyInCntFrm() ) 6874 pFly->Paint( aOut ); 6875 pLines->PaintLines( &aDev ); 6876 /// OD 30.08.2002 #102450# - add 3rd parameter 6877 pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor, 6878 (pFlyPage->IsRightToLeft() ? true : false), 6879 &aSwRedirector ); 6880 pLines->PaintLines( &aDev ); 6881 DELETEZ( pLines ); 6882 pFlyOnlyDraw = 0; 6883 6884 pFlyMetafileOut = 0; 6885 bFlyMetafile = sal_False; 6886 ::SetOutDevAndWin( pSh, pOld, pWin, nZoom ); 6887 6888 // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted 6889 pSh->DLPostPaint2(true); 6890 6891 aMet.Stop(); 6892 aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() ); 6893 aRet = Graphic( aMet ); 6894 6895 if( bNoteURL ) 6896 { 6897 ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." ); 6898 pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap ); 6899 delete pNoteURL; 6900 pNoteURL = NULL; 6901 } 6902 pGlobalShell = pOldGlobal; 6903 } 6904 return aRet; 6905 } 6906 6907 Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* ) 6908 { 6909 Graphic aRet; 6910 SwDrawModel* pMod = getIDocumentDrawModelAccess()->GetDrawModel(); 6911 if ( pMod ) 6912 { 6913 SdrObject *pObj = FindSdrObject(); 6914 SdrView *pView = new SdrView( pMod ); 6915 SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0)); 6916 pView->MarkObj( pObj, pPgView ); 6917 aRet = pView->GetMarkedObjBitmapEx(); 6918 pView->HideSdrPage(); 6919 delete pView; 6920 } 6921 return aRet; 6922 } 6923 6924 /* vim: set noet sw=4 ts=4: */ 6925