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