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