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