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