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