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