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