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