merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / layout / paintfrm.cxx
blob7740a37618f3878024f6d40edd9d2acedd8732fb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: paintfrm.cxx,v $
10 * $Revision: 1.121.110.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <com/sun/star/text/HoriOrientation.hpp>
37 #include <hintids.hxx>
39 #ifndef _SOUND_HXX //autogen
40 #include <vcl/sound.hxx>
41 #endif
42 #include <tools/poly.hxx>
43 #define _SVSTDARR_LONGS
44 #include <svtools/svstdarr.hxx>
45 #include <svx/xoutbmp.hxx>
46 #include <sfx2/progress.hxx>
47 #include <svx/brshitem.hxx>
48 #include <svx/opaqitem.hxx>
49 #include <svx/prntitem.hxx>
50 #include <svx/boxitem.hxx>
51 #include <svx/shaditem.hxx>
52 // --> collapsing borders FME 2005-05-27 #i29550#
53 #include <svx/framelink.hxx>
54 // <--
55 #ifndef _GRAPH_HXX //autogen
56 #include <vcl/graph.hxx>
57 #endif
58 #include <svx/svdpagv.hxx>
59 #include <tgrditem.hxx>
62 #include <fmtsrnd.hxx>
63 #include <fmtclds.hxx>
64 #include <tools/shl.hxx>
65 #ifndef _COMCORE_HRC
66 #include <comcore.hrc>
67 #endif
68 #include <swmodule.hxx>
69 #include <rootfrm.hxx>
70 #include <pagefrm.hxx>
71 #include <cntfrm.hxx>
72 #include <viewsh.hxx>
73 #include <section.hxx>
74 #include <sectfrm.hxx>
75 #include <doc.hxx>
76 #include <viewimp.hxx>
77 #include <dflyobj.hxx>
78 #include <flyfrm.hxx>
79 #include <frmtool.hxx>
80 #include <viewopt.hxx>
81 #include <dview.hxx>
82 #include <dcontact.hxx>
83 #include <txtfrm.hxx>
84 #include <ftnfrm.hxx>
85 #include <tabfrm.hxx>
86 #include <rowfrm.hxx>
87 #include <cellfrm.hxx>
88 #include <notxtfrm.hxx>
89 #include <swregion.hxx>
90 #include <layact.hxx>
91 #include <pagedesc.hxx>
92 #include <ptqueue.hxx>
93 #include <noteurl.hxx>
94 #include <virtoutp.hxx>
95 #ifndef _LINEINFO_HXX
96 #include <lineinfo.hxx>
97 #endif
98 #include <dbg_lay.hxx>
99 #include <accessibilityoptions.hxx>
100 // OD 20.12.2002 #94627#
101 #ifndef _DOCSH_HXX
102 #include <docsh.hxx>
103 #endif
104 // OD 28.02.2003 #b4779636#, #107692#
105 #include <swtable.hxx>
106 // OD 02.07.2003 #108784#
107 #include <svx/svdogrp.hxx>
108 // OD 2004-05-24 #i28701#
109 #include <sortedobjs.hxx>
111 // --> FME 2004-06-08 #i12836# enhanced pdf export
112 #include <EnhancedPDFExportHelper.hxx>
113 // <--
115 #include <ndole.hxx>
116 #include <svtools/chartprettypainter.hxx>
118 #include <PostItMgr.hxx>
119 #include <tools/color.hxx>
120 #define COL_NOTES_SIDEPANE RGB_COLORDATA(230,230,230)
121 #define COL_NOTES_SIDEPANE_BORDER RGB_COLORDATA(200,200,200)
122 #define COL_NOTES_SIDEPANE_SCROLLAREA RGB_COLORDATA(230,230,220)
123 #include <vcl/svapp.hxx>
125 using namespace ::com::sun::star;
127 #define GETOBJSHELL() ((SfxObjectShell*)rSh.GetDoc()->GetDocShell())
129 //Tabellenhilfslinien an?
130 #define IS_SUBS_TABLE \
131 (pGlobalShell->GetViewOptions()->IsTable() && \
132 !pGlobalShell->GetViewOptions()->IsPagePreview()&&\
133 !pGlobalShell->GetViewOptions()->IsReadonly()&&\
134 !pGlobalShell->GetViewOptions()->IsFormView() &&\
135 SwViewOption::IsTableBoundaries())
136 //sonstige Hilfslinien an?
137 #define IS_SUBS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
138 !pGlobalShell->GetViewOptions()->IsReadonly() && \
139 !pGlobalShell->GetViewOptions()->IsFormView() &&\
140 SwViewOption::IsDocBoundaries())
141 //Hilfslinien fuer Bereiche
142 #define IS_SUBS_SECTION (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
143 !pGlobalShell->GetViewOptions()->IsReadonly()&&\
144 !pGlobalShell->GetViewOptions()->IsFormView() &&\
145 SwViewOption::IsSectionBoundaries())
146 #define IS_SUBS_FLYS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
147 !pGlobalShell->GetViewOptions()->IsReadonly()&&\
148 !pGlobalShell->GetViewOptions()->IsFormView() &&\
149 SwViewOption::IsObjectBoundaries())
151 #define SW_MAXBORDERCACHE 20
153 //Klassendeklarationen. Hier weil sie eben nur in diesem File benoetigt
154 //werden.
156 #define SUBCOL_PAGE 0x01 //Helplines of the page
157 #define SUBCOL_BREAK 0x02 //Helpline for a page or column break
158 #define SUBCOL_TAB 0x08 //Helplines inside tables
159 #define SUBCOL_FLY 0x10 //Helplines inside fly frames
160 #define SUBCOL_SECT 0x20 //Helplines inside sections
162 //----- Klassen zum Sammeln von Umrandungen und Hilfslinien ---
163 class SwLineRect : public SwRect
165 const Color *pColor;
166 const SwTabFrm *pTab;
167 BYTE nSubColor; //Hilfslinien einfaerben
168 BOOL bPainted; //schon gepaintet?
169 BYTE nLock; //Um die Linien zum Hell-Layer abzugrenzen.
170 public:
171 SwLineRect( const SwRect &rRect, const Color *pCol,
172 const SwTabFrm *pT , const BYTE nSCol );
174 const Color *GetColor() const { return pColor;}
175 const SwTabFrm *GetTab() const { return pTab; }
176 void SetPainted() { bPainted = TRUE; }
177 void Lock( BOOL bLock ) { if ( bLock )
178 ++nLock;
179 else if ( nLock )
180 --nLock;
182 BOOL IsPainted() const { return bPainted; }
183 BOOL IsLocked() const { return nLock != 0; }
184 BYTE GetSubColor() const { return nSubColor;}
186 BOOL MakeUnion( const SwRect &rRect );
189 SV_DECL_VARARR( SwLRects, SwLineRect, 100, 100 )
191 class SwLineRects : public SwLRects
193 USHORT nLastCount; //unuetze Durchlaeufe im PaintLines verhindern.
194 public:
195 SwLineRects() : nLastCount( 0 ) {}
196 void AddLineRect( const SwRect& rRect, const Color *pColor,
197 const SwTabFrm *pTab, const BYTE nSCol );
198 void ConnectEdges( OutputDevice *pOut );
199 void PaintLines ( OutputDevice *pOut );
200 void LockLines( BOOL bLock );
202 /// OD 13.08.2002 - correct type of function
203 USHORT Free() const { return nFree; }
206 class SwSubsRects : public SwLineRects
208 void RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects ); //;-)
209 public:
210 void PaintSubsidiary( OutputDevice *pOut, const SwLineRects *pRects );
212 inline void Ins( const SwRect &rRect, const BYTE nSCol );
215 //----------------- End Klassen Umrandungen ----------------------
217 static ViewShell *pGlobalShell = 0;
219 //Wenn durchsichtige FlyInCnts im PaintBackground gepainted werden so soll der
220 //Hintergrund nicht mehr retouchiert werden.
221 //static BOOL bLockFlyBackground = FALSE;
223 //Wenn vom Fly ein Metafile abgezogen wird, so soll nur der FlyInhalt und vor
224 //nur hintergrund vom FlyInhalt gepaintet werden.
225 static BOOL bFlyMetafile = FALSE;
226 static OutputDevice *pFlyMetafileOut = 0;
228 //Die Retouche fuer Durchsichtige Flys wird vom Hintergrund der Flys
229 //erledigt. Dabei darf der Fly selbst natuerlich nicht ausgespart werden.
230 //siehe PaintBackground und lcl_SubtractFlys()
231 static SwFlyFrm *pRetoucheFly = 0;
232 static SwFlyFrm *pRetoucheFly2 = 0;
234 //Groesse eines Pixel und die Haelfte davon. Wird jeweils bei Eintritt in
235 //SwRootFrm::Paint neu gesetzt.
236 static long nPixelSzW = 0, nPixelSzH = 0;
237 static long nHalfPixelSzW = 0, nHalfPixelSzH = 0;
238 static long nMinDistPixelW = 0, nMinDistPixelH = 0;
240 //Aktueller Zoomfaktor
241 static double aScaleX = 1.0;
242 static double aScaleY = 1.0;
243 static double aMinDistScale = 0.73;
244 static double aEdgeScale = 0.5;
247 //In pLines werden Umrandungen waehrend des Paint gesammelt und soweit
248 //moeglich zusammengefasst.
249 //In pSubsLines werden Hilfslinien gesammelt und zusammengefasst. Diese
250 //werden vor der Ausgabe mit pLines abgeglichen, so dass moeglichst keine
251 //Umrandungen von den Hilfslinen verdeckt werden.
252 //bTablines ist waerend des Paints einer Tabelle TRUE.
253 static SwLineRects *pLines = 0;
254 static SwSubsRects *pSubsLines = 0;
255 // OD 18.11.2002 #99672# - global variable for sub-lines of body, header, footer,
256 // section and footnote frames.
257 static SwSubsRects *pSpecSubsLines = 0;
259 static SfxProgress *pProgress = 0;
261 static SwFlyFrm *pFlyOnlyDraw = 0;
263 //Damit die Flys auch fuer den Hack richtig gepaintet werden koennen.
264 static BOOL bTableHack = FALSE;
266 //Um das teure Ermitteln der RetoucheColor zu optimieren
267 Color aGlobalRetoucheColor;
269 //Statics fuer Umrandungsalignment setzen.
270 // OD 05.05.2003 #107169# - adjustment for 'small' twip-to-pixel relations:
271 // For 'small' twip-to-pixel relations (less then 2:1)
272 // values of <nHalfPixelSzW> and <nHalfPixelSzH> are set to ZERO.
273 void SwCalcPixStatics( OutputDevice *pOut )
275 // OD 30.04.2003 #107169# - determine 'small' twip-to-pixel relation
276 sal_Bool bSmallTwipToPxRelW = sal_False;
277 sal_Bool bSmallTwipToPxRelH = sal_False;
279 Size aCheckTwipToPxRelSz( pOut->PixelToLogic( Size( 100, 100 )) );
280 if ( (aCheckTwipToPxRelSz.Width()/100.0) < 2.0 )
282 bSmallTwipToPxRelW = sal_True;
284 if ( (aCheckTwipToPxRelSz.Height()/100.0) < 2.0 )
286 bSmallTwipToPxRelH = sal_True;
290 Size aSz( pOut->PixelToLogic( Size( 1,1 )) );
292 nPixelSzW = aSz.Width();
293 if( !nPixelSzW )
294 nPixelSzW = 1;
295 nPixelSzH = aSz.Height();
296 if( !nPixelSzH )
297 nPixelSzH = 1;
299 // OD 06.05.2003 #107169# - consider 'small' twip-to-pixel relations
300 if ( !bSmallTwipToPxRelW )
302 nHalfPixelSzW = nPixelSzW / 2 + 1;
304 else
306 nHalfPixelSzW = 0;
308 // OD 06.05.2003 #107169# - consider 'small' twip-to-pixel relations
309 if ( !bSmallTwipToPxRelH )
311 nHalfPixelSzH = nPixelSzH / 2 + 1;
313 else
315 nHalfPixelSzH = 0;
318 nMinDistPixelW = nPixelSzW * 2 + 1;
319 nMinDistPixelH = nPixelSzH * 2 + 1;
321 const MapMode &rMap = pOut->GetMapMode();
322 aScaleX = rMap.GetScaleX();
323 aScaleY = rMap.GetScaleY();
326 //Zum Sichern der statics, damit das Paint (quasi) reentrant wird.
327 class SwSavePaintStatics
329 BOOL bSFlyMetafile,
330 bSPageOnly;
331 ViewShell *pSGlobalShell;
332 OutputDevice *pSFlyMetafileOut;
333 SwFlyFrm *pSRetoucheFly,
334 *pSRetoucheFly2,
335 *pSFlyOnlyDraw;
336 SwLineRects *pSLines;
337 SwSubsRects *pSSubsLines;
338 // --> OD 2005-07-04 #123196#
339 SwSubsRects* pSSpecSubsLines;
340 // <--
341 SfxProgress *pSProgress;
342 long nSPixelSzW,
343 nSPixelSzH,
344 nSHalfPixelSzW,
345 nSHalfPixelSzH,
346 nSMinDistPixelW,
347 nSMinDistPixelH;
348 Color aSGlobalRetoucheColor;
349 double aSScaleX,
350 aSScaleY;
351 public:
352 SwSavePaintStatics();
353 ~SwSavePaintStatics();
356 SwSavePaintStatics::SwSavePaintStatics() :
357 bSFlyMetafile ( bFlyMetafile ),
358 pSGlobalShell ( pGlobalShell ),
359 pSFlyMetafileOut ( pFlyMetafileOut ),
360 pSRetoucheFly ( pRetoucheFly ),
361 pSRetoucheFly2 ( pRetoucheFly2 ),
362 pSFlyOnlyDraw ( pFlyOnlyDraw ),
363 pSLines ( pLines ),
364 pSSubsLines ( pSubsLines ),
365 // --> OD 2005-07-04 #123196#
366 pSSpecSubsLines ( pSpecSubsLines ),
367 // <--
368 pSProgress ( pProgress ),
369 nSPixelSzW ( nPixelSzW ),
370 nSPixelSzH ( nPixelSzH ),
371 nSHalfPixelSzW ( nHalfPixelSzW ),
372 nSHalfPixelSzH ( nHalfPixelSzH ),
373 nSMinDistPixelW ( nMinDistPixelW ),
374 nSMinDistPixelH ( nMinDistPixelH ),
375 aSGlobalRetoucheColor( aGlobalRetoucheColor ),
376 aSScaleX ( aScaleX ),
377 aSScaleY ( aScaleY )
379 bFlyMetafile = FALSE;
380 pFlyMetafileOut = 0;
381 pRetoucheFly = 0;
382 pRetoucheFly2 = 0;
383 nPixelSzW = nPixelSzH =
384 nHalfPixelSzW = nHalfPixelSzH =
385 nMinDistPixelW = nMinDistPixelH = 0;
386 aScaleX = aScaleY = 1.0;
387 aMinDistScale = 0.73;
388 aEdgeScale = 0.5;
389 pLines = 0;
390 pSubsLines = 0;
391 // --> OD 2005-07-04 #123196#
392 pSpecSubsLines = 0L;
393 // <--
394 pProgress = 0;
397 SwSavePaintStatics::~SwSavePaintStatics()
399 pGlobalShell = pSGlobalShell;
400 bFlyMetafile = bSFlyMetafile;
401 pFlyMetafileOut = pSFlyMetafileOut;
402 pRetoucheFly = pSRetoucheFly;
403 pRetoucheFly2 = pSRetoucheFly2;
404 pFlyOnlyDraw = pSFlyOnlyDraw;
405 pLines = pSLines;
406 pSubsLines = pSSubsLines;
407 // --> OD 2005-07-04 #123196#
408 pSpecSubsLines = pSSpecSubsLines;
409 // <--
410 pProgress = pSProgress;
411 nPixelSzW = nSPixelSzW;
412 nPixelSzH = nSPixelSzH;
413 nHalfPixelSzW = nSHalfPixelSzW;
414 nHalfPixelSzH = nSHalfPixelSzH;
415 nMinDistPixelW = nSMinDistPixelW;
416 nMinDistPixelH = nSMinDistPixelH;
417 aGlobalRetoucheColor = aSGlobalRetoucheColor;
418 aScaleX = aSScaleX;
419 aScaleY = aSScaleY;
422 //----------------- Implementierungen fuer Tabellenumrandung --------------
424 SV_IMPL_VARARR( SwLRects, SwLineRect );
427 SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol,
428 const SwTabFrm *pT, const BYTE nSCol ) :
429 SwRect( rRect ),
430 pColor( pCol ),
431 pTab( pT ),
432 nSubColor( nSCol ),
433 bPainted( FALSE ),
434 nLock( 0 )
438 BOOL SwLineRect::MakeUnion( const SwRect &rRect )
440 //Es wurde bereits ausserhalb geprueft, ob die Rechtecke die gleiche
441 //Ausrichtung (horizontal bzw. vertikal), Farbe usw. besitzen.
442 if ( Height() > Width() ) //Vertikale Linie
444 if ( Left() == rRect.Left() && Width() == rRect.Width() )
446 //Zusammenfassen wenn kein Luecke zwischen den Linien ist.
447 const long nAdd = nPixelSzW + nHalfPixelSzW;
448 if ( Bottom() + nAdd >= rRect.Top() &&
449 Top() - nAdd <= rRect.Bottom() )
451 Bottom( Max( Bottom(), rRect.Bottom() ) );
452 Top ( Min( Top(), rRect.Top() ) );
453 return TRUE;
457 else
459 if ( Top() == rRect.Top() && Height() == rRect.Height() )
461 //Zusammenfassen wenn kein Luecke zwischen den Linien ist.
462 const long nAdd = nPixelSzW + nHalfPixelSzW;
463 if ( Right() + nAdd >= rRect.Left() &&
464 Left() - nAdd <= rRect.Right() )
466 Right( Max( Right(), rRect.Right() ) );
467 Left ( Min( Left(), rRect.Left() ) );
468 return TRUE;
472 return FALSE;
475 void SwLineRects::AddLineRect( const SwRect &rRect, const Color *pCol,
476 const SwTabFrm *pTab, const BYTE nSCol )
478 //Rueckwaerts durch, weil Linien die zusammengefasst werden koennen i.d.R.
479 //im gleichen Kontext gepaintet werden.
480 for ( USHORT i = Count(); i ; )
482 SwLineRect &rLRect = operator[](--i);
483 //Pruefen von Ausrichtung, Farbe, Tabelle.
484 if ( rLRect.GetTab() == pTab &&
485 !rLRect.IsPainted() && rLRect.GetSubColor() == nSCol &&
486 (rLRect.Height() > rLRect.Width()) == (rRect.Height() > rRect.Width()) &&
487 ((!rLRect.GetColor() && !pCol) ||
488 (rLRect.GetColor() && pCol && *rLRect.GetColor() == *pCol)) )
490 if ( rLRect.MakeUnion( rRect ) )
491 return;
494 Insert( SwLineRect( rRect, pCol, pTab, nSCol ), Count() );
497 void SwLineRects::ConnectEdges( OutputDevice *pOut )
499 if ( pOut->GetOutDevType() != OUTDEV_PRINTER )
501 //Fuer einen zu kleinen Zoom arbeite ich nicht.
502 if ( aScaleX < aEdgeScale || aScaleY < aEdgeScale )
503 return;
506 static const long nAdd = 20;
508 SvPtrarr aCheck( 64, 64 );
510 for ( int i = 0; i < (int)Count(); ++i )
512 SwLineRect &rL1 = operator[](USHORT(i));
513 if ( !rL1.GetTab() || rL1.IsPainted() || rL1.IsLocked() )
514 continue;
516 aCheck.Remove( 0, aCheck.Count() );
518 const BOOL bVert = rL1.Height() > rL1.Width();
519 long nL1a, nL1b, nL1c, nL1d;
521 if ( bVert )
523 nL1a = rL1.Top(); nL1b = rL1.Left();
524 nL1c = rL1.Right(); nL1d = rL1.Bottom();
526 else
528 nL1a = rL1.Left(); nL1b = rL1.Top();
529 nL1c = rL1.Bottom(); nL1d = rL1.Right();
532 //Alle moeglicherweise mit i1 zu verbindenden Linien einsammeln.
533 for ( USHORT i2 = 0; i2 < Count(); ++i2 )
535 SwLineRect &rL2 = operator[](i2);
536 if ( rL2.GetTab() != rL1.GetTab() ||
537 rL2.IsPainted() ||
538 rL2.IsLocked() ||
539 bVert == rL2.Height() > rL2.Width() )
540 continue;
542 long nL2a, nL2b, nL2c, nL2d;
543 if ( bVert )
545 nL2a = rL2.Top(); nL2b = rL2.Left();
546 nL2c = rL2.Right(); nL2d = rL2.Bottom();
548 else
550 nL2a = rL2.Left(); nL2b = rL2.Top();
551 nL2c = rL2.Bottom(); nL2d = rL2.Right();
554 if ( (nL1a - nAdd < nL2d && nL1d + nAdd > nL2a) &&
555 ((nL1b > nL2b && nL1c < nL2c) ||
556 (nL1c >= nL2c && nL1b - nAdd < nL2c) ||
557 (nL1b <= nL2b && nL1c + nAdd > nL2b)) )
559 SwLineRect *pMSC = &rL2;
560 aCheck.Insert( (void*&)pMSC, aCheck.Count() );
563 if ( aCheck.Count() < 2 )
564 continue;
566 BOOL bRemove = FALSE;
568 //Fuer jede Linie jede alle folgenden checken.
569 for ( USHORT k = 0; !bRemove && k < aCheck.Count(); ++k )
571 SwLineRect &rR1 = (SwLineRect&)*(SwLineRect*)aCheck[k];
573 for ( USHORT k2 = k+1; !bRemove && k2 < aCheck.Count(); ++k2 )
575 SwLineRect &rR2 = (SwLineRect&)*(SwLineRect*)aCheck[k2];
576 if ( bVert )
578 SwLineRect *pLA = 0;
579 SwLineRect *pLB = 0;
580 if ( rR1.Top() < rR2.Top() )
582 pLA = &rR1; pLB = &rR2;
584 else if ( rR1.Top() > rR2.Top() )
586 pLA = &rR2; pLB = &rR1;
588 //beschreiben k1 und k2 eine Doppellinie?
589 if ( pLA && pLA->Bottom() + 60 > pLB->Top() )
591 if ( rL1.Top() < pLA->Top() )
593 if ( rL1.Bottom() == pLA->Bottom() )
594 continue; //kleiner Irrtum (woher?)
596 SwRect aIns( rL1 );
597 aIns.Bottom( pLA->Bottom() );
598 if ( !rL1.IsInside( aIns ) )
599 continue;
600 const USHORT nTmpFree = Free();
601 Insert( SwLineRect( aIns, rL1.GetColor(),
602 rL1.GetTab(), SUBCOL_TAB ), Count() );
603 if ( !nTmpFree )
605 --i;
606 k = aCheck.Count();
607 break;
611 if ( rL1.Bottom() > pLB->Bottom() )
612 rL1.Top( pLB->Top() ); //i1 nach oben verlaengern
613 else
614 bRemove = TRUE; //abbrechen, i1 entfernen
617 else
619 SwLineRect *pLA = 0;
620 SwLineRect *pLB = 0;
621 if ( rR1.Left() < rR2.Left() )
623 pLA = &rR1; pLB = &rR2;
625 else if ( rR1.Left() > rR2.Left() )
627 pLA = &rR2; pLB = &rR1;
629 //Liegt eine 'doppellinie' vor?
630 if ( pLA && pLA->Right() + 60 > pLB->Left() )
632 if ( rL1.Left() < pLA->Left() )
634 if ( rL1.Right() == pLA->Right() )
635 continue; //kleiner irrtum
637 SwRect aIns( rL1 );
638 aIns.Right( pLA->Right() );
639 if ( !rL1.IsInside( aIns ) )
640 continue;
641 const USHORT nTmpFree = Free();
642 Insert( SwLineRect( aIns, rL1.GetColor(),
643 rL1.GetTab(), SUBCOL_TAB ), Count() );
644 if ( !nTmpFree )
646 --i;
647 k = aCheck.Count();
648 break;
651 if ( rL1.Right() > pLB->Right() )
652 rL1.Left( pLB->Left() );
653 else
654 bRemove = TRUE;
659 if ( bRemove )
661 Remove( static_cast<USHORT>(i), 1 );
662 --i; //keinen auslassen!
667 inline void SwSubsRects::Ins( const SwRect &rRect, const BYTE nSCol )
669 //Linien die kuerzer als die breiteste Linienbreite sind werden
670 //nicht aufgenommen.
671 if ( rRect.Height() > DEF_LINE_WIDTH_4 || rRect.Width() > DEF_LINE_WIDTH_4 )
672 Insert( SwLineRect( rRect, 0, 0, nSCol ), Count());
675 void SwSubsRects::RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects )
677 //Alle Hilfslinien, die sich mit irgendwelchen Umrandungen decken werden
678 //entfernt bzw. zerstueckelt..
679 for ( USHORT i = 0; i < Count(); ++i )
681 // OD 18.11.2002 #99672# - get a copy instead of a reference, because
682 // an <insert> may destroy the object due to a necessary array resize.
683 const SwLineRect aSubsLineRect = SwLineRect( operator[](i) );
685 // OD 19.12.2002 #106318# - add condition <aSubsLineRect.IsLocked()>
686 // in order to consider only border lines, which are *not* locked.
687 if ( aSubsLineRect.IsPainted() ||
688 aSubsLineRect.IsLocked() )
689 continue;
691 const bool bVerticalSubs = aSubsLineRect.Height() > aSubsLineRect.Width();
692 SwRect aSubsRect( aSubsLineRect );
693 if ( bVerticalSubs )
695 aSubsRect.Left ( aSubsRect.Left() - (nPixelSzW+nHalfPixelSzW) );
696 aSubsRect.Right ( aSubsRect.Right() + (nPixelSzW+nHalfPixelSzW) );
698 else
700 aSubsRect.Top ( aSubsRect.Top() - (nPixelSzH+nHalfPixelSzH) );
701 aSubsRect.Bottom( aSubsRect.Bottom() + (nPixelSzH+nHalfPixelSzH) );
703 for ( USHORT k = 0; k < rRects.Count(); ++k )
705 SwLineRect &rLine = rRects[k];
707 // OD 20.12.2002 #106318# - do *not* consider painted or locked
708 // border lines.
709 // OD 20.01.2003 #i1837# - locked border lines have to be considered.
710 if ( rLine.IsLocked () )
711 continue;
713 if ( !bVerticalSubs == rLine.Height() > rLine.Width() ) //gleiche Ausrichtung?
714 continue;
716 if ( aSubsRect.IsOver( rLine ) )
718 if ( bVerticalSubs ) //Vertikal?
720 if ( aSubsRect.Left() <= rLine.Right() &&
721 aSubsRect.Right() >= rLine.Left() )
723 long nTmp = rLine.Top()-(nPixelSzH+1);
724 if ( aSubsLineRect.Top() < nTmp )
726 SwRect aNewSubsRect( aSubsLineRect );
727 aNewSubsRect.Bottom( nTmp );
728 Insert( SwLineRect( aNewSubsRect, 0, 0,
729 aSubsLineRect.GetSubColor() ), Count());
731 nTmp = rLine.Bottom()+nPixelSzH+1;
732 if ( aSubsLineRect.Bottom() > nTmp )
734 SwRect aNewSubsRect( aSubsLineRect );
735 aNewSubsRect.Top( nTmp );
736 Insert( SwLineRect( aNewSubsRect, 0, 0,
737 aSubsLineRect.GetSubColor() ), Count());
739 Remove( i, 1 );
740 --i;
741 break;
744 else //Horizontal
746 if ( aSubsRect.Top() <= rLine.Bottom() &&
747 aSubsRect.Bottom() >= rLine.Top() )
749 long nTmp = rLine.Left()-(nPixelSzW+1);
750 if ( aSubsLineRect.Left() < nTmp )
752 SwRect aNewSubsRect( aSubsLineRect );
753 aNewSubsRect.Right( nTmp );
754 Insert( SwLineRect( aNewSubsRect, 0, 0,
755 aSubsLineRect.GetSubColor() ), Count());
757 nTmp = rLine.Right()+nPixelSzW+1;
758 if ( aSubsLineRect.Right() > nTmp )
760 SwRect aNewSubsRect( aSubsLineRect );
761 aNewSubsRect.Left( nTmp );
762 Insert( SwLineRect( aNewSubsRect, 0, 0,
763 aSubsLineRect.GetSubColor() ), Count());
765 Remove( i, 1 );
766 --i;
767 break;
775 void SwLineRects::LockLines( BOOL bLock )
777 for ( USHORT i = 0; i < Count(); ++i )
778 operator[](i).Lock( bLock );
781 void SwLineRects::PaintLines( OutputDevice *pOut )
783 //Painten der Umrandungen. Leider muessen wir zweimal durch.
784 //Einmal fuer die innenliegenden und einmal fuer die Aussenkanten
785 //der Tabellen.
786 if ( Count() != nLastCount )
788 // --> FME 2004-06-24 #i16816# tagged pdf support
789 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
790 // <--
792 // OD 2004-04-23 #116347#
793 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
794 pOut->SetLineColor();
795 ConnectEdges( pOut );
796 const Color *pLast = 0;
798 BOOL bPaint2nd = FALSE;
799 USHORT nMinCount = Count();
800 USHORT i;
802 for ( i = 0; i < Count(); ++i )
804 SwLineRect &rLRect = operator[](i);
806 if ( rLRect.IsPainted() )
807 continue;
809 if ( rLRect.IsLocked() )
811 nMinCount = Min( nMinCount, i );
812 continue;
815 //Jetzt malen oder erst in der zweiten Runde?
816 BOOL bPaint = TRUE;
817 if ( rLRect.GetTab() )
819 if ( rLRect.Height() > rLRect.Width() )
821 //Senkrechte Kante, ueberlappt sie mit der TabellenKante?
822 SwTwips nLLeft = rLRect.Left() - 30,
823 nLRight = rLRect.Right() + 30,
824 nTLeft = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Left(),
825 nTRight = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Right();
826 if ( (nTLeft >= nLLeft && nTLeft <= nLRight) ||
827 (nTRight>= nLLeft && nTRight<= nLRight) )
828 bPaint = FALSE;
830 else
831 { //Waagerechte Kante, ueberlappt sie mit der Tabellenkante?
832 SwTwips nLTop = rLRect.Top() - 30,
833 nLBottom = rLRect.Bottom() + 30,
834 nTTop = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Top(),
835 nTBottom = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Bottom();
836 if ( (nTTop >= nLTop && nTTop <= nLBottom) ||
837 (nTBottom >= nLTop && nTBottom <= nLBottom) )
838 bPaint = FALSE;
841 if ( bPaint )
843 if ( !pLast || *pLast != *rLRect.GetColor() )
845 pLast = rLRect.GetColor();
847 ULONG nOldDrawMode = pOut->GetDrawMode();
848 if( pGlobalShell->GetWin() &&
849 Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
850 pOut->SetDrawMode( 0 );
852 pOut->SetFillColor( *pLast );
853 pOut->SetDrawMode( nOldDrawMode );
855 if( !rLRect.IsEmpty() )
856 pOut->DrawRect( rLRect.SVRect() );
857 rLRect.SetPainted();
859 else
860 bPaint2nd = TRUE;
862 if ( bPaint2nd )
863 for ( i = 0; i < Count(); ++i )
865 SwLineRect &rLRect = operator[](i);
866 if ( rLRect.IsPainted() )
867 continue;
869 if ( rLRect.IsLocked() )
871 nMinCount = Min( nMinCount, i );
872 continue;
875 if ( !pLast || *pLast != *rLRect.GetColor() )
877 pLast = rLRect.GetColor();
879 ULONG nOldDrawMode = pOut->GetDrawMode();
880 if( pGlobalShell->GetWin() &&
881 Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
883 pOut->SetDrawMode( 0 );
886 pOut->SetFillColor( *pLast );
887 pOut->SetDrawMode( nOldDrawMode );
889 if( !rLRect.IsEmpty() )
890 pOut->DrawRect( rLRect.SVRect() );
891 rLRect.SetPainted();
893 nLastCount = nMinCount;
894 pOut->Pop();
898 void SwSubsRects::PaintSubsidiary( OutputDevice *pOut,
899 const SwLineRects *pRects )
901 if ( Count() )
903 // --> FME 2004-06-24 #i16816# tagged pdf support
904 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
905 // <--
907 //Alle Hilfslinien, die sich fast decken entfernen (Tabellen)
908 for ( USHORT i = 0; i < Count(); ++i )
910 SwLineRect &rLi = operator[](i);
911 const bool bVerticalSubs = rLi.Height() > rLi.Width();
913 for ( USHORT k = i+1; k < Count(); ++k )
915 SwLineRect &rLk = operator[](k);
916 if ( rLi.SSize() == rLk.SSize() )
918 if ( bVerticalSubs == rLk.Height() > rLk.Width() )
920 if ( bVerticalSubs )
922 long nLi = rLi.Right();
923 long nLk = rLk.Right();
924 if ( rLi.Top() == rLk.Top() &&
925 ((nLi < rLk.Left() && nLi+21 > rLk.Left()) ||
926 (nLk < rLi.Left() && nLk+21 > rLi.Left())))
928 Remove( k, 1 );
929 //Nicht mit der inneren Schleife weiter, weil
930 //das Array schrumpfen koennte!
931 --i; k = Count();
934 else
936 long nLi = rLi.Bottom();
937 long nLk = rLk.Bottom();
938 if ( rLi.Left() == rLk.Left() &&
939 ((nLi < rLk.Top() && nLi+21 > rLk.Top()) ||
940 (nLk < rLi.Top() && nLk+21 > rLi.Top())))
942 Remove( k, 1 );
943 --i; k = Count();
952 if ( pRects && pRects->Count() )
953 RemoveSuperfluousSubsidiaryLines( *pRects );
955 if ( Count() )
957 // OD 2004-04-23 #116347#
958 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
959 pOut->SetLineColor();
961 // OD 14.01.2003 #106660# - reset draw mode in high contrast
962 // mode in order to get fill color set at output device.
963 // Recover draw mode after draw of lines.
964 // Necessary for the subsidiary lines painted by the fly frames.
965 ULONG nOldDrawMode = pOut->GetDrawMode();
966 if( pGlobalShell->GetWin() &&
967 Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
969 pOut->SetDrawMode( 0 );
972 for ( USHORT i = 0; i < Count(); ++i )
974 SwLineRect &rLRect = operator[](i);
975 // OD 19.12.2002 #106318# - add condition <!rLRect.IsLocked()>
976 // to prevent paint of locked subsidiary lines.
977 if ( !rLRect.IsPainted() &&
978 !rLRect.IsLocked() )
980 const Color *pCol = 0;
981 switch ( rLRect.GetSubColor() )
983 case SUBCOL_PAGE: pCol = &SwViewOption::GetDocBoundariesColor(); break;
984 case SUBCOL_FLY: pCol = &SwViewOption::GetObjectBoundariesColor(); break;
985 case SUBCOL_TAB: pCol = &SwViewOption::GetTableBoundariesColor(); break;
986 case SUBCOL_SECT: pCol = &SwViewOption::GetSectionBoundColor(); break;
987 case SUBCOL_BREAK: pCol = &SwViewOption::GetPageBreakColor(); break;
990 if ( pOut->GetFillColor() != *pCol )
991 pOut->SetFillColor( *pCol );
992 pOut->DrawRect( rLRect.SVRect() );
994 rLRect.SetPainted();
998 // OD 14.01.2003 #106660# - recovering draw mode
999 pOut->SetDrawMode( nOldDrawMode );
1001 pOut->Pop();
1006 //-------------------------------------------------------------------------
1007 //Diverse Functions die in diesem File so verwendet werden.
1009 // OD 20.02.2003 - Note: function <SwAlignRect(..)> also used outside this file.
1010 // OD 29.04.2003 #107169# - correction: adjust rectangle on pixel level in order
1011 // to assure, that the border 'leaves its original pixel', if it has to.
1012 // No prior adjustments for odd relation between pixel and twip.
1013 void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh )
1015 if( !rRect.HasArea() )
1016 return;
1018 // OD 03.09.2002 #102450#
1019 // Assure that view shell (parameter <pSh>) exists, if the output device
1020 // is taken from this view shell --> no output device, no alignment.
1021 // Output device taken from view shell <pSh>, if <bFlyMetafile> not set.
1022 if ( !bFlyMetafile && !pSh )
1024 return;
1027 const OutputDevice *pOut = bFlyMetafile ?
1028 pFlyMetafileOut : pSh->GetOut();
1030 // OD 28.04.2003 #107169# - hold original rectangle in pixel
1031 const Rectangle aOrgPxRect = pOut->LogicToPixel( rRect.SVRect() );
1032 // OD 29.04.2003 #107169# - determine pixel-center rectangle in twip
1033 const SwRect aPxCenterRect( pOut->PixelToLogic( aOrgPxRect ) );
1035 // OD 06.05.2003 #107169# - perform adjustments on pixel level.
1036 SwRect aAlignedPxRect( aOrgPxRect );
1037 if ( rRect.Top() > aPxCenterRect.Top() )
1039 // 'leave pixel overlapping on top'
1040 aAlignedPxRect.Top( aAlignedPxRect.Top() + 1 );
1043 if ( rRect.Bottom() < aPxCenterRect.Bottom() )
1045 // 'leave pixel overlapping on bottom'
1046 aAlignedPxRect.Bottom( aAlignedPxRect.Bottom() - 1 );
1049 if ( rRect.Left() > aPxCenterRect.Left() )
1051 // 'leave pixel overlapping on left'
1052 aAlignedPxRect.Left( aAlignedPxRect.Left() + 1 );
1055 if ( rRect.Right() < aPxCenterRect.Right() )
1057 // 'leave pixel overlapping on right'
1058 aAlignedPxRect.Right( aAlignedPxRect.Right() - 1 );
1061 // OD 11.10.2002 #103636# - consider negative width/height
1062 // check, if aligned SwRect has negative width/height.
1063 // If Yes, adjust it to width/height = 0 twip.
1064 // NOTE: A SwRect with negative width/height can occur, if the width/height
1065 // of the given SwRect in twip was less than a pixel in twip and that
1066 // the alignment calculates that the aligned SwRect should not contain
1067 // the pixels the width/height is on.
1068 if ( aAlignedPxRect.Width() < 0 )
1070 aAlignedPxRect.Width(0);
1072 if ( aAlignedPxRect.Height() < 0 )
1074 aAlignedPxRect.Height(0);
1076 // OD 30.04.2003 #107169# - consider zero width/height
1077 // For converting a rectangle from pixel to logic it needs a width/height.
1078 // Thus, set width/height to one, if it's zero and correct this on the twip
1079 // level after the conversion.
1080 sal_Bool bZeroWidth = sal_False;
1081 if ( aAlignedPxRect.Width() == 0 )
1083 aAlignedPxRect.Width(1);
1084 bZeroWidth = sal_True;
1086 sal_Bool bZeroHeight = sal_False;
1087 if ( aAlignedPxRect.Height() == 0 )
1089 aAlignedPxRect.Height(1);
1090 bZeroHeight = sal_True;
1093 rRect = pOut->PixelToLogic( aAlignedPxRect.SVRect() );
1095 // OD 30.04.2003 #107169# - consider zero width/height and adjust calculated
1096 // aligned twip rectangle.
1097 // OD 19.05.2003 #109667# - reset width/height to zero; previous negative
1098 // width/height haven't to be considered.
1099 if ( bZeroWidth )
1101 rRect.Width(0);
1103 if ( bZeroHeight )
1105 rRect.Height(0);
1109 /** OD 19.05.2003 #109667# - helper method for twip adjustments on pixel base
1111 method compares the x- or y-pixel position of two twip-point. If the x-/y-pixel
1112 positions are the same, the x-/y-pixel position of the second twip point is
1113 adjusted by a given amount of pixels.
1115 @author OD
1117 void lcl_CompPxPosAndAdjustPos( const OutputDevice& _rOut,
1118 const Point& _rRefPt,
1119 Point& _rCompPt,
1120 const sal_Bool _bChkXPos,
1121 const sal_Int8 _nPxAdjustment )
1123 const Point aRefPxPt = _rOut.LogicToPixel( _rRefPt );
1124 Point aCompPxPt = _rOut.LogicToPixel( _rCompPt );
1126 if ( _bChkXPos )
1128 if ( aCompPxPt.X() == aRefPxPt.X() )
1130 aCompPxPt.X() += _nPxAdjustment ;
1131 const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
1132 _rCompPt.X() = aAdjustedCompPt.X();
1135 else
1137 if ( aCompPxPt.Y() == aRefPxPt.Y() )
1139 aCompPxPt.Y() += _nPxAdjustment ;
1140 const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
1141 _rCompPt.Y() = aAdjustedCompPt.Y();
1146 /** OD 25.09.2002 #99739# - method to pixel-align rectangle for drawing graphic object
1148 Because for drawing a graphic left-top-corner and size coordinations are
1149 used, these coordinations have to be determined on pixel level.
1150 Thus, convert rectangle to pixel and then convert left-top-corner and
1151 size of pixel rectangle back to logic.
1152 This calculation is necessary, because there exists a different between
1153 the convert from logic to pixel of a normal rectangle with its left-top-
1154 and right-bottom-corner and the same convert of the same rectangle
1155 with left-top-corner and size.
1156 Call this method before each <GraphicObject.Draw(...)>
1158 @author OD
1160 void SwAlignGrfRect( SwRect *pGrfRect, const OutputDevice &rOut )
1162 Rectangle aPxRect = rOut.LogicToPixel( pGrfRect->SVRect() );
1163 pGrfRect->Pos( rOut.PixelToLogic( aPxRect.TopLeft() ) );
1164 pGrfRect->SSize( rOut.PixelToLogic( aPxRect.GetSize() ) );
1167 long MA_FASTCALL lcl_AlignWidth( const long nWidth )
1169 if ( nWidth )
1171 const long nW = nWidth % nPixelSzW;
1173 if ( !nW || nW > nHalfPixelSzW )
1174 return Max(1L, nWidth - nHalfPixelSzW);
1176 return nWidth;
1179 long MA_FASTCALL lcl_AlignHeight( const long nHeight )
1181 if ( nHeight )
1183 const long nH = nHeight % nPixelSzH;
1185 if ( !nH || nH > nHalfPixelSzH )
1186 return Max(1L, nHeight - nHalfPixelSzH);
1188 return nHeight;
1191 long MA_FASTCALL lcl_MinHeightDist( const long nDist )
1193 if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale )
1194 return nDist;
1195 return ::lcl_AlignHeight( Max( nDist, nMinDistPixelH ));
1198 long MA_FASTCALL lcl_MinWidthDist( const long nDist )
1200 if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale )
1201 return nDist;
1202 return ::lcl_AlignWidth( Max( nDist, nMinDistPixelW ));
1206 //Ermittelt PrtArea plus Umrandung plus Schatten.
1207 void MA_FASTCALL lcl_CalcBorderRect( SwRect &rRect, const SwFrm *pFrm,
1208 const SwBorderAttrs &rAttrs,
1209 const BOOL bShadow )
1211 // OD 23.01.2003 #106386# - special handling for cell frames.
1212 // The printing area of a cell frame is completely enclosed in the frame area
1213 // and a cell frame has no shadow. Thus, for cell frames the calculated
1214 // area equals the frame area.
1215 // Notes: Borders of cell frames in R2L text direction will switch its side
1216 // - left border is painted on the right; right border on the left.
1217 // See <lcl_PaintLeftLine> and <lcl_PaintRightLine>.
1218 if( pFrm->IsSctFrm() )
1220 rRect = pFrm->Prt();
1221 rRect.Pos() += pFrm->Frm().Pos();
1223 else if ( pFrm->IsCellFrm() )
1224 rRect = pFrm->Frm();
1225 else
1227 rRect = pFrm->Prt();
1228 rRect.Pos() += pFrm->Frm().Pos();
1230 if ( rAttrs.IsLine() || rAttrs.IsBorderDist() ||
1231 (bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE) )
1233 SwRectFn fnRect = pFrm->IsVertical() ? fnRectVert : fnRectHori;
1234 const SvxBoxItem &rBox = rAttrs.GetBox();
1235 const BOOL bTop = 0 != (pFrm->*fnRect->fnGetTopMargin)();
1236 if ( bTop )
1238 SwTwips nDiff = rBox.GetTop() ?
1239 rBox.CalcLineSpace( BOX_LINE_TOP ) :
1240 ( rAttrs.IsBorderDist() ?
1241 // OD 23.01.2003 #106386# - increase of distance by
1242 // one twip is incorrect.
1243 rBox.GetDistance( BOX_LINE_TOP ) : 0 );
1244 if( nDiff )
1245 (rRect.*fnRect->fnSubTop)( nDiff );
1248 const BOOL bBottom = 0 != (pFrm->*fnRect->fnGetBottomMargin)();
1249 if ( bBottom )
1251 SwTwips nDiff = 0;
1252 // --> collapsing borders FME 2005-05-27 #i29550#
1253 if ( pFrm->IsTabFrm() &&
1254 ((SwTabFrm*)pFrm)->IsCollapsingBorders() )
1256 // For collapsing borders, we have to add the height of
1257 // the height of the last line
1258 nDiff = ((SwTabFrm*)pFrm)->GetBottomLineSize();
1260 // <-- collapsing
1261 else
1263 nDiff = rBox.GetBottom() ?
1264 rBox.CalcLineSpace( BOX_LINE_BOTTOM ) :
1265 ( rAttrs.IsBorderDist() ?
1266 // OD 23.01.2003 #106386# - increase of distance by
1267 // one twip is incorrect.
1268 rBox.GetDistance( BOX_LINE_BOTTOM ) : 0 );
1270 if( nDiff )
1271 (rRect.*fnRect->fnAddBottom)( nDiff );
1274 if ( rBox.GetLeft() )
1275 (rRect.*fnRect->fnSubLeft)( rBox.CalcLineSpace( BOX_LINE_LEFT ) );
1276 else if ( rAttrs.IsBorderDist() )
1277 // OD 23.01.2003 #106386# - increase of distance by one twip is incorrect.
1278 (rRect.*fnRect->fnSubLeft)( rBox.GetDistance( BOX_LINE_LEFT ) );
1280 if ( rBox.GetRight() )
1281 (rRect.*fnRect->fnAddRight)( rBox.CalcLineSpace( BOX_LINE_RIGHT ) );
1282 else if ( rAttrs.IsBorderDist() )
1283 // OD 23.01.2003 #106386# - increase of distance by one twip is incorrect.
1284 (rRect.*fnRect->fnAddRight)( rBox.GetDistance( BOX_LINE_RIGHT ) );
1286 if ( bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
1288 const SvxShadowItem &rShadow = rAttrs.GetShadow();
1289 if ( bTop )
1290 (rRect.*fnRect->fnSubTop)(rShadow.CalcShadowSpace(SHADOW_TOP));
1291 (rRect.*fnRect->fnSubLeft)(rShadow.CalcShadowSpace(SHADOW_LEFT));
1292 if ( bBottom )
1293 (rRect.*fnRect->fnAddBottom)
1294 (rShadow.CalcShadowSpace( SHADOW_BOTTOM ));
1295 (rRect.*fnRect->fnAddRight)(rShadow.CalcShadowSpace(SHADOW_RIGHT));
1300 ::SwAlignRect( rRect, pGlobalShell );
1303 void MA_FASTCALL lcl_ExtendLeftAndRight( SwRect& _rRect,
1304 const SwFrm& _rFrm,
1305 const SwBorderAttrs& _rAttrs,
1306 const SwRectFn& _rRectFn )
1308 // OD 21.05.2003 #108789# - extend left/right border/shadow rectangle to
1309 // bottom of previous frame/to top of next frame, if border/shadow is joined
1310 // with previous/next frame.
1311 if ( _rAttrs.JoinedWithPrev( _rFrm ) )
1313 const SwFrm* pPrevFrm = _rFrm.GetPrev();
1314 (_rRect.*_rRectFn->fnSetTop)( (pPrevFrm->*_rRectFn->fnGetPrtBottom)() );
1316 if ( _rAttrs.JoinedWithNext( _rFrm ) )
1318 const SwFrm* pNextFrm = _rFrm.GetNext();
1319 (_rRect.*_rRectFn->fnSetBottom)( (pNextFrm->*_rRectFn->fnGetPrtTop)() );
1324 void MA_FASTCALL lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage,
1325 const SwRect &rRect, SwRegionRects &rRegion )
1327 const SwSortedObjs& rObjs = *pPage->GetSortedObjs();
1328 const SwFlyFrm* pSelfFly = pFrm->IsInFly() ? pFrm->FindFlyFrm() : pRetoucheFly2;
1329 if ( !pRetoucheFly )
1330 pRetoucheFly = pRetoucheFly2;
1332 for ( USHORT j = 0; (j < rObjs.Count()) && rRegion.Count(); ++j )
1334 const SwAnchoredObject* pAnchoredObj = rObjs[j];
1335 const SdrObject* pSdrObj = pAnchoredObj->GetDrawObj();
1337 // OD 2004-01-15 #110582# - do not consider invisible objects
1338 if ( !pPage->GetFmt()->GetDoc()->IsVisibleLayerId( pSdrObj->GetLayer() ) )
1339 continue;
1341 if ( !pAnchoredObj->ISA(SwFlyFrm) )
1342 continue;
1344 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
1346 if ( pSelfFly == pFly || pRetoucheFly == pFly || !rRect.IsOver( pFly->Frm() ) )
1347 continue;
1349 if ( !pFly->GetFmt()->GetPrint().GetValue() &&
1350 (OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() ||
1351 pGlobalShell->IsPreView()))
1352 continue;
1354 const BOOL bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly ) ?
1355 TRUE : FALSE;
1357 //Bei zeichengebundenem Fly nur diejenigen betrachten, in denen er
1358 //nicht selbst verankert ist.
1359 //#33429# Warum nur bei zeichengebundenen? Es macht doch nie Sinn
1360 //Rahmen abzuziehen in denen er selbst verankert ist oder?
1361 if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
1362 continue;
1364 //#57194# Und warum gilt das nicht analog fuer den RetoucheFly?
1365 if ( pRetoucheFly && pRetoucheFly->IsLowerOf( pFly ) )
1366 continue;
1369 #ifndef PRODUCT
1370 //Flys, die innerhalb des eigenen verankert sind, muessen eine
1371 //groessere OrdNum haben oder Zeichengebunden sein.
1372 if ( pSelfFly && bLowerOfSelf )
1374 ASSERT( pFly->IsFlyInCntFrm() ||
1375 pSdrObj->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(),
1376 "Fly with wrong z-Order" );
1378 #endif
1380 BOOL bStopOnHell = TRUE;
1381 if ( pSelfFly )
1383 const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
1384 if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
1386 if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
1387 //Im gleichen Layer werden nur obenliegende beachtet.
1388 continue;
1390 else
1392 if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
1393 //Aus anderem Layer interessieren uns nur nicht transparente
1394 //oder innenliegende
1395 continue;
1396 bStopOnHell = FALSE;
1399 if ( pRetoucheFly )
1401 const SdrObject *pTmp = pRetoucheFly->GetVirtDrawObj();
1402 if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
1404 if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
1405 //Im gleichen Layer werden nur obenliegende beachtet.
1406 continue;
1408 else
1410 if ( !pFly->IsLowerOf( pRetoucheFly ) && !pFly->GetFmt()->GetOpaque().GetValue() )
1411 //Aus anderem Layer interessieren uns nur nicht transparente
1412 //oder innenliegende
1413 continue;
1414 bStopOnHell = FALSE;
1418 //Wenn der Inhalt des Fly Transparent ist, wird er nicht abgezogen, es sei denn
1419 //er steht im Hell-Layer (#31941#)
1420 const IDocumentDrawModelAccess* pIDDMA = pFly->GetFmt()->getIDocumentDrawModelAccess();
1421 BOOL bHell = pSdrObj->GetLayer() == pIDDMA->GetHellId();
1422 if ( (bStopOnHell && bHell) ||
1423 /// OD 05.08.2002 - change internal order of condition
1424 /// first check "!bHell", then "..->Lower()" and "..->IsNoTxtFrm()"
1425 /// have not to be performed, if frame is in "Hell"
1426 ( !bHell && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() &&
1427 ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
1428 ((SwNoTxtFrm*)pFly->Lower())->HasAnimation() ||
1429 pFly->GetFmt()->GetSurround().IsContour()
1433 continue;
1435 // OD 08.10.2002 #103898#
1436 // Own if-statements for transparent background/shadow of fly frames
1437 // (#99657#) in order to handle special conditions.
1438 if ( pFly->IsBackgroundTransparent() )
1440 // Background <pFly> is transparent drawn. Thus normally, its region
1441 // have not to be substracted from given region.
1442 // But, if method is called for a fly frame and
1443 // <pFly> is a direct lower of this fly frame and
1444 // <pFly> inherites its transparent background brush from its parent,
1445 // then <pFly> frame area have to be subtracted from given region.
1446 // NOTE: Because in Status Quo transparent backgrounds can only be
1447 // assigned to fly frames, the handle of this special case
1448 // avoids drawing of transparent areas more than once, if
1449 // a fly frame inherites a transparent background from its
1450 // parent fly frame.
1451 if ( pFrm->IsFlyFrm() &&
1452 (pFly->GetAnchorFrm()->FindFlyFrm() == pFrm) &&
1453 static_cast<const SwFlyFrmFmt*>(pFly->GetFmt())->IsBackgroundBrushInherited()
1456 SwRect aRect;
1457 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
1458 const SwBorderAttrs &rAttrs = *aAccess.Get();
1459 ::lcl_CalcBorderRect( aRect, pFly, rAttrs, TRUE );
1460 rRegion -= aRect;
1461 continue;
1463 else
1465 continue;
1468 if ( pFly->IsShadowTransparent() )
1470 continue;
1473 if ( bHell && pFly->GetAnchorFrm()->IsInFly() )
1475 //Damit die Umrandung nicht vom Hintergrund des anderen Flys
1476 //zerlegt wird.
1477 SwRect aRect;
1478 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
1479 const SwBorderAttrs &rAttrs = *aAccess.Get();
1480 ::lcl_CalcBorderRect( aRect, pFly, rAttrs, TRUE );
1481 rRegion -= aRect;
1483 else
1485 SwRect aRect( pFly->Prt() );
1486 aRect += pFly->Frm().Pos();
1487 rRegion -= aRect;
1490 if ( pRetoucheFly == pRetoucheFly2 )
1491 pRetoucheFly = 0;
1494 // --> OD 2008-05-16 #i84659# - no longer needed
1495 //inline BOOL IsShortCut( const SwRect &rRect, const SwRect &rFrmRect )
1497 // //Wenn der Frm vollstaendig rechts neben bzw. unter dem
1498 // //Rect sitzt ist's genug mit Painten.
1499 // return rFrmRect.Top() > rRect.Bottom();
1500 // // PAGES01 || (rFrmRect.Left() > rRect.Right()) );
1502 // <--
1504 //---------------- Ausgabe fuer das BrushItem ----------------
1506 /** lcl_DrawGraphicBackgrd - local help method to draw a background for a graphic
1508 OD 17.10.2002 #103876#
1509 Under certain circumstances we have to draw a background for a graphic.
1510 This method takes care of the conditions and draws the background with the
1511 corresponding color.
1512 Method introduced for bug fix #103876# in order to optimize drawing tiled
1513 background graphics. Previously, this code was integrated in method
1514 <lcl_DrawGraphic>.
1515 Method implemented as a inline, checking the conditions and calling method
1516 method <lcl_implDrawGraphicBackgrd(..)> for the intrinsic drawing.
1518 @author OD
1520 @param _rBackgrdBrush
1521 background brush contain the color the background has to be drawn.
1523 @param _pOut
1524 output device the background has to be drawn in.
1526 @param _rPaintRect
1527 paint retangle in the output device, which has to be drawn with the background.
1528 rectangle have to be aligned by method ::SwAlignRect
1530 @param _rGraphicObj
1531 graphic object, for which the background has to be drawn. Used for checking
1532 the transparency of its bitmap, its type and if the graphic is drawn transparent
1534 @param _bNumberingGraphic
1535 boolean indicating that graphic is used as a numbering.
1537 @param _bBackgrdAlreadyDrawn
1538 boolean (optional; default: false) indicating, if the background is already drawn.
1540 void lcl_implDrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush,
1541 OutputDevice* _pOut,
1542 const SwRect& _rAlignedPaintRect,
1543 const GraphicObject& _rGraphicObj )
1545 /// determine color of background
1546 /// If color of background brush is not "no fill"/"auto fill" or
1547 /// <bFlyMetafile> is set, use color of background brush, otherwise
1548 /// use global retouche color.
1549 const Color aColor( ( (_rBackgrdBrush.GetColor() != COL_TRANSPARENT) || bFlyMetafile )
1550 ? _rBackgrdBrush.GetColor()
1551 : aGlobalRetoucheColor );
1553 /// determine, if background color have to be drawn transparent
1554 /// and calculate transparency percent value
1555 sal_Int8 nTransparencyPercent = 0;
1556 bool bDrawTransparent = false;
1557 if ( aColor.GetTransparency() != 0 )
1558 /// background color is transparent --> draw transparent.
1560 bDrawTransparent = true;
1561 nTransparencyPercent = (aColor.GetTransparency()*100 + 0x7F)/0xFF;
1563 else if ( (_rGraphicObj.GetAttr().GetTransparency() != 0) &&
1564 (_rBackgrdBrush.GetColor() == COL_TRANSPARENT) )
1565 /// graphic is drawn transparent and background color is
1566 /// "no fill"/"auto fill" --> draw transparent
1568 bDrawTransparent = true;
1569 nTransparencyPercent = (_rGraphicObj.GetAttr().GetTransparency()*100 + 0x7F)/0xFF;
1572 if ( bDrawTransparent )
1574 /// draw background transparent
1575 if( _pOut->GetFillColor() != aColor.GetRGBColor() )
1576 _pOut->SetFillColor( aColor.GetRGBColor() );
1577 PolyPolygon aPoly( _rAlignedPaintRect.SVRect() );
1578 _pOut->DrawTransparent( aPoly, nTransparencyPercent );
1580 else
1582 /// draw background opaque
1583 if ( _pOut->GetFillColor() != aColor )
1584 _pOut->SetFillColor( aColor );
1585 _pOut->DrawRect( _rAlignedPaintRect.SVRect() );
1589 inline void lcl_DrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush,
1590 OutputDevice* _pOut,
1591 const SwRect& _rAlignedPaintRect,
1592 const GraphicObject& _rGraphicObj,
1593 bool _bNumberingGraphic,
1594 bool _bBackgrdAlreadyDrawn = false )
1596 /// draw background with background color, if
1597 /// (1) graphic is not used as a numbering AND
1598 /// (2) background is not already drawn AND
1599 /// (3) intrinsic graphic is transparent OR intrinsic graphic doesn't exists
1600 if ( !_bNumberingGraphic &&
1601 !_bBackgrdAlreadyDrawn &&
1602 ( _rGraphicObj.IsTransparent() || _rGraphicObj.GetType() == GRAPHIC_NONE )
1605 lcl_implDrawGraphicBackgrd( _rBackgrdBrush, _pOut, _rAlignedPaintRect, _rGraphicObj );
1609 /// OD 06.08.2002 #99657# - Note: the transparency of the background graphic
1610 /// is saved in SvxBrushItem.GetGraphicObject(<shell>).GetAttr().Set/GetTransparency()
1611 /// and is considered in the drawing of the graphic.
1612 /// Thus, to provide transparent background graphic for text frames nothing
1613 /// has to be coded.
1614 /// OD 25.09.2002 #99739# - use align rectangle for drawing graphic
1615 /// OD 25.09.2002 #99739# - pixel-align coordinations for drawing graphic.
1616 /// OD 17.10.2002 #103876# - outsource code for drawing background of the graphic
1617 /// with a background color in method <lcl_DrawGraphicBackgrd>
1618 /// Also, change type of <bGrfNum> and <bClip> from <BOOL> to <bool>.
1619 void lcl_DrawGraphic( const SvxBrushItem& rBrush, OutputDevice *pOut,
1620 ViewShell &rSh, const SwRect &rGrf, const SwRect &rOut,
1621 bool bClip, bool bGrfNum,
1622 bool bBackgrdAlreadyDrawn = false )
1623 /// OD 02.09.2002 #99657#
1624 /// add parameter <bBackgrdAlreadyDrawn> to indicate
1625 /// that the background is already drawn.
1627 /// OD 25.09.2002 #99739# - calculate align rectangle from parameter <rGrf>
1628 /// and use aligned rectangle <aAlignedGrfRect> in the following code
1629 SwRect aAlignedGrfRect = rGrf;
1630 ::SwAlignRect( aAlignedGrfRect, &rSh );
1632 /// OD 17.10.2002 #103876# - change type from <BOOL> to <bool>.
1633 const bool bNotInside = bClip && !rOut.IsInside( aAlignedGrfRect );
1634 if ( bNotInside )
1636 pOut->Push( PUSH_CLIPREGION );
1637 pOut->IntersectClipRegion( rOut.SVRect() );
1640 //Hier kein Link, wir wollen die Grafik synchron laden!
1641 ((SvxBrushItem&)rBrush).SetDoneLink( Link() );
1642 GraphicObject *pGrf = (GraphicObject*)rBrush.GetGraphicObject(
1643 GETOBJSHELL() );
1645 /// OD 17.10.2002 #103876# - outsourcing drawing of background with a background color.
1646 ::lcl_DrawGraphicBackgrd( rBrush, pOut, aAlignedGrfRect, *pGrf, bGrfNum, bBackgrdAlreadyDrawn );
1648 /// OD 25.09.2002 #99739# -
1649 /// Because for drawing a graphic left-top-corner and size coordinations are
1650 /// used, these coordinations have to be determined on pixel level.
1651 ::SwAlignGrfRect( &aAlignedGrfRect, *pOut );
1652 pGrf->Draw( pOut, aAlignedGrfRect.Pos(), aAlignedGrfRect.SSize() );
1654 if ( bNotInside )
1655 pOut->Pop();
1656 } // end of method <lcl_DrawGraphic>
1658 void MA_FASTCALL DrawGraphic( const SvxBrushItem *pBrush,
1659 OutputDevice *pOutDev,
1660 const SwRect &rOrg,
1661 const SwRect &rOut,
1662 const BYTE nGrfNum,
1663 const sal_Bool bConsiderBackgroundTransparency )
1664 /// OD 05.08.2002 #99657# - add 6th parameter to indicate that method should
1665 /// consider background transparency, saved in the color of the brush item
1667 ViewShell &rSh = *pGlobalShell;
1668 /// OD 17.10.2002 #103876# - change type from <BOOL> to <bool>
1669 bool bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum;
1670 bool bGrfNum = GRFNUM_NO != nGrfNum;
1671 Size aGrfSize;
1672 SvxGraphicPosition ePos = GPOS_NONE;
1673 if( pBrush && !bReplaceGrfNum )
1675 if( rSh.GetViewOptions()->IsGraphic() )
1677 //#125488#: load graphic directly in PDF import
1678 // --> OD 2006-08-25 #i68953# - also during print load graphic directly.
1679 if ( (rSh).GetViewOptions()->IsPDFExport() ||
1680 rSh.GetOut()->GetOutDevType() == OUTDEV_PRINTER )
1681 // <--
1683 ((SvxBrushItem*)pBrush)->PurgeMedium();
1684 ((SvxBrushItem*)pBrush)->SetDoneLink( Link() );
1686 else
1687 ((SvxBrushItem*)pBrush)->SetDoneLink( STATIC_LINK(
1688 rSh.GetDoc(), SwDoc, BackgroundDone ) );
1689 SfxObjectShell &rObjSh = *GETOBJSHELL();
1690 const Graphic* pGrf = pBrush->GetGraphic( &rObjSh );
1691 if( pGrf && GRAPHIC_NONE != pGrf->GetType() )
1693 ePos = pBrush->GetGraphicPos();
1694 if( pGrf->IsSupportedGraphic() )
1695 // don't the use the specific output device! Bug 94802
1696 aGrfSize = ::GetGraphicSizeTwip( *pGrf, 0 );
1699 else
1700 bReplaceGrfNum = bGrfNum;
1703 SwRect aGrf;
1704 aGrf.SSize( aGrfSize );
1705 BOOL bDraw = TRUE;
1706 BOOL bRetouche = TRUE;
1707 switch ( ePos )
1709 case GPOS_LT:
1710 aGrf.Pos() = rOrg.Pos();
1711 break;
1713 case GPOS_MT:
1714 aGrf.Pos().Y() = rOrg.Top();
1715 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1716 break;
1718 case GPOS_RT:
1719 aGrf.Pos().Y() = rOrg.Top();
1720 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1721 break;
1723 case GPOS_LM:
1724 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1725 aGrf.Pos().X() = rOrg.Left();
1726 break;
1728 case GPOS_MM:
1729 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1730 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1731 break;
1733 case GPOS_RM:
1734 aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1735 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1736 break;
1738 case GPOS_LB:
1739 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1740 aGrf.Pos().X() = rOrg.Left();
1741 break;
1743 case GPOS_MB:
1744 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1745 aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1746 break;
1748 case GPOS_RB:
1749 aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1750 aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1751 break;
1753 case GPOS_AREA:
1754 aGrf = rOrg;
1755 /// OD 05.09.2002 #102912#
1756 /// In spite the fact that the background graphic have to fill the complete
1757 /// area, it has been checked, if the graphic will completely fill out
1758 /// the region to be painted <rOut> and thus, nothing has to be retouched.
1759 /// For example, this is the case for a fly frame without a background
1760 /// brush positioned on the border of the page and inherited the
1761 /// background brush from the page.
1762 bRetouche = !rOut.IsInside( aGrf );
1763 break;
1765 case GPOS_TILED:
1767 // OD 17.10.2002 #103876# - draw background of tiled graphic
1768 // before drawing tiled graphic in loop
1769 // determine graphic object
1770 GraphicObject* pGraphicObj = const_cast< GraphicObject* >(pBrush->GetGraphicObject( GETOBJSHELL() ));
1771 // calculate aligned paint rectangle
1772 SwRect aAlignedPaintRect = rOut;
1773 ::SwAlignRect( aAlignedPaintRect, &rSh );
1774 // OD 25.10.2002 #103876# - draw background color for aligned paint rectangle
1775 lcl_DrawGraphicBackgrd( *pBrush, pOutDev, aAlignedPaintRect, *pGraphicObj, bGrfNum );
1777 // set left-top-corner of background graphic to left-top-corner of the
1778 // area, from which the background brush is determined.
1779 aGrf.Pos() = rOrg.Pos();
1780 // setup clipping at output device
1781 pOutDev->Push( PUSH_CLIPREGION );
1782 pOutDev->IntersectClipRegion( rOut.SVRect() );
1783 // OD 28.10.2002 #103876# - use new method <GraphicObject::DrawTiled(::)>
1785 // calculate paint offset
1786 Point aPaintOffset( aAlignedPaintRect.Pos() - aGrf.Pos() );
1787 // draw background graphic tiled for aligned paint rectangle
1788 // --> OD 2005-02-15 #i42643# - apply fix #104004# for Calc
1789 // also for Writer - see /sc/source/view/printfun.cxx
1790 // For PDF export, every draw operation for bitmaps takes a
1791 // noticeable amount of place (~50 characters). Thus, optimize
1792 // between tile bitmap size and number of drawing operations here.
1794 // A_out
1795 // n_chars = k1 * ---------- + k2 * A_bitmap
1796 // A_bitmap
1798 // minimum n_chars is obtained for (derive for A_bitmap,
1799 // set to 0, take positive solution):
1800 // k1
1801 // A_bitmap = Sqrt( ---- A_out )
1802 // k2
1804 // where k1 is the number of chars per draw operation, and
1805 // k2 is the number of chars per bitmap pixel.
1806 // This is approximately 50 and 7 for current PDF writer, respectively.
1808 const double k1( 50 );
1809 const double k2( 7 );
1810 const Size aSize( aAlignedPaintRect.SSize() );
1811 const double Abitmap( k1/k2 * static_cast<double>(aSize.Width())*aSize.Height() );
1813 pGraphicObj->DrawTiled( pOutDev,
1814 aAlignedPaintRect.SVRect(),
1815 aGrf.SSize(),
1816 Size( aPaintOffset.X(), aPaintOffset.Y() ),
1817 NULL, GRFMGR_DRAW_STANDARD,
1818 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1819 // <--
1821 // reset clipping at output device
1822 pOutDev->Pop();
1823 // set <bDraw> and <bRetouche> to false, indicating that background
1824 // graphic and background are already drawn.
1825 bDraw = bRetouche = FALSE;
1827 break;
1829 case GPOS_NONE:
1830 bDraw = FALSE;
1831 break;
1833 default: ASSERT( !pOutDev, "new Graphic position?" );
1836 /// OD 02.09.2002 #99657#
1837 /// init variable <bGrfBackgrdAlreadDrawn> to indicate, if background of
1838 /// graphic is already drawn or not.
1839 bool bGrfBackgrdAlreadyDrawn = false;
1840 if ( bRetouche )
1842 // OD 2004-04-23 #116347#
1843 pOutDev->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
1844 pOutDev->SetLineColor();
1846 // OD 07.08.2002 #99657# #GetTransChg#
1847 // check, if a existing background graphic (not filling the complete
1848 // background) is transparent drawn and the background color is
1849 // "no fill" respectively "auto fill", if background transparency
1850 // has to be considered.
1851 // If YES, memorise transparency of background graphic.
1852 // check also, if background graphic bitmap is transparent.
1853 bool bTransparentGrfWithNoFillBackgrd = false;
1854 sal_Int32 nGrfTransparency = 0;
1855 bool bGrfIsTransparent = false;
1856 if ( (ePos != GPOS_NONE) &&
1857 (ePos != GPOS_TILED) && (ePos != GPOS_AREA)
1860 GraphicObject *pGrf = (GraphicObject*)pBrush->GetGraphicObject(
1861 GETOBJSHELL() );
1862 if ( bConsiderBackgroundTransparency )
1864 GraphicAttr pGrfAttr = pGrf->GetAttr();
1865 if ( (pGrfAttr.GetTransparency() != 0) &&
1866 ( pBrush && (pBrush->GetColor() == COL_TRANSPARENT) )
1869 bTransparentGrfWithNoFillBackgrd = true;
1870 nGrfTransparency = pGrfAttr.GetTransparency();
1873 if ( pGrf->IsTransparent() )
1875 bGrfIsTransparent = true;
1879 /// OD 06.08.2002 #99657# #GetTransChg# - to get color of brush,
1880 /// check background color against COL_TRANSPARENT ("no fill"/"auto fill")
1881 /// instead of checking, if transparency is not set.
1882 const Color aColor( pBrush &&
1883 ( !(pBrush->GetColor() == COL_TRANSPARENT) ||
1884 bFlyMetafile )
1885 ? pBrush->GetColor()
1886 : aGlobalRetoucheColor );
1888 /// OD 08.08.2002 #99657# - determine, if background region have to be
1889 /// drawn transparent.
1890 /// background region has to be drawn transparent, if
1891 /// background transparency have to be considered
1892 /// AND
1893 /// ( background color is transparent OR
1894 /// background graphic is transparent and background color is "no fill"
1895 /// )
1896 sal_Bool bDrawTransparent = bConsiderBackgroundTransparency &&
1897 ( ( aColor.GetTransparency() != 0) ||
1898 bTransparentGrfWithNoFillBackgrd );
1900 // --> OD 2008-06-02 #i75614#
1901 // reset draw mode in high contrast mode in order to get fill color set
1902 const ULONG nOldDrawMode = pOutDev->GetDrawMode();
1903 if ( pGlobalShell->GetWin() &&
1904 Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1906 pOutDev->SetDrawMode( 0 );
1908 // <--
1910 /// OD 06.08.2002 #99657# - if background region have to be drawn
1911 /// transparent, set only the RGB values of the background color as
1912 /// the fill color for the output device.
1913 if ( bDrawTransparent )
1915 if( pOutDev->GetFillColor() != aColor.GetRGBColor() )
1916 pOutDev->SetFillColor( aColor.GetRGBColor() );
1918 else
1920 if( pOutDev->GetFillColor() != aColor )
1921 pOutDev->SetFillColor( aColor );
1924 // --> OD 2008-06-02 #i75614#
1925 // restore draw mode
1926 pOutDev->SetDrawMode( nOldDrawMode );
1927 // <--
1929 /// OD 02.09.2002 #99657#
1930 if ( bDrawTransparent )
1932 /// background region have to be drawn transparent.
1933 /// Thus, create a poly-polygon from the region and draw it with
1934 /// the corresponding transparency precent.
1935 PolyPolygon aDrawPoly( rOut.SVRect() );
1936 if ( aGrf.HasArea() )
1938 if ( !bGrfIsTransparent )
1940 /// substract area of background graphic from draw area
1941 /// OD 08.10.2002 #103898# - consider only that part of the
1942 /// graphic area that is overlapping with draw area.
1943 SwRect aTmpGrf = aGrf;
1944 aTmpGrf.Intersection( rOut );
1945 if ( aTmpGrf.HasArea() )
1947 Polygon aGrfPoly( aTmpGrf.SVRect() );
1948 aDrawPoly.Insert( aGrfPoly );
1951 else
1952 bGrfBackgrdAlreadyDrawn = true;
1954 /// calculate transparency percent:
1955 /// ( <transparency value[0x01..0xFF]>*100 + 0x7F ) / 0xFF
1956 /// If there is a background graphic with a background color "no fill"/"auto fill",
1957 /// the transparency value is taken from the background graphic,
1958 /// otherwise take the transparency value from the color.
1959 sal_Int8 nTransparencyPercent = static_cast<sal_Int8>(
1960 (( bTransparentGrfWithNoFillBackgrd ? nGrfTransparency : aColor.GetTransparency()
1961 )*100 + 0x7F)/0xFF);
1962 /// draw poly-polygon transparent
1963 pOutDev->DrawTransparent( aDrawPoly, nTransparencyPercent );
1965 else
1967 SwRegionRects aRegion( rOut, 4 );
1968 if ( !bGrfIsTransparent )
1969 aRegion -= aGrf;
1970 else
1971 bGrfBackgrdAlreadyDrawn = true;
1972 /// loop rectangles of background region, which has to be drawn
1973 for( USHORT i = 0; i < aRegion.Count(); ++i )
1975 pOutDev->DrawRect( aRegion[i].SVRect() );
1978 pOutDev ->Pop();
1981 if( bDraw && aGrf.IsOver( rOut ) )
1982 /// OD 02.09.2002 #99657#
1983 /// add parameter <bGrfBackgrdAlreadyDrawn>
1984 lcl_DrawGraphic( *pBrush, pOutDev, rSh, aGrf, rOut, true, bGrfNum,
1985 bGrfBackgrdAlreadyDrawn );
1987 if( bReplaceGrfNum )
1989 const BitmapEx& rBmp = ViewShell::GetReplacementBitmap( false );
1990 Font aTmp( pOutDev->GetFont() );
1991 Graphic::DrawEx( pOutDev, aEmptyStr, aTmp, rBmp, rOrg.Pos(), rOrg.SSize() );
1995 //------------------------------------------------------------------------
1997 /** local help method for SwRootFrm::Paint(..) - Adjust given rectangle to pixel size
1999 By OD at 27.09.2002 for #103636#
2000 In order to avoid paint errors caused by multiple alignments - e.g. method
2001 ::SwAlignRect(..) - and other changes to the rectangle to be painted,
2002 this method is called for the rectangle to be painted in order to
2003 adjust it to the pixel it is overlapping.
2005 @author OD
2007 void lcl_AdjustRectToPixelSize( SwRect& io_aSwRect, const OutputDevice &aOut )
2009 /// local constant object of class <Size> to determine number of Twips
2010 /// representing a pixel.
2011 const Size aTwipToPxSize( aOut.PixelToLogic( Size( 1,1 )) );
2013 /// local object of class <Rectangle> in Twip coordinates
2014 /// calculated from given rectangle aligned to pixel centers.
2015 const Rectangle aPxCenterRect = aOut.PixelToLogic(
2016 aOut.LogicToPixel( io_aSwRect.SVRect() ) );
2018 /// local constant object of class <Rectangle> representing given rectangle
2019 /// in pixel.
2020 const Rectangle aOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2022 /// calculate adjusted rectangle from pixel centered rectangle.
2023 /// Due to rounding differences <aPxCenterRect> doesn't exactly represents
2024 /// the Twip-centers. Thus, adjust borders by half of pixel width/height plus 1.
2025 /// Afterwards, adjust calculated Twip-positions of the all borders.
2026 Rectangle aSizedRect = aPxCenterRect;
2027 aSizedRect.Left() -= (aTwipToPxSize.Width()/2 + 1);
2028 aSizedRect.Right() += (aTwipToPxSize.Width()/2 + 1);
2029 aSizedRect.Top() -= (aTwipToPxSize.Height()/2 + 1);
2030 aSizedRect.Bottom() += (aTwipToPxSize.Height()/2 + 1);
2032 /// adjust left()
2033 while ( (aOut.LogicToPixel(aSizedRect)).Left() < aOrgPxRect.Left() )
2035 ++aSizedRect.Left();
2037 /// adjust right()
2038 while ( (aOut.LogicToPixel(aSizedRect)).Right() > aOrgPxRect.Right() )
2040 --aSizedRect.Right();
2042 /// adjust top()
2043 while ( (aOut.LogicToPixel(aSizedRect)).Top() < aOrgPxRect.Top() )
2045 ++aSizedRect.Top();
2047 /// adjust bottom()
2048 while ( (aOut.LogicToPixel(aSizedRect)).Bottom() > aOrgPxRect.Bottom() )
2050 --aSizedRect.Bottom();
2053 io_aSwRect = SwRect( aSizedRect );
2055 #ifndef PRODUCT
2056 Rectangle aTestOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2057 Rectangle aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2058 ASSERT( aTestOrgPxRect == aTestNewPxRect,
2059 "Error in lcl_AlignRectToPixelSize(..): Adjusted rectangle has incorrect position or size");
2060 #if OSL_DEBUG_LEVEL > 1
2061 Rectangle aTestNewRect( aSizedRect );
2062 /// check Left()
2063 --aSizedRect.Left();
2064 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2065 ASSERT( aTestOrgPxRect.Left() >= (aTestNewPxRect.Left()+1),
2066 "Error in lcl_AlignRectToPixelSize(..): Left() not correct adjusted");
2067 ++aSizedRect.Left();
2068 /// check Right()
2069 ++aSizedRect.Right();
2070 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2071 ASSERT( aTestOrgPxRect.Right() <= (aTestNewPxRect.Right()-1),
2072 "Error in lcl_AlignRectToPixelSize(..): Right() not correct adjusted");
2073 --aSizedRect.Right();
2074 /// check Top()
2075 --aSizedRect.Top();
2076 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2077 ASSERT( aTestOrgPxRect.Top() >= (aTestNewPxRect.Top()+1),
2078 "Error in lcl_AlignRectToPixelSize(..): Top() not correct adjusted");
2079 ++aSizedRect.Top();
2080 /// check Bottom()
2081 ++aSizedRect.Bottom();
2082 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2083 ASSERT( aTestOrgPxRect.Bottom() <= (aTestNewPxRect.Bottom()-1),
2084 "Error in lcl_AlignRectToPixelSize(..): Bottom() not correct adjusted");
2085 --aSizedRect.Bottom();
2086 #endif
2087 #endif
2092 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES START
2095 struct SwLineEntry
2097 SwTwips mnKey;
2098 SwTwips mnStartPos;
2099 SwTwips mnEndPos;
2101 svx::frame::Style maAttribute;
2103 enum OverlapType { NO_OVERLAP, OVERLAP1, OVERLAP2, OVERLAP3 };
2105 public:
2106 SwLineEntry( SwTwips nKey,
2107 SwTwips nStartPos,
2108 SwTwips nEndPos,
2109 const svx::frame::Style& rAttribute );
2111 OverlapType Overlaps( const SwLineEntry& rComp ) const;
2114 SwLineEntry::SwLineEntry( SwTwips nKey,
2115 SwTwips nStartPos,
2116 SwTwips nEndPos,
2117 const svx::frame::Style& rAttribute )
2118 : mnKey( nKey ),
2119 mnStartPos( nStartPos ),
2120 mnEndPos( nEndPos ),
2121 maAttribute( rAttribute )
2127 1. ---------- rOld
2128 ---------- rNew
2130 2. ---------- rOld
2131 ------------- rNew
2133 3. ------- rOld
2134 ------------- rNew
2136 4. ------------- rOld
2137 ---------- rNew
2139 5. ---------- rOld
2140 ---- rNew
2142 6. ---------- rOld
2143 ---------- rNew
2145 7. ------------- rOld
2146 ---------- rNew
2148 8. ---------- rOld
2149 ------------- rNew
2151 9. ---------- rOld
2152 ---------- rNew
2155 SwLineEntry::OverlapType SwLineEntry::Overlaps( const SwLineEntry& rNew ) const
2157 SwLineEntry::OverlapType eRet = OVERLAP3;
2159 if ( mnStartPos >= rNew.mnEndPos || mnEndPos <= rNew.mnStartPos )
2160 eRet = NO_OVERLAP;
2162 // 1, 2, 3
2163 else if ( mnEndPos < rNew.mnEndPos )
2164 eRet = OVERLAP1;
2166 // 4, 5, 6, 7
2167 else if ( mnStartPos <= rNew.mnStartPos && mnEndPos >= rNew.mnEndPos )
2168 eRet = OVERLAP2;
2170 // 8, 9
2171 return eRet;
2174 struct lt_SwLineEntry
2176 bool operator()( const SwLineEntry& e1, const SwLineEntry& e2 ) const
2178 return e1.mnStartPos < e2.mnStartPos;
2182 typedef std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet;
2183 typedef std::set< SwLineEntry, lt_SwLineEntry >::iterator SwLineEntrySetIter;
2184 typedef std::set< SwLineEntry, lt_SwLineEntry >::const_iterator SwLineEntrySetConstIter;
2185 typedef std::map< SwTwips, SwLineEntrySet > SwLineEntryMap;
2186 typedef std::map< SwTwips, SwLineEntrySet >::iterator SwLineEntryMapIter;
2187 typedef std::map< SwTwips, SwLineEntrySet >::const_iterator SwLineEntryMapConstIter;
2189 class SwTabFrmPainter
2191 SwLineEntryMap maVertLines;
2192 SwLineEntryMap maHoriLines;
2193 const SwTabFrm& mrTabFrm;
2195 void Insert( SwLineEntry&, bool bHori );
2196 void Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem );
2197 void HandleFrame( const SwLayoutFrm& rFrm );
2198 void FindStylesForLine( const Point&,
2199 const Point&,
2200 svx::frame::Style*,
2201 bool bHori ) const;
2203 public:
2204 SwTabFrmPainter( const SwTabFrm& rTabFrm );
2206 void PaintLines( OutputDevice& rDev, const SwRect& rRect ) const;
2209 SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm )
2210 : mrTabFrm( rTabFrm )
2212 HandleFrame( rTabFrm );
2215 void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm )
2217 // Add border lines of cell frames. Skip covered cells. Skip cells
2218 // in special row span row, which do not have a negative row span:
2219 if ( rLayoutFrm.IsCellFrm() && !rLayoutFrm.IsCoveredCell() )
2221 const SwCellFrm* pThisCell = static_cast<const SwCellFrm*>(&rLayoutFrm);
2222 const SwRowFrm* pRowFrm = static_cast<const SwRowFrm*>(pThisCell->GetUpper());
2223 const long nRowSpan = pThisCell->GetTabBox()->getRowSpan();
2224 if ( !pRowFrm->IsRowSpanLine() || nRowSpan > 1 || nRowSpan < -1 )
2226 SwBorderAttrAccess aAccess( SwFrm::GetCache(), &rLayoutFrm );
2227 const SwBorderAttrs& rAttrs = *aAccess.Get();
2228 const SvxBoxItem& rBox = rAttrs.GetBox();
2229 Insert( rLayoutFrm, rBox );
2233 // Recurse into lower layout frames, but do not recurse into lower tabframes.
2234 const SwFrm* pLower = rLayoutFrm.Lower();
2235 while ( pLower )
2237 const SwLayoutFrm* pLowerLayFrm = dynamic_cast<const SwLayoutFrm*>(pLower);
2238 if ( pLowerLayFrm && !pLowerLayFrm->IsTabFrm() )
2239 HandleFrame( *pLowerLayFrm );
2241 pLower = pLower->GetNext();
2245 void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) const
2247 // --> FME 2004-06-24 #i16816# tagged pdf support
2248 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev );
2249 // <--
2251 const SwFrm* pTmpFrm = &mrTabFrm;
2252 const bool bVert = pTmpFrm->IsVertical();
2254 SwLineEntryMapConstIter aIter = maHoriLines.begin();
2255 bool bHori = true;
2257 // color for subsidiary lines:
2258 const Color& rCol( SwViewOption::GetTableBoundariesColor() );
2260 // high contrast mode:
2261 // overrides the color of non-subsidiary lines.
2262 const Color* pHCColor = 0;
2263 ULONG nOldDrawMode = rDev.GetDrawMode();
2264 if( pGlobalShell->GetWin() &&
2265 Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
2267 pHCColor = &SwViewOption::GetFontColor();
2268 rDev.SetDrawMode( 0 );
2271 // set clip region:
2272 rDev.Push( PUSH_CLIPREGION );
2273 Size aSize( rRect.SSize() );
2274 // Hack! Necessary, because the layout is not pixel aligned!
2275 aSize.Width() += nPixelSzW; aSize.Height() += nPixelSzH;
2276 rDev.SetClipRegion( Rectangle( rRect.Pos(), aSize ) );
2278 // The following stuff if necessary to have the new table borders fit
2279 // into a ::SwAlignRect adjusted world.
2280 const SwTwips nTwipXCorr = bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-)
2281 const SwTwips nTwipYCorr = !bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-)
2282 const SwFrm* pUpper = mrTabFrm.GetUpper();
2283 SwRect aUpper( pUpper->Prt() );
2284 aUpper.Pos() += pUpper->Frm().Pos();
2285 SwRect aUpperAligned( aUpper );
2286 ::SwAlignRect( aUpperAligned, pGlobalShell );
2288 while ( true )
2290 if ( bHori && aIter == maHoriLines.end() )
2292 aIter = maVertLines.begin();
2293 bHori = false;
2296 if ( !bHori && aIter == maVertLines.end() )
2297 break;
2299 const SwLineEntrySet& rEntrySet = (*aIter).second;
2300 SwLineEntrySetIter aSetIter = rEntrySet.begin();
2301 while ( aSetIter != rEntrySet.end() )
2303 const SwLineEntry& rEntry = *aSetIter;
2304 const svx::frame::Style& rEntryStyle( (*aSetIter).maAttribute );
2306 Point aStart, aEnd;
2307 if ( bHori )
2309 aStart.X() = rEntry.mnStartPos;
2310 aStart.Y() = rEntry.mnKey;
2311 aEnd.X() = rEntry.mnEndPos;
2312 aEnd.Y() = rEntry.mnKey;
2314 else
2316 aStart.X() = rEntry.mnKey;
2317 aStart.Y() = rEntry.mnStartPos;
2318 aEnd.X() = rEntry.mnKey;
2319 aEnd.Y() = rEntry.mnEndPos;
2322 SwRect aRepaintRect( aStart, aEnd );
2324 // the repaint rectangle has to be moved a bit for the centered lines:
2325 SwTwips nRepaintRectSize = !rEntryStyle.GetWidth() ? 1 : rEntryStyle.GetWidth();
2326 if ( bHori )
2328 aRepaintRect.Height( 2 * nRepaintRectSize );
2329 aRepaintRect.Pos().Y() -= nRepaintRectSize;
2331 else
2333 aRepaintRect.Width( 2 * nRepaintRectSize );
2334 aRepaintRect.Pos().X() -= nRepaintRectSize;
2337 if ( rRect.IsOver( aRepaintRect ) )
2339 svx::frame::Style aStyles[ 7 ];
2340 aStyles[ 0 ] = rEntryStyle;
2341 FindStylesForLine( aStart, aEnd, aStyles, bHori );
2343 // subsidiary lines
2344 const Color* pTmpColor = 0;
2345 if ( 0 == aStyles[ 0 ].GetWidth() )
2347 if ( IS_SUBS_TABLE && pGlobalShell->GetWin() )
2348 aStyles[ 0 ].Set( rCol, 1, 0, 0 );
2350 else
2351 pTmpColor = pHCColor;
2353 // The line sizes stored in the line style have to be adjusted as well.
2354 // This will guarantee that lines with the same twip size will have the
2355 // same pixel size.
2356 for ( int i = 0; i < 7; ++i )
2358 sal_uInt16 nPrim = aStyles[ i ].Prim();
2359 sal_uInt16 nDist = aStyles[ i ].Dist();
2360 sal_uInt16 nSecn = aStyles[ i ].Secn();
2362 if ( nPrim > 0 )
2363 nPrim = (sal_uInt16)( Max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) );
2364 if ( nDist > 0 )
2365 nDist = (sal_uInt16)( Max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) );
2366 if ( nSecn > 0 )
2367 nSecn = (sal_uInt16)( Max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) );
2369 aStyles[ i ].Set( nPrim, nDist, nSecn );
2372 // The (twip) positions will be adjusted to meet these requirements:
2373 // 1. The y coordinates are located in the middle of the pixel grid
2374 // 2. The x coordinated are located at the beginning of the pixel grid
2375 // This is done, because the horizontal lines are painted "at beginning",
2376 // whereas the vertical lines are painted "centered". By making the line
2377 // sizes a multiple of one pixel size, we can assure, that all lines having
2378 // the same twip size have the same pixel size, independent of their position
2379 // on the screen.
2380 Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel( aStart ) );
2381 Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel( aEnd ) );
2383 if( pGlobalShell->GetWin() )
2385 // The table borders do not use SwAlignRect, but all the other frames do.
2386 // Therefore we tweak the outer borders a bit to achieve that the outer
2387 // borders match the subsidiary lines of the upper:
2388 if ( aStart.X() == aUpper.Left() )
2389 aPaintStart.X() = aUpperAligned.Left();
2390 else if ( aStart.X() == aUpper._Right() )
2391 aPaintStart.X() = aUpperAligned._Right();
2392 if ( aStart.Y() == aUpper.Top() )
2393 aPaintStart.Y() = aUpperAligned.Top();
2394 else if ( aStart.Y() == aUpper._Bottom() )
2395 aPaintStart.Y() = aUpperAligned._Bottom();
2397 if ( aEnd.X() == aUpper.Left() )
2398 aPaintEnd.X() = aUpperAligned.Left();
2399 else if ( aEnd.X() == aUpper._Right() )
2400 aPaintEnd.X() = aUpperAligned._Right();
2401 if ( aEnd.Y() == aUpper.Top() )
2402 aPaintEnd.Y() = aUpperAligned.Top();
2403 else if ( aEnd.Y() == aUpper._Bottom() )
2404 aPaintEnd.Y() = aUpperAligned._Bottom();
2407 aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel
2408 aPaintEnd.X() -= nTwipXCorr;
2409 aPaintStart.Y() -= nTwipYCorr;
2410 aPaintEnd.Y() -= nTwipYCorr;
2412 // Here comes the painting stuff: Thank you, DR, great job!!!
2413 if ( bHori )
2415 svx::frame::DrawHorFrameBorder
2417 rDev,
2418 aPaintStart,
2419 aPaintEnd,
2420 aStyles[ 0 ], // current style
2421 aStyles[ 1 ], // aLFromT
2422 aStyles[ 2 ], // aLFromL
2423 aStyles[ 3 ], // aLFromB
2424 aStyles[ 4 ], // aRFromT
2425 aStyles[ 5 ], // aRFromR
2426 aStyles[ 6 ], // aRFromB
2427 pTmpColor
2430 else
2432 svx::frame::DrawVerFrameBorder
2434 rDev,
2435 aPaintStart,
2436 aPaintEnd,
2437 aStyles[ 0 ], // current style
2438 aStyles[ 1 ], // aTFromL
2439 aStyles[ 2 ], // aTFromT
2440 aStyles[ 3 ], // aTFromR
2441 aStyles[ 4 ], // aBFromL
2442 aStyles[ 5 ], // aBFromB
2443 aStyles[ 6 ], // aBFromR
2444 pTmpColor
2449 ++aSetIter;
2452 ++aIter;
2455 // restore output device:
2456 rDev.Pop();
2457 rDev.SetDrawMode( nOldDrawMode );
2460 // Finds the lines that join the line defined by (StartPoint, EndPoint) in either
2461 // StartPoint or Endpoint. The styles of these lines are required for DR's magic
2462 // line painting functions.
2463 void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint,
2464 const Point& rEndPoint,
2465 svx::frame::Style* pStyles,
2466 bool bHori ) const
2468 // pStyles[ 1 ] = bHori ? aLFromT : TFromL
2469 // pStyles[ 2 ] = bHori ? aLFromL : TFromT,
2470 // pStyles[ 3 ] = bHori ? aLFromB : TFromR,
2471 // pStyles[ 4 ] = bHori ? aRFromT : BFromL,
2472 // pStyles[ 5 ] = bHori ? aRFromR : BFromB,
2473 // pStyles[ 6 ] = bHori ? aRFromB : BFromR,
2475 SwLineEntryMapConstIter aMapIter = maVertLines.find( rStartPoint.X() );
2476 ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" )
2477 const SwLineEntrySet& rVertSet = (*aMapIter).second;
2478 SwLineEntrySetConstIter aIter = rVertSet.begin();
2480 while ( aIter != rVertSet.end() )
2482 const SwLineEntry& rEntry = *aIter;
2483 if ( bHori )
2485 if ( rStartPoint.Y() == rEntry.mnStartPos )
2486 pStyles[ 3 ] = rEntry.maAttribute;
2487 else if ( rStartPoint.Y() == rEntry.mnEndPos )
2488 pStyles[ 1 ] = rEntry.maAttribute;
2490 else
2492 if ( rStartPoint.Y() == rEntry.mnEndPos )
2493 pStyles[ 2 ] = rEntry.maAttribute;
2494 else if ( rEndPoint.Y() == rEntry.mnStartPos )
2495 pStyles[ 5 ] = rEntry.maAttribute;
2497 ++aIter;
2500 aMapIter = maHoriLines.find( rStartPoint.Y() );
2501 ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" )
2502 const SwLineEntrySet& rHoriSet = (*aMapIter).second;
2503 aIter = rHoriSet.begin();
2505 while ( aIter != rHoriSet.end() )
2507 const SwLineEntry& rEntry = *aIter;
2508 if ( bHori )
2510 if ( rStartPoint.X() == rEntry.mnEndPos )
2511 pStyles[ 2 ] = rEntry.maAttribute;
2512 else if ( rEndPoint.X() == rEntry.mnStartPos )
2513 pStyles[ 5 ] = rEntry.maAttribute;
2515 else
2517 if ( rStartPoint.X() == rEntry.mnEndPos )
2518 pStyles[ 1 ] = rEntry.maAttribute;
2519 else if ( rStartPoint.X() == rEntry.mnStartPos )
2520 pStyles[ 3 ] = rEntry.maAttribute;
2522 ++aIter;
2525 if ( bHori )
2527 aMapIter = maVertLines.find( rEndPoint.X() );
2528 ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" )
2529 const SwLineEntrySet& rVertSet2 = (*aMapIter).second;
2530 aIter = rVertSet2.begin();
2532 while ( aIter != rVertSet2.end() )
2534 const SwLineEntry& rEntry = *aIter;
2535 if ( rEndPoint.Y() == rEntry.mnStartPos )
2536 pStyles[ 6 ] = rEntry.maAttribute;
2537 else if ( rEndPoint.Y() == rEntry.mnEndPos )
2538 pStyles[ 4 ] = rEntry.maAttribute;
2539 ++aIter;
2542 else
2544 aMapIter = maHoriLines.find( rEndPoint.Y() );
2545 ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" )
2546 const SwLineEntrySet& rHoriSet2 = (*aMapIter).second;
2547 aIter = rHoriSet2.begin();
2549 while ( aIter != rHoriSet2.end() )
2551 const SwLineEntry& rEntry = *aIter;
2552 if ( rEndPoint.X() == rEntry.mnEndPos )
2553 pStyles[ 4 ] = rEntry.maAttribute;
2554 else if ( rEndPoint.X() == rEntry.mnStartPos )
2555 pStyles[ 6 ] = rEntry.maAttribute;
2556 ++aIter;
2561 void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem )
2563 std::vector< const SwFrm* > aTestVec;
2564 aTestVec.push_back( &rFrm );
2565 aTestVec.push_back( &rFrm );
2566 aTestVec.push_back( &rFrm );
2568 // build 4 line entries for the 4 borders:
2569 SwRect aBorderRect = rFrm.Frm();
2570 if ( rFrm.IsTabFrm() )
2572 aBorderRect = rFrm.Prt();
2573 aBorderRect.Pos() += rFrm.Frm().Pos();
2576 const SwTwips nLeft = aBorderRect._Left();
2577 const SwTwips nRight = aBorderRect._Right();
2578 const SwTwips nTop = aBorderRect._Top();
2579 const SwTwips nBottom = aBorderRect._Bottom();
2581 svx::frame::Style aL( rBoxItem.GetLeft() );
2582 svx::frame::Style aR( rBoxItem.GetRight() );
2583 svx::frame::Style aT( rBoxItem.GetTop() );
2584 svx::frame::Style aB( rBoxItem.GetBottom() );
2586 aR.MirrorSelf();
2587 aB.MirrorSelf();
2589 bool bVert = mrTabFrm.IsVertical();
2590 bool bR2L = mrTabFrm.IsRightToLeft();
2592 aL.SetRefMode( svx::frame::REFMODE_CENTERED );
2593 aR.SetRefMode( svx::frame::REFMODE_CENTERED );
2594 aT.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
2595 aB.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
2597 SwLineEntry aLeft ( nLeft, nTop, nBottom, bVert ? aB : ( bR2L ? aR : aL ) );
2598 SwLineEntry aRight ( nRight, nTop, nBottom, bVert ? aT : ( bR2L ? aL : aR ) );
2599 SwLineEntry aTop ( nTop, nLeft, nRight, bVert ? aL : aT );
2600 SwLineEntry aBottom( nBottom, nLeft, nRight, bVert ? aR : aB );
2602 Insert( aLeft, false );
2603 Insert( aRight, false );
2604 Insert( aTop, true );
2605 Insert( aBottom, true );
2607 const SwRowFrm* pThisRowFrm = dynamic_cast<const SwRowFrm*>(rFrm.GetUpper());
2609 // special case: #i9860#
2610 // first line in follow table without repeated headlines
2611 if ( pThisRowFrm &&
2612 pThisRowFrm->GetUpper() == &mrTabFrm &&
2613 mrTabFrm.IsFollow() &&
2614 !mrTabFrm.GetTable()->GetRowsToRepeat() &&
2615 (!pThisRowFrm->GetPrev() || static_cast<const SwRowFrm*>(pThisRowFrm->GetPrev())->IsRowSpanLine()) &&
2616 !rBoxItem.GetTop() &&
2617 rBoxItem.GetBottom() )
2619 SwLineEntry aFollowTop( !bVert ? nTop : nRight, !bVert ? nLeft : nTop, !bVert ? nRight : nBottom, aB );
2620 Insert( aFollowTop, !bVert );
2624 void SwTabFrmPainter::Insert( SwLineEntry& rNew, bool bHori )
2626 // get all lines from structure, that have key entry of pLE
2627 SwLineEntryMap* pLine2 = bHori ? &maHoriLines : &maVertLines;
2628 const SwTwips nKey = rNew.mnKey;
2629 SwLineEntryMapIter aMapIter = pLine2->find( nKey );
2631 SwLineEntrySet* pLineSet = aMapIter != pLine2->end() ? &((*aMapIter).second) : 0;
2632 if ( !pLineSet )
2634 SwLineEntrySet aNewSet;
2635 (*pLine2)[ nKey ] = aNewSet;
2636 pLineSet = &(*pLine2)[ nKey ];
2638 SwLineEntrySetIter aIter = pLineSet->begin();
2640 while ( pLineSet && aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos )
2642 const SwLineEntry& rOld = *aIter;
2643 const SwLineEntry::OverlapType nOverlapType = rOld.Overlaps( rNew );
2645 const svx::frame::Style& rOldAttr = rOld.maAttribute;
2646 const svx::frame::Style& rNewAttr = rNew.maAttribute;
2647 const svx::frame::Style& rCmpAttr = rNewAttr > rOldAttr ? rNewAttr : rOldAttr;
2649 if ( SwLineEntry::OVERLAP1 == nOverlapType )
2651 ASSERT( rNew.mnStartPos >= rOld.mnStartPos, "Overlap type 3? How this?" )
2653 // new left segment
2654 const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
2656 // new middle segment
2657 const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rOld.mnEndPos, rCmpAttr );
2659 // new right segment
2660 rNew.mnStartPos = rOld.mnEndPos;
2662 // update current lines set
2663 pLineSet->erase( aIter );
2664 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
2665 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2667 aIter = pLineSet->begin();
2669 continue; // start over
2671 else if ( SwLineEntry::OVERLAP2 == nOverlapType )
2673 // new left segment
2674 const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
2676 // new middle segment
2677 const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rNew.mnEndPos, rCmpAttr );
2679 // new right segment
2680 const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr );
2682 // update current lines set
2683 pLineSet->erase( aIter );
2684 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
2685 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2686 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
2688 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
2690 break; // we are finished
2692 else if ( SwLineEntry::OVERLAP3 == nOverlapType )
2694 // new left segment
2695 const SwLineEntry aLeft( nKey, rNew.mnStartPos, rOld.mnStartPos, rNewAttr );
2697 // new middle segment
2698 const SwLineEntry aMiddle( nKey, rOld.mnStartPos, rNew.mnEndPos, rCmpAttr );
2700 // new right segment
2701 const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr );
2703 // update current lines set
2704 pLineSet->erase( aIter );
2705 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
2706 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2707 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
2709 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
2711 break; // we are finished
2714 ++aIter;
2717 if ( rNew.mnStartPos < rNew.mnEndPos ) // insert rest
2718 pLineSet->insert( rNew );
2722 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES END
2726 /*************************************************************************
2728 |* SwRootFrm::Paint()
2730 |* Beschreibung
2731 |* Fuer jede sichtbare Seite, die von Rect ber?hrt wird einmal Painten.
2732 |* 1. Umrandungen und Hintergruende Painten.
2733 |* 2. Den Draw Layer (Ramen und Zeichenobjekte) der unter dem Dokument
2734 |* liegt painten (Hoelle).
2735 |* 3. Den Dokumentinhalt (Text) Painten.
2736 |* 4. Den Drawlayer der ueber dem Dokuemnt liegt painten.
2738 |* Ersterstellung MA 01. Jun. 92
2739 |* Letzte Aenderung MA 10. Oct. 97
2741 |*************************************************************************/
2743 void SwRootFrm::Paint( const SwRect& rRect ) const
2745 ASSERT( Lower() && Lower()->IsPageFrm(), "Lower der Root keine Seite." );
2747 PROTOCOL( this, PROT_FILE_INIT, 0, 0)
2749 BOOL bResetRootPaint = FALSE;
2750 ViewShell *pSh = pCurrShell;
2752 if ( pSh->GetWin() )
2754 if ( pSh->GetOut() == pSh->GetWin() && !pSh->GetWin()->IsVisible() )
2756 return;
2758 if ( SwRootFrm::bInPaint )
2760 SwPaintQueue::Add( pSh, rRect );
2761 return;
2764 else
2765 SwRootFrm::bInPaint = bResetRootPaint = TRUE;
2767 SwSavePaintStatics *pStatics = 0;
2768 if ( pGlobalShell )
2769 pStatics = new SwSavePaintStatics();
2770 pGlobalShell = pSh;
2772 if( !pSh->GetWin() )
2773 pProgress = SfxProgress::GetActiveProgress( (SfxObjectShell*) pSh->GetDoc()->GetDocShell() );
2775 ::SwCalcPixStatics( pSh->GetOut() );
2776 aGlobalRetoucheColor = pSh->Imp()->GetRetoucheColor();
2778 //Ggf. eine Action ausloesen um klare Verhaeltnisse zu schaffen.
2779 //Durch diesen Kunstgriff kann in allen Paints davon ausgegangen werden,
2780 //das alle Werte gueltigt sind - keine Probleme, keine Sonderbehandlung(en).
2781 // --> OD 2008-10-07 #i92745#
2782 // Extend check on certain states of the 'current' <ViewShell> instance to
2783 // all existing <ViewShell> instances.
2784 // if ( !pSh->IsInEndAction() && !pSh->IsPaintInProgress() &&
2785 // (!pSh->Imp()->IsAction() || !pSh->Imp()->GetLayAction().IsActionInProgress() ) )
2786 bool bPerformLayoutAction( true );
2788 ViewShell* pTmpViewShell = pSh;
2789 do {
2790 if ( pTmpViewShell->IsInEndAction() ||
2791 pTmpViewShell->IsPaintInProgress() ||
2792 ( pTmpViewShell->Imp()->IsAction() &&
2793 pTmpViewShell->Imp()->GetLayAction().IsActionInProgress() ) )
2795 bPerformLayoutAction = false;
2798 pTmpViewShell = static_cast<ViewShell*>(pTmpViewShell->GetNext());
2799 } while ( bPerformLayoutAction && pTmpViewShell != pSh );
2801 if ( bPerformLayoutAction )
2802 // <--
2804 ((SwRootFrm*)this)->ResetTurbo();
2805 SwLayAction aAction( (SwRootFrm*)this, pSh->Imp() );
2806 aAction.SetPaint( FALSE );
2807 aAction.SetComplete( FALSE );
2808 aAction.SetReschedule( pProgress ? TRUE : FALSE );
2809 aAction.Action();
2810 ((SwRootFrm*)this)->ResetTurboFlag();
2811 if ( !pSh->ActionPend() )
2812 pSh->Imp()->DelRegions();
2815 SwRect aRect( rRect );
2816 aRect.Intersection( pSh->VisArea() );
2818 const BOOL bExtraData = ::IsExtraData( GetFmt()->GetDoc() );
2820 pLines = new SwLineRects; //Sammler fuer Umrandungen.
2822 // #104289#. During painting, something (OLE) can
2823 // load the linguistic, which in turn can cause a reformat
2824 // of the document. Dangerous! We better set this flag to
2825 // avoid the reformat.
2826 const sal_Bool bOldAction = IsCallbackActionEnabled();
2827 ((SwRootFrm*)this)->SetCallbackActionEnabled( FALSE );
2829 const SwPageFrm *pPage = pSh->Imp()->GetFirstVisPage();
2831 const bool bBookMode = pGlobalShell->GetViewOptions()->IsViewLayoutBookMode();
2832 if ( bBookMode && pPage->GetPrev() && static_cast<const SwPageFrm*>(pPage->GetPrev())->IsEmptyPage() )
2833 pPage = static_cast<const SwPageFrm*>(pPage->GetPrev());
2835 const bool bLTR = IsLeftToRightViewLayout();
2837 // #i68597#
2838 const bool bGridPainting(pSh->GetWin() && pSh->Imp()->HasDrawView() && pSh->Imp()->GetDrawView()->IsGridVisible());
2840 // --> OD 2008-05-16 #i84659#
2841 // while ( pPage && !::IsShortCut( aRect, pPage->Frm() ) )
2842 while ( pPage )
2843 // <--
2845 const bool bPaintRightShadow = !bBookMode || (pPage == Lower()) || (!bLTR && !pPage->OnRightPage()) || (bLTR && pPage->OnRightPage());
2846 const bool bRightSidebar = !pPage->MarginSide();
2848 if ( !pPage->IsEmptyPage() )
2850 SwRect aPaintRect;
2851 SwPageFrm::GetBorderAndShadowBoundRect( pPage->Frm(), pSh, aPaintRect, bRightSidebar );
2853 if ( aRect.IsOver( aPaintRect ) )
2854 // <--
2856 if ( pSh->GetWin() )
2858 pSubsLines = new SwSubsRects;
2859 // OD 18.11.2002 #99672# - create array for special sub-lines
2860 pSpecSubsLines = new SwSubsRects;
2863 aPaintRect._Intersection( aRect );
2865 // --> OD 2007-11-14 #i82616#
2866 // Invalidate area for extra data (line numbers or change tracking
2867 // marks), if painting on a window and the paint is trigger by an
2868 // end action. The inefficient and simple enlargement of the
2869 // paint area is replaced by this invalidation.
2870 // if ( bExtraData )
2871 // {
2872 // //Ja, das ist grob, aber wie macht man es besser?
2873 // SWRECTFN( pPage )
2874 // (aPaintRect.*fnRect->fnSetLeftAndWidth)(
2875 // (pPage->Frm().*fnRect->fnGetLeft)(),
2876 // (pPage->Frm().*fnRect->fnGetWidth)() );
2877 // aPaintRect._Intersection( pSh->VisArea() );
2878 // }
2879 if ( bExtraData &&
2880 pSh->GetWin() && pSh->IsInEndAction() )
2882 // enlarge paint rectangle to complete page width, subtract
2883 // current paint area and invalidate the resulting region.
2884 SWRECTFN( pPage )
2885 SwRect aPageRectTemp( aPaintRect );
2886 (aPageRectTemp.*fnRect->fnSetLeftAndWidth)(
2887 (pPage->Frm().*fnRect->fnGetLeft)(),
2888 (pPage->Frm().*fnRect->fnGetWidth)() );
2889 aPageRectTemp._Intersection( pSh->VisArea() );
2890 Region aPageRectRegion( aPageRectTemp.SVRect() );
2891 aPageRectRegion.Exclude( aPaintRect.SVRect() );
2892 pSh->GetWin()->Invalidate( aPageRectRegion, INVALIDATE_CHILDREN );
2894 // <--
2896 // --> OD 2007-08-20 #i80793#
2897 // enlarge paint rectangle for objects overlapping the same pixel
2898 // in all cases and before the DrawingLayer overlay is initialized.
2899 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
2900 // <--
2902 // #i68597#
2903 // moved paint pre-process for DrawingLayer overlay here since the above
2904 // code dependent from bExtraData may expand the PaintRect
2906 // #i75172# if called from ViewShell::ImplEndAction it sould no longer
2907 // really be used but handled by ViewShell::ImplEndAction already
2908 const Region aDLRegion(aPaintRect.SVRect());
2909 pSh->DLPrePaint2(aDLRegion);
2912 if(OUTDEV_WINDOW == pGlobalShell->GetOut()->GetOutDevType())
2914 /// OD 27.09.2002 #103636# - changed method SwLayVout::Enter(..)
2915 /// 2nd parameter is no longer <const> and will be set to the
2916 /// rectangle the virtual output device is calculated from <aPaintRect>,
2917 /// if the virtual output is used.
2918 pVout->Enter( pSh, aPaintRect, !bNoVirDev );
2920 /// OD 27.09.2002 #103636# - adjust paint rectangle to pixel size
2921 /// Thus, all objects overlapping on pixel level with the unadjusted
2922 /// paint rectangle will be considered in the paint.
2923 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
2926 // maybe this can be put in the above scope. Since we are not sure, just leave it ATM
2927 pVout->SetOrgRect( aPaintRect );
2929 /// OD 29.08.2002 #102450#
2930 /// determine background color of page for <PaintLayer> method
2931 /// calls, paint <hell> or <heaven>
2932 const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
2934 pPage->PaintBaBo( aPaintRect, pPage, TRUE );
2936 if ( pSh->Imp()->HasDrawView() )
2938 pLines->LockLines( TRUE );
2939 // OD 29.08.2002 #102450# - add 3rd parameter
2940 // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
2941 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
2942 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), aPaintRect,
2943 &aPageBackgrdColor, (pPage->IsRightToLeft() ? true : false) );
2944 pLines->PaintLines( pSh->GetOut() );
2945 pLines->LockLines( FALSE );
2948 if( pSh->GetWin() )
2950 // OD 18.11.2002 #99672# - collect sub-lines
2951 pPage->RefreshSubsidiary( aPaintRect );
2952 // OD 18.11.2002 #99672# - paint special sub-lines
2953 pSpecSubsLines->PaintSubsidiary( pSh->GetOut(), NULL );
2956 pPage->Paint( aPaintRect );
2958 // OD 20.12.2002 #94627# - no paint of page border and shadow, if
2959 // writer is in place mode.
2960 if( pSh->GetWin() && pSh->GetDoc()->GetDocShell() &&
2961 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
2963 // OD 12.02.2003 #i9719#, #105645# - use new method
2964 // <SwPageFrm::PaintBorderAndShadow(..)>.
2965 SwPageFrm::PaintBorderAndShadow( pPage->Frm(), pSh, bPaintRightShadow, bRightSidebar );
2966 SwPageFrm::PaintNotesSidebar( pPage->Frm(), pSh, pPage->GetPhyPageNum(), bRightSidebar);
2969 pLines->PaintLines( pSh->GetOut() );
2971 if ( pSh->Imp()->HasDrawView() )
2973 /// OD 29.08.2002 #102450# - add 3rd parameter
2974 // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
2975 pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(), aPaintRect,
2976 &aPageBackgrdColor,
2977 (pPage->IsRightToLeft() ? true : false) );
2980 if ( bExtraData )
2981 pPage->RefreshExtraData( aPaintRect );
2983 if ( pSh->GetWin() )
2985 pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines );
2986 DELETEZ( pSubsLines );
2987 DELETEZ( pSpecSubsLines );
2989 pVout->Leave();
2991 // #i68597#
2992 // needed to move grid painting inside Begin/EndDrawLayer bounds and to change
2993 // output rect for it accordingly
2994 if(bGridPainting)
2996 SdrPaintView* pPaintView = pSh->Imp()->GetDrawView();
2997 SdrPageView* pPageView = pPaintView->GetSdrPageView();
2998 pPageView->DrawPageViewGrid(*pSh->GetOut(), aPaintRect.SVRect(), SwViewOption::GetTextGridColor() );
3001 // #i68597#
3002 // moved paint post-process for DrawingLayer overlay here, see above
3004 pSh->DLPostPaint2(true);
3008 else if ( bBookMode && pSh->GetWin() && !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
3010 // paint empty page
3011 SwRect aPaintRect;
3012 SwRect aEmptyPageRect( pPage->Frm() );
3014 // code from vprint.cxx
3015 const SwPageFrm& rFormatPage = pPage->GetFormatPage();
3016 aEmptyPageRect.SSize() = rFormatPage.Frm().SSize();
3018 SwPageFrm::GetBorderAndShadowBoundRect( aEmptyPageRect, pSh, aPaintRect, bRightSidebar );
3019 aPaintRect._Intersection( aRect );
3021 if ( aRect.IsOver( aEmptyPageRect ) )
3023 // #i75172# if called from ViewShell::ImplEndAction it sould no longer
3024 // really be used but handled by ViewShell::ImplEndAction already
3026 const Region aDLRegion(aPaintRect.SVRect());
3027 pSh->DLPrePaint2(aDLRegion);
3030 if( pSh->GetOut()->GetFillColor() != aGlobalRetoucheColor )
3031 pSh->GetOut()->SetFillColor( aGlobalRetoucheColor );
3033 pSh->GetOut()->SetLineColor(); // OD 20.02.2003 #107369# - no line color
3034 // OD 20.02.2003 #107369# - use aligned page rectangle
3036 SwRect aTmpPageRect( aEmptyPageRect );
3037 ::SwAlignRect( aTmpPageRect, pSh );
3038 aEmptyPageRect = aTmpPageRect;
3041 pSh->GetOut()->DrawRect( aEmptyPageRect.SVRect() );
3043 // paint empty page text
3044 const Font& rEmptyPageFont = SwPageFrm::GetEmptyPageFont();
3045 const Font aOldFont( pSh->GetOut()->GetFont() );
3047 pSh->GetOut()->SetFont( rEmptyPageFont );
3048 pSh->GetOut()->DrawText( aEmptyPageRect.SVRect(), SW_RESSTR( STR_EMPTYPAGE ),
3049 TEXT_DRAW_VCENTER |
3050 TEXT_DRAW_CENTER |
3051 TEXT_DRAW_CLIP );
3053 pSh->GetOut()->SetFont( aOldFont );
3054 // paint shadow and border for empty page
3055 // OD 19.02.2003 #107369# - use new method to paint page border and
3056 // shadow
3057 SwPageFrm::PaintBorderAndShadow( aEmptyPageRect, pSh, bPaintRightShadow, bRightSidebar );
3058 SwPageFrm::PaintNotesSidebar( aEmptyPageRect, pSh, pPage->GetPhyPageNum(), bRightSidebar);
3061 pSh->DLPostPaint2(true);
3066 ASSERT( !pPage->GetNext() || pPage->GetNext()->IsPageFrm(),
3067 "Nachbar von Seite keine Seite." );
3068 pPage = (SwPageFrm*)pPage->GetNext();
3071 DELETEZ( pLines );
3073 #ifdef FRANK_TEST
3074 if ( pSh->GetWin() )
3076 Rectangle aRect( aFrm.SVRect() );
3077 pSh->GetWin()->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
3078 pSh->GetWin()->SetFillColor();
3079 pSh->GetWin()->SetLineColor( COL_LIGHTRED );
3080 pSh->GetWin()->DrawRect( aRect );
3081 pSh->GetWin()->Pop();
3083 #endif
3085 if ( bResetRootPaint )
3086 SwRootFrm::bInPaint = FALSE;
3087 if ( pStatics )
3088 delete pStatics;
3089 else
3091 pProgress = 0;
3092 pGlobalShell = 0;
3095 ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction );
3098 #ifdef LONG_TABLE_HACK
3100 /*************************************************************************
3102 |* SwRootFrm::HackPrepareLongTblPaint()
3104 |* Ersterstellung MA 27. Sep. 96
3105 |* Letzte Aenderung MA 18. Nov. 97
3107 |*************************************************************************/
3109 void SwRootFrm::HackPrepareLongTblPaint( int nMode )
3111 switch ( nMode )
3113 case HACK_TABLEMODE_INIT : ASSERT( !pLines, "HackPrepare: already prepared" );
3114 pLines = new SwLineRects;
3115 ASSERT( !pGlobalShell, "old GlobalShell lost" );
3116 pGlobalShell = GetShell();
3117 bTableHack = TRUE;
3118 break;
3119 case HACK_TABLEMODE_LOCKLINES : pLines->LockLines( TRUE ); break;
3120 case HACK_TABLEMODE_PAINTLINES : pLines->PaintLines( GetShell()->GetOut() );
3121 break;
3122 case HACK_TABLEMODE_UNLOCKLINES: pLines->LockLines( FALSE ); break;
3123 case HACK_TABLEMODE_EXIT : pLines->PaintLines( GetShell()->GetOut() );
3124 DELETEZ( pLines );
3125 pGlobalShell = 0;
3126 bTableHack = FALSE;
3127 break;
3131 #endif
3134 /*************************************************************************
3136 |* SwLayoutFrm::Paint()
3138 |* Ersterstellung MA 19. May. 92
3139 |* Letzte Aenderung MA 19. Apr. 95
3141 |*************************************************************************/
3143 void MA_FASTCALL lcl_EmergencyFormatFtnCont( SwFtnContFrm *pCont )
3145 //Es kann sein, dass der Cont vernichtet wird.
3146 SwCntntFrm *pCnt = pCont->ContainsCntnt();
3147 while ( pCnt && pCnt->IsInFtn() )
3149 pCnt->Calc();
3150 pCnt = pCnt->GetNextCntntFrm();
3154 class SwShortCut
3156 SwRectDist fnCheck;
3157 long nLimit;
3158 public:
3159 SwShortCut( const SwFrm& rFrm, const SwRect& rRect );
3160 BOOL Stop( const SwRect& rRect ) const
3161 { return (rRect.*fnCheck)( nLimit ) > 0; }
3164 SwShortCut::SwShortCut( const SwFrm& rFrm, const SwRect& rRect )
3166 BOOL bVert = rFrm.IsVertical();
3167 BOOL bR2L = rFrm.IsRightToLeft();
3168 if( rFrm.IsNeighbourFrm() && bVert == bR2L )
3170 if( bVert )
3172 fnCheck = &SwRect::GetBottomDistance;
3173 nLimit = rRect.Top();
3175 else
3177 fnCheck = &SwRect::GetLeftDistance;
3178 nLimit = rRect.Left() + rRect.Width();
3181 else if( bVert == rFrm.IsNeighbourFrm() )
3183 fnCheck = &SwRect::GetTopDistance;
3184 nLimit = rRect.Top() + rRect.Height();
3186 else
3188 fnCheck = &SwRect::GetRightDistance;
3189 nLimit = rRect.Left();
3193 void SwLayoutFrm::Paint( const SwRect& rRect ) const
3195 ViewShell *pSh = GetShell();
3197 // --> FME 2004-06-24 #i16816# tagged pdf support
3198 Frm_Info aFrmInfo( *this );
3199 SwTaggedPDFHelper aTaggedPDFHelper( 0, &aFrmInfo, 0, *pSh->GetOut() );
3200 // <--
3202 const SwFrm *pFrm = Lower();
3203 if ( !pFrm )
3204 return;
3206 SwShortCut aShortCut( *pFrm, rRect );
3207 BOOL bCnt;
3208 if ( TRUE == (bCnt = pFrm->IsCntntFrm()) )
3209 pFrm->Calc();
3211 if ( pFrm->IsFtnContFrm() )
3213 ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm );
3214 pFrm = Lower();
3217 const SwPageFrm *pPage = 0;
3218 const BOOL bWin = pGlobalShell->GetWin() ? TRUE : FALSE;
3220 while ( IsAnLower( pFrm ) )
3222 SwRect aPaintRect( pFrm->PaintArea() );
3223 if( aShortCut.Stop( aPaintRect ) )
3224 break;
3225 if ( bCnt && pProgress )
3226 pProgress->Reschedule();
3228 //Wenn ein Frm es explizit will muss retouchiert werden.
3229 //Erst die Retouche, denn selbige koennte die aligned'en Raender
3230 //plaetten.
3231 if ( pFrm->IsRetouche() )
3233 if ( pFrm->IsRetoucheFrm() && bWin && !pFrm->GetNext() )
3234 { if ( !pPage )
3235 pPage = FindPageFrm();
3236 pFrm->Retouche( pPage, rRect );
3238 pFrm->ResetRetouche();
3241 if ( rRect.IsOver( aPaintRect ) )
3243 if ( bCnt && pFrm->IsCompletePaint() &&
3244 !rRect.IsInside( aPaintRect ) && GetpApp()->AnyInput( INPUT_KEYBOARD ) )
3246 //fix(8104): Es kann vorkommen, dass die Verarbeitung nicht
3247 //vollstaendig war, aber trotzdem Teile des Absatzes gepaintet
3248 //werden. In der Folge werden dann evtl. wiederum andere Teile
3249 //des Absatzes garnicht mehr gepaintet. Einziger Ausweg scheint
3250 //hier ein Invalidieren der Windows zu sein.
3251 //Um es nicht alzu Heftig werden zu lassen versuche ich hier
3252 //das Rechteck zu begrenzen indem der gewuenschte Teil gepaintet
3253 //und nur die uebrigen Absatzanteile invalidiert werden.
3254 if ( aPaintRect.Left() == rRect.Left() &&
3255 aPaintRect.Right() == rRect.Right() )
3257 aPaintRect.Bottom( rRect.Top() - 1 );
3258 if ( aPaintRect.Height() > 0 )
3259 pGlobalShell->InvalidateWindows(aPaintRect);
3260 aPaintRect.Top( rRect.Bottom() + 1 );
3261 aPaintRect.Bottom( pFrm->Frm().Bottom() );
3262 if ( aPaintRect.Height() > 0 )
3263 pGlobalShell->InvalidateWindows(aPaintRect);
3264 aPaintRect.Top( pFrm->Frm().Top() );
3265 aPaintRect.Bottom( pFrm->Frm().Bottom() );
3267 else
3269 pGlobalShell->InvalidateWindows( aPaintRect );
3270 pFrm = pFrm->GetNext();
3271 if ( pFrm && (TRUE == (bCnt = pFrm->IsCntntFrm())) )
3272 pFrm->Calc();
3273 continue;
3276 pFrm->ResetCompletePaint();
3277 aPaintRect._Intersection( rRect );
3279 pFrm->Paint( aPaintRect );
3281 if ( Lower() && Lower()->IsColumnFrm() )
3283 //Ggf. die Spaltentrennlinien malen. Fuer den Seitenbody ist
3284 //nicht der Upper sondern die Seite Zustaendig.
3285 const SwFrmFmt *pFmt = GetUpper() && GetUpper()->IsPageFrm()
3286 ? GetUpper()->GetFmt()
3287 : GetFmt();
3288 const SwFmtCol &rCol = pFmt->GetCol();
3289 if ( rCol.GetLineAdj() != COLADJ_NONE )
3291 if ( !pPage )
3292 pPage = pFrm->FindPageFrm();
3294 PaintColLines( aPaintRect, rCol, pPage );
3298 if ( !bCnt && pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() )
3299 ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm->GetNext() );
3301 pFrm = pFrm->GetNext();
3302 if ( pFrm && (TRUE == (bCnt = pFrm->IsCntntFrm())) )
3303 pFrm->Calc();
3308 /** FlyFrm::IsBackgroundTransparent - for feature #99657#
3310 OD 12.08.2002
3311 determines, if background of fly frame has to be drawn transparent
3312 declaration found in /core/inc/flyfrm.cxx
3313 OD 08.10.2002 #103898# - If the background of the fly frame itself is not
3314 transparent and the background is inherited from its parent/grandparent,
3315 the background brush, used for drawing, has to be investigated for transparency.
3317 @author OD
3319 @return true, if background is transparent drawn.
3321 sal_Bool SwFlyFrm::IsBackgroundTransparent() const
3323 sal_Bool bBackgroundTransparent = GetFmt()->IsBackgroundTransparent();
3324 if ( !bBackgroundTransparent &&
3325 static_cast<const SwFlyFrmFmt*>(GetFmt())->IsBackgroundBrushInherited() )
3327 const SvxBrushItem* pBackgrdBrush = 0;
3328 const Color* pSectionTOXColor = 0;
3329 SwRect aDummyRect;
3330 if ( GetBackgroundBrush( pBackgrdBrush, pSectionTOXColor, aDummyRect, false) )
3332 if ( pSectionTOXColor &&
3333 (pSectionTOXColor->GetTransparency() != 0) &&
3334 (pSectionTOXColor->GetColor() != COL_TRANSPARENT) )
3336 bBackgroundTransparent = sal_True;
3338 else if ( pBackgrdBrush )
3340 if ( (pBackgrdBrush->GetColor().GetTransparency() != 0) &&
3341 (pBackgrdBrush->GetColor() != COL_TRANSPARENT) )
3343 bBackgroundTransparent = sal_True;
3345 else
3347 const GraphicObject *pTmpGrf =
3348 static_cast<const GraphicObject*>(pBackgrdBrush->GetGraphicObject());
3349 if ( (pTmpGrf) &&
3350 (pTmpGrf->GetAttr().GetTransparency() != 0)
3353 bBackgroundTransparent = sal_True;
3360 return bBackgroundTransparent;
3363 /** FlyFrm::IsShadowTransparent - for feature #99657#
3365 OD 13.08.2002
3366 determine, if shadow color of fly frame has to be drawn transparent
3367 declaration found in /core/inc/flyfrm.cxx
3369 @author OD
3371 @return true, if shadow color is transparent.
3373 sal_Bool SwFlyFrm::IsShadowTransparent() const
3375 return GetFmt()->IsShadowTransparent();
3378 /*************************************************************************
3380 |* SwFlyFrm::IsPaint()
3382 |* Ersterstellung MA 16. Jan. 97
3383 |* Letzte Aenderung MA 16. Jan. 97
3385 |*************************************************************************/
3387 BOOL SwFlyFrm::IsPaint( SdrObject *pObj, const ViewShell *pSh )
3389 SdrObjUserCall *pUserCall;
3391 if ( 0 == ( pUserCall = GetUserCall(pObj) ) )
3392 return TRUE;
3394 //Attributabhaengig nicht fuer Drucker oder PreView painten
3395 BOOL bPaint = pFlyOnlyDraw ||
3396 ((SwContact*)pUserCall)->GetFmt()->GetPrint().GetValue();
3397 if ( !bPaint )
3398 bPaint = pSh->GetWin() && !pSh->IsPreView();
3400 if ( bPaint )
3402 //Das Paint kann evtl. von von uebergeordneten Flys verhindert werden.
3403 SwFrm *pAnch = 0;
3404 if ( pObj->ISA(SwVirtFlyDrawObj) )
3406 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
3407 if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly )
3408 return TRUE;
3410 //Die Anzeige eines Zwischenstadiums vermeiden, Flys die nicht mit
3411 //der Seite auf der sie verankert sind ueberlappen werden auch
3412 //nicht gepaintet.
3413 //HACK: Ausnahme: Drucken von Rahmen in Tabellen, diese koennen
3414 //bei uebergrossen Tabellen (HTML) schon mal auserhalb der Seite
3415 //stehen.
3416 SwPageFrm *pPage = pFly->FindPageFrm();
3417 if ( pPage )
3419 if ( pPage->Frm().IsOver( pFly->Frm() ) )
3420 pAnch = pFly->AnchorFrm();
3421 else if ( bTableHack &&
3422 pFly->Frm().Top() >= pFly->GetAnchorFrm()->Frm().Top() &&
3423 pFly->Frm().Top() < pFly->GetAnchorFrm()->Frm().Bottom() &&
3424 long(pSh->GetOut()) ==
3425 long(pSh->getIDocumentDeviceAccess()->getPrinter( false ) ) )
3427 pAnch = pFly->AnchorFrm();
3432 else
3434 // OD 13.10.2003 #i19919# - consider 'virtual' drawing objects
3435 // OD 2004-03-29 #i26791#
3436 pAnch = ((SwDrawContact*)pUserCall)->GetAnchorFrm( pObj );
3437 if ( pAnch )
3439 if ( !pAnch->GetValidPosFlag() )
3440 pAnch = 0;
3441 else if ( long(pSh->GetOut()) == long(pSh->getIDocumentDeviceAccess()->getPrinter( false )))
3443 //HACK: fuer das Drucken muessen wir ein paar Objekte
3444 //weglassen, da diese sonst doppelt gedruckt werden.
3445 //Die Objekte sollen gedruckt werden, wenn der TableHack
3446 //gerade greift. In der Folge duerfen sie nicht gedruckt werden
3447 //wenn sie mit der Seite dran sind, ueber der sie von der
3448 //Position her gerade schweben.
3449 const SwPageFrm *pPage = pAnch->FindPageFrm();
3450 if ( !bTableHack &&
3451 !pPage->Frm().IsOver( pObj->GetCurrentBoundRect() ) )
3452 pAnch = 0;
3455 else
3457 // OD 02.07.2003 #108784# - debug assert
3458 if ( !pObj->ISA(SdrObjGroup) )
3460 ASSERT( false, "<SwFlyFrm::IsPaint(..)> - paint of drawing object without anchor frame!?" );
3464 if ( pAnch )
3466 if ( pAnch->IsInFly() )
3467 bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(),
3468 pSh );
3469 else if ( pFlyOnlyDraw )
3470 bPaint = FALSE;
3472 else
3473 bPaint = FALSE;
3475 return bPaint;
3478 /*************************************************************************
3479 |* SwCellFrm::Paint( const SwRect& ) const
3480 |*************************************************************************/
3481 void SwCellFrm::Paint( const SwRect& rRect ) const
3483 if ( GetLayoutRowSpan() >= 1 )
3484 SwLayoutFrm::Paint( rRect );
3487 /*************************************************************************
3489 |* SwFlyFrm::Paint()
3491 |* Ersterstellung MA ??
3492 |* Letzte Aenderung MA 16. Jan. 97
3494 |*************************************************************************/
3496 //Weiter unten definiert
3497 void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay,
3498 const SwRect &rRect, const SwPageFrm *pPage );
3500 void SwFlyFrm::Paint( const SwRect& rRect ) const
3502 //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die
3503 //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben.
3504 //z.B. #33066#
3505 pLines->LockLines(TRUE);
3507 SwRect aRect( rRect );
3508 aRect._Intersection( Frm() );
3510 OutputDevice* pOut = pGlobalShell->GetOut();
3511 pOut->Push( PUSH_CLIPREGION );
3512 pOut->SetClipRegion();
3513 const SwPageFrm* pPage = FindPageFrm();
3515 const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm()
3516 ? (SwNoTxtFrm*)Lower() : 0;
3518 bool bIsChart = false; //#i102950# don't paint additional borders for charts
3519 //check whether we have a chart
3520 if(pNoTxt)
3522 const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode());
3523 if( pNoTNd )
3525 SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode());
3526 if( pOLENd && ChartPrettyPainter::IsChart( pOLENd->GetOLEObj().GetObject() ) )
3527 bIsChart = true;
3532 bool bContour = GetFmt()->GetSurround().IsContour();
3533 PolyPolygon aPoly;
3534 if ( bContour )
3536 // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True>
3537 // to indicate that method is called for paint in order to avoid
3538 // load of the intrinsic graphic.
3539 bContour = GetContour( aPoly, sal_True );
3542 // --> OD 2005-06-08 #i47804# - distinguish complete background paint
3543 // and margin paint.
3544 // paint complete background for Writer text fly frames
3545 bool bPaintCompleteBack( !pNoTxt );
3546 // <--
3547 // paint complete background for transparent graphic and contour,
3548 // if own background color exists.
3549 const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false;
3550 if ( !bPaintCompleteBack &&
3551 ( bIsGraphicTransparent|| bContour ) )
3553 const SvxBrushItem &rBack = GetFmt()->GetBackground();
3554 // OD 07.08.2002 #99657# #GetTransChg#
3555 // to determine, if background has to be painted, by checking, if
3556 // background color is not COL_TRANSPARENT ("no fill"/"auto fill")
3557 // or a background graphic exists.
3558 bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) ||
3559 rBack.GetGraphicPos() != GPOS_NONE;
3561 // paint of margin needed.
3562 const bool bPaintMarginOnly( !bPaintCompleteBack &&
3563 Prt().SSize() != Frm().SSize() );
3565 // --> OD 2005-06-08 #i47804# - paint background of parent fly frame
3566 // for transparent graphics in layer Hell, if parent fly frame isn't
3567 // in layer Hell. It's only painted the intersection between the
3568 // parent fly frame area and the paint area <aRect>
3569 const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
3571 if ( bIsGraphicTransparent &&
3572 GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() &&
3573 GetAnchorFrm()->FindFlyFrm() )
3575 const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm();
3576 if ( pParentFlyFrm->GetDrawObj()->GetLayer() !=
3577 pIDDMA->GetHellId() )
3579 SwFlyFrm* pOldRet = pRetoucheFly2;
3580 pRetoucheFly2 = const_cast<SwFlyFrm*>(this);
3582 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm );
3583 const SwBorderAttrs &rAttrs = *aAccess.Get();
3584 SwRect aPaintRect( aRect );
3585 aPaintRect._Intersection( pParentFlyFrm->Frm() );
3586 pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, FALSE, FALSE );
3588 pRetoucheFly2 = pOldRet;
3592 if ( bPaintCompleteBack || bPaintMarginOnly )
3594 //#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder
3595 //das orig. Rect bekommt, aber PaintBackground das begrenzte.
3597 // OD 2004-04-23 #116347#
3598 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
3599 pOut->SetLineColor();
3601 pPage = FindPageFrm();
3603 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3604 const SwBorderAttrs &rAttrs = *aAccess.Get();
3606 // OD 06.08.2002 #99657# - paint border before painting background
3607 // paint border
3609 SwRect aTmp( rRect );
3610 PaintBorder( aTmp, pPage, rAttrs );
3613 // paint background
3615 SwRegionRects aRegion( aRect );
3616 // --> OD 2007-12-13 #i80822#
3617 // suppress painting of background in printing area for
3618 // non-transparent graphics.
3619 // if ( bPaintMarginOnly )
3620 if ( bPaintMarginOnly ||
3621 ( pNoTxt && !bIsGraphicTransparent ) )
3622 // <--
3624 //Was wir eigentlich Painten wollen ist der schmale Streifen
3625 //zwischen PrtArea und aeusserer Umrandung.
3626 SwRect aTmp( Prt() ); aTmp += Frm().Pos();
3627 aRegion -= aTmp;
3629 if ( bContour )
3631 pOut->Push();
3632 // --> OD 2007-12-13 #i80822#
3633 // apply clip region under the same conditions, which are
3634 // used in <SwNoTxtFrm::Paint(..)> to set the clip region
3635 // for painting the graphic/OLE. Thus, the clip region is
3636 // also applied for the PDF export.
3637 // if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER )
3638 ViewShell *pSh = GetShell();
3639 if ( !pOut->GetConnectMetaFile() || !pSh->GetWin() )
3640 // <--
3642 pOut->SetClipRegion( aPoly );
3644 for ( USHORT i = 0; i < aRegion.Count(); ++i )
3645 PaintBackground( aRegion[i], pPage, rAttrs, FALSE, TRUE );
3646 pOut->Pop();
3648 else
3649 for ( USHORT i = 0; i < aRegion.Count(); ++i )
3650 PaintBackground( aRegion[i], pPage, rAttrs, FALSE, TRUE );
3653 pOut->Pop();
3657 // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and
3658 // the subsidiary lines of its lowers on its own, due to overlapping with
3659 // other fly frames or other objects.
3660 if( pGlobalShell->GetWin()
3661 && !bIsChart ) //#i102950# don't paint additional borders for charts
3663 bool bSubsLineRectsCreated;
3664 if ( pSubsLines )
3666 // Lock already existing subsidiary lines
3667 pSubsLines->LockLines( TRUE );
3668 bSubsLineRectsCreated = false;
3670 else
3672 // create new subsidiardy lines
3673 pSubsLines = new SwSubsRects;
3674 bSubsLineRectsCreated = true;
3677 bool bSpecSubsLineRectsCreated;
3678 if ( pSpecSubsLines )
3680 // Lock already existing special subsidiary lines
3681 pSpecSubsLines->LockLines( TRUE );
3682 bSpecSubsLineRectsCreated = false;
3684 else
3686 // create new special subsidiardy lines
3687 pSpecSubsLines = new SwSubsRects;
3688 bSpecSubsLineRectsCreated = true;
3690 // Add subsidiary lines of fly frame and its lowers
3691 RefreshLaySubsidiary( pPage, aRect );
3692 // paint subsidiary lines of fly frame and its lowers
3693 pSpecSubsLines->PaintSubsidiary( pOut, NULL );
3694 pSubsLines->PaintSubsidiary( pOut, pLines );
3695 if ( !bSubsLineRectsCreated )
3696 // unlock subsidiary lines
3697 pSubsLines->LockLines( FALSE );
3698 else
3699 // delete created subsidiary lines container
3700 DELETEZ( pSubsLines );
3702 if ( !bSpecSubsLineRectsCreated )
3703 // unlock special subsidiary lines
3704 pSpecSubsLines->LockLines( FALSE );
3705 else
3707 // delete created special subsidiary lines container
3708 DELETEZ( pSpecSubsLines );
3712 SwLayoutFrm::Paint( aRect );
3714 Validate();
3716 // OD 19.12.2002 #106318# - first paint lines added by fly frame paint
3717 // and then unlock other lines.
3718 pLines->PaintLines( pOut );
3719 pLines->LockLines( FALSE );
3721 pOut->Pop();
3723 if ( pProgress && pNoTxt )
3724 pProgress->Reschedule();
3726 /*************************************************************************
3728 |* SwTabFrm::Paint()
3730 |* Ersterstellung MA 11. May. 93
3731 |* Letzte Aenderung MA 23. Mar. 95
3733 |*************************************************************************/
3735 void SwTabFrm::Paint( const SwRect& rRect ) const
3737 if ( pGlobalShell->GetViewOptions()->IsTable() )
3739 // --> collapsing borders FME 2005-05-27 #i29550#
3740 if ( IsCollapsingBorders() )
3742 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3743 const SwBorderAttrs &rAttrs = *aAccess.Get();
3745 // paint shadow
3746 if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
3748 SwRect aRect;
3749 ::lcl_CalcBorderRect( aRect, this, rAttrs, TRUE );
3750 PaintShadow( rRect, aRect, rAttrs );
3753 // paint lines
3754 SwTabFrmPainter aHelper( *this );
3755 aHelper.PaintLines( *pGlobalShell->GetOut(), rRect );
3757 // <-- collapsing
3759 SwLayoutFrm::Paint( rRect );
3761 // OD 10.01.2003 #i6467# - no light grey rectangle for page preview
3762 else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() )
3764 // OD 10.01.2003 #i6467# - intersect output rectangle with table frame
3765 SwRect aTabRect( Prt() );
3766 aTabRect.Pos() += Frm().Pos();
3767 SwRect aTabOutRect( rRect );
3768 aTabOutRect.Intersection( aTabRect );
3769 pGlobalShell->GetViewOptions()->
3770 DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY );
3772 ((SwTabFrm*)this)->ResetComplete();
3775 /*************************************************************************
3777 |* SwFrm::PaintShadow()
3779 |* Beschreibung Malt einen Schatten wenns das FrmFormat fordert.
3780 |* Der Schatten wird immer an den auesseren Rand des OutRect gemalt.
3781 |* Das OutRect wird ggf. so verkleinert, dass auf diesem das
3782 |* malen der Umrandung stattfinden kann.
3783 |* Ersterstellung MA 21. Dec. 92
3784 |* Letzte Aenderung MA 29. May. 97
3786 |*************************************************************************/
3787 /// OD 23.08.2002 #99657#
3788 /// draw full shadow rectangle for frames with transparent drawn backgrounds.
3789 void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
3790 const SwBorderAttrs &rAttrs ) const
3792 const SvxShadowItem &rShadow = rAttrs.GetShadow();
3793 const long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth() );
3794 const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() );
3796 SwRects aRegion( 2, 2 );
3797 SwRect aOut( rOutRect );
3799 const BOOL bCnt = IsCntntFrm();
3800 const BOOL bTop = !bCnt || rAttrs.GetTopLine ( *(this) ) ? TRUE : FALSE;
3801 const BOOL bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? TRUE : FALSE;
3803 SvxShadowLocation eLoc = rShadow.GetLocation();
3805 SWRECTFN( this )
3806 if( IsVertical() )
3808 switch( eLoc )
3810 case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
3811 case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
3812 case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
3813 case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_TOPLEFT; break;
3814 default: break;
3818 /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to
3819 /// be drawn or only two shadow rectangles beside the frame.
3820 /// draw full shadow rectangle, if frame background is drawn transparent.
3821 /// Status Quo:
3822 /// SwLayoutFrm can have transparent drawn backgrounds. Thus,
3823 /// "asked" their frame format.
3824 sal_Bool bDrawFullShadowRectangle =
3825 ( IsLayoutFrm() &&
3826 (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent()
3828 switch ( eLoc )
3830 case SVX_SHADOW_BOTTOMRIGHT:
3832 if ( bDrawFullShadowRectangle )
3834 /// OD 06.08.2002 #99657# - draw full shadow rectangle
3835 aOut.Top( aOut.Top() + nHeight );
3836 aOut.Left( aOut.Left() + nWidth );
3837 aRegion.Insert( aOut, aRegion.Count() );
3839 else
3841 aOut.Top ( aOut.Bottom() - nHeight );
3842 aOut.Left( aOut.Left() + nWidth );
3843 if ( bBottom )
3844 aRegion.Insert( aOut, aRegion.Count() );
3845 aOut.Left( aOut.Right() - nWidth );
3846 aOut.Top ( rOutRect.Top() + nHeight );
3847 if ( bBottom )
3848 aOut.Bottom( aOut.Bottom() - nHeight );
3849 if ( bCnt && (!bTop || !bBottom) )
3850 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3851 aRegion.Insert( aOut, aRegion.Count() );
3854 rOutRect.Right ( rOutRect.Right() - nWidth );
3855 rOutRect.Bottom( rOutRect.Bottom()- nHeight );
3857 break;
3858 case SVX_SHADOW_TOPLEFT:
3860 if ( bDrawFullShadowRectangle )
3862 /// OD 06.08.2002 #99657# - draw full shadow rectangle
3863 aOut.Bottom( aOut.Bottom() - nHeight );
3864 aOut.Right( aOut.Right() - nWidth );
3865 aRegion.Insert( aOut, aRegion.Count() );
3867 else
3869 aOut.Bottom( aOut.Top() + nHeight );
3870 aOut.Right ( aOut.Right() - nWidth );
3871 if ( bTop )
3872 aRegion.Insert( aOut, aRegion.Count() );
3873 aOut.Right ( aOut.Left() + nWidth );
3874 aOut.Bottom( rOutRect.Bottom() - nHeight );
3875 if ( bTop )
3876 aOut.Top( aOut.Top() + nHeight );
3877 if ( bCnt && (!bBottom || !bTop) )
3878 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3879 aRegion.Insert( aOut, aRegion.Count() );
3882 rOutRect.Left( rOutRect.Left() + nWidth );
3883 rOutRect.Top( rOutRect.Top() + nHeight );
3885 break;
3886 case SVX_SHADOW_TOPRIGHT:
3888 if ( bDrawFullShadowRectangle )
3890 /// OD 06.08.2002 #99657# - draw full shadow rectangle
3891 aOut.Bottom( aOut.Bottom() - nHeight);
3892 aOut.Left( aOut.Left() + nWidth );
3893 aRegion.Insert( aOut, aRegion.Count() );
3895 else
3897 aOut.Bottom( aOut.Top() + nHeight );
3898 aOut.Left ( aOut.Left()+ nWidth );
3899 if ( bTop )
3900 aRegion.Insert( aOut, aRegion.Count() );
3901 aOut.Left ( aOut.Right() - nWidth );
3902 aOut.Bottom( rOutRect.Bottom() - nHeight );
3903 if ( bTop )
3904 aOut.Top( aOut.Top() + nHeight );
3905 if ( bCnt && (!bBottom || bTop) )
3906 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3907 aRegion.Insert( aOut, aRegion.Count() );
3910 rOutRect.Right( rOutRect.Right() - nWidth );
3911 rOutRect.Top( rOutRect.Top() + nHeight );
3913 break;
3914 case SVX_SHADOW_BOTTOMLEFT:
3916 if ( bDrawFullShadowRectangle )
3918 /// OD 06.08.2002 #99657# - draw full shadow rectangle
3919 aOut.Top( aOut.Top() + nHeight );
3920 aOut.Right( aOut.Right() - nWidth );
3921 aRegion.Insert( aOut, aRegion.Count() );
3923 else
3925 aOut.Top ( aOut.Bottom()- nHeight );
3926 aOut.Right( aOut.Right() - nWidth );
3927 if ( bBottom )
3928 aRegion.Insert( aOut, aRegion.Count() );
3929 aOut.Right( aOut.Left() + nWidth );
3930 aOut.Top( rOutRect.Top() + nHeight );
3931 if ( bBottom )
3932 aOut.Bottom( aOut.Bottom() - nHeight );
3933 if ( bCnt && (!bTop || !bBottom) )
3934 ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3935 aRegion.Insert( aOut, aRegion.Count() );
3938 rOutRect.Left( rOutRect.Left() + nWidth );
3939 rOutRect.Bottom( rOutRect.Bottom() - nHeight );
3941 break;
3942 default:
3943 ASSERT( !this, "new ShadowLocation() ?" )
3944 break;
3947 OutputDevice *pOut = pGlobalShell->GetOut();
3949 ULONG nOldDrawMode = pOut->GetDrawMode();
3950 Color aShadowColor( rShadow.GetColor() );
3951 if( aRegion.Count() && pGlobalShell->GetWin() &&
3952 Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
3954 // Is heigh contrast mode, the output device has already set the
3955 // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function
3956 // to ignore the setting of a new color. Therefore we have to reset
3957 // the drawing mode
3958 pOut->SetDrawMode( 0 );
3959 aShadowColor = SwViewOption::GetFontColor();
3962 if ( pOut->GetFillColor() != aShadowColor )
3963 pOut->SetFillColor( aShadowColor );
3965 pOut->SetDrawMode( nOldDrawMode );
3967 for ( USHORT i = 0; i < aRegion.Count(); ++i )
3969 SwRect &rOut = aRegion[i];
3970 aOut = rOut;
3971 // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle
3972 // no alignment necessary, because (1) <rRect> is already aligned
3973 // and because (2) paint of border and background will occur later.
3974 // Thus, (1) assures that no conflicts with neighbour object will occure
3975 // and (2) assures that border and background is not affected by the
3976 // shadow paint.
3978 ::SwAlignRect( aOut, pGlobalShell );
3980 if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
3982 aOut._Intersection( rRect );
3983 pOut->DrawRect( aOut.SVRect() );
3988 /*************************************************************************
3990 |* SwFrm::PaintBorderLine()
3992 |* Ersterstellung MA 22. Dec. 92
3993 |* Letzte Aenderung MA 22. Jan. 95
3995 |*************************************************************************/
3997 void SwFrm::PaintBorderLine( const SwRect& rRect,
3998 const SwRect& rOutRect,
3999 const SwPageFrm *pPage,
4000 const Color *pColor ) const
4002 if ( !rOutRect.IsOver( rRect ) )
4003 return;
4005 SwRect aOut( rOutRect );
4006 aOut._Intersection( rRect );
4008 const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0;
4009 BYTE nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB :
4010 ( IsInSct() ? SUBCOL_SECT :
4011 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
4012 if( pColor && pGlobalShell->GetWin() &&
4013 Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4015 pColor = &SwViewOption::GetFontColor();
4018 if ( pPage->GetSortedObjs() )
4020 SwRegionRects aRegion( aOut, 4, 1 );
4021 ::lcl_SubtractFlys( this, pPage, aOut, aRegion );
4022 for ( USHORT i = 0; i < aRegion.Count(); ++i )
4023 pLines->AddLineRect( aRegion[i], pColor, pTab, nSubCol );
4025 else
4026 pLines->AddLineRect( aOut, pColor, pTab, nSubCol );
4029 /*************************************************************************
4031 |* SwFrm::PaintBorderLines()
4033 |* Beschreibung Nur alle Linien einfach oder alle Linien doppelt!!!!
4034 |* Ersterstellung MA 22. Dec. 92
4035 |* Letzte Aenderung MA 22. Mar. 95
4037 |*************************************************************************/
4039 // OD 29.04.2003 #107169# - method called for left and right border rectangles.
4040 // For a printer output device perform adjustment for non-overlapping top and
4041 // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate
4042 // printer output device.
4043 // NOTE: For printer output device left/right border rectangle <_iorRect>
4044 // has to be already non-overlapping the outer top/bottom border rectangle.
4045 void MA_FASTCALL lcl_SubTopBottom( SwRect& _iorRect,
4046 const SvxBoxItem& _rBox,
4047 const SwBorderAttrs& _rAttrs,
4048 const SwFrm& _rFrm,
4049 const SwRectFn& _rRectFn,
4050 const sal_Bool _bPrtOutputDev )
4052 const BOOL bCnt = _rFrm.IsCntntFrm();
4053 if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() &&
4054 ( !bCnt || _rAttrs.GetTopLine( _rFrm ) )
4057 // substract distance between outer and inner line.
4058 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() );
4059 // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4060 // adjust x-/y-position, if inner top line is a hair line (width = 1)
4061 sal_Bool bIsInnerTopLineHairline = sal_False;
4062 if ( !_bPrtOutputDev )
4064 // additionally substract width of top outer line
4065 // --> left/right inner/outer line doesn't overlap top outer line.
4066 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() );
4068 else
4070 // OD 29.04.2003 #107169# - additionally substract width of top inner line
4071 // --> left/right inner/outer line doesn't overlap top inner line.
4072 nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() );
4073 bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1;
4075 (_iorRect.*_rRectFn->fnSubTop)( -nDist );
4076 // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line
4077 // is a hair line
4078 if ( bIsInnerTopLineHairline )
4080 if ( _rFrm.IsVertical() )
4082 // right of border rectangle has to be checked and adjusted
4083 Point aCompPt( _iorRect.Right(), 0 );
4084 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4085 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4086 aRefPt, aCompPt,
4087 sal_True, -1 );
4088 _iorRect.Right( aCompPt.X() );
4090 else
4092 // top of border rectangle has to be checked and adjusted
4093 Point aCompPt( 0, _iorRect.Top() );
4094 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4095 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4096 aRefPt, aCompPt,
4097 sal_False, +1 );
4098 _iorRect.Top( aCompPt.Y() );
4103 if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() &&
4104 ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) )
4107 // substract distance between outer and inner line.
4108 SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() );
4109 // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4110 // adjust x-/y-position, if inner bottom line is a hair line (width = 1)
4111 sal_Bool bIsInnerBottomLineHairline = sal_False;
4112 if ( !_bPrtOutputDev )
4114 // additionally substract width of bottom outer line
4115 // --> left/right inner/outer line doesn't overlap bottom outer line.
4116 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() );
4118 else
4120 // OD 29.04.2003 #107169# - additionally substract width of bottom inner line
4121 // --> left/right inner/outer line doesn't overlap bottom inner line.
4122 nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() );
4123 bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1;
4125 (_iorRect.*_rRectFn->fnAddBottom)( -nDist );
4126 // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner
4127 // bottom line is a hair line.
4128 if ( bIsInnerBottomLineHairline )
4130 if ( _rFrm.IsVertical() )
4132 // left of border rectangle has to be checked and adjusted
4133 Point aCompPt( _iorRect.Left(), 0 );
4134 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4135 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4136 aRefPt, aCompPt,
4137 sal_True, +1 );
4138 _iorRect.Left( aCompPt.X() );
4140 else
4142 // bottom of border rectangle has to be checked and adjusted
4143 Point aCompPt( 0, _iorRect.Bottom() );
4144 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4145 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4146 aRefPt, aCompPt,
4147 sal_False, -1 );
4148 _iorRect.Bottom( aCompPt.Y() );
4154 // method called for top and bottom border rectangles.
4155 void MA_FASTCALL lcl_SubLeftRight( SwRect& rRect,
4156 const SvxBoxItem& rBox,
4157 const SwRectFn& rRectFn )
4159 if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() )
4161 const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() )
4162 + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() );
4163 (rRect.*rRectFn->fnSubLeft)( -nDist );
4166 if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() )
4168 const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() )
4169 + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() );
4170 (rRect.*rRectFn->fnAddRight)( -nDist );
4174 // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine>
4175 // into new method <lcl_PaintLeftRightLine(..)>
4176 void lcl_PaintLeftRightLine( const sal_Bool _bLeft,
4177 const SwFrm& _rFrm,
4178 const SwPageFrm& _rPage,
4179 const SwRect& _rOutRect,
4180 const SwRect& _rRect,
4181 const SwBorderAttrs& _rAttrs,
4182 const SwRectFn& _rRectFn )
4184 const SvxBoxItem& rBox = _rAttrs.GetBox();
4185 const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft();
4186 const SvxBorderLine* pLeftRightBorder = 0;
4187 if ( _bLeft )
4189 pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft();
4191 else
4193 pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight();
4195 // OD 06.05.2003 #107169# - init boolean indicating printer output device.
4196 const sal_Bool bPrtOutputDev =
4197 ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() );
4199 if ( !pLeftRightBorder )
4201 return;
4204 SwRect aRect( _rOutRect );
4205 if ( _bLeft )
4207 (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4208 (aRect.*_rRectFn->fnGetWidth)() );
4210 else
4212 (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4213 (aRect.*_rRectFn->fnGetWidth)() );
4216 const BOOL bCnt = _rFrm.IsCntntFrm();
4218 if ( bCnt )
4220 ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn );
4223 // OD 06.05.2003 #107169# - adjustments for printer output device
4224 if ( bPrtOutputDev )
4226 // substract width of outer top line.
4227 if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) )
4229 long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() );
4230 (aRect.*_rRectFn->fnSubTop)( -nDist );
4231 // OD 19.05.2003 #109667# - If outer top line is hair line, calculated
4232 // top has to be adjusted.
4233 if ( nDist == 1 )
4235 if ( _rFrm.IsVertical() )
4237 // right of border rectangle has to be checked and adjusted
4238 Point aCompPt( aRect.Right(), 0 );
4239 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4240 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4241 aRefPt, aCompPt,
4242 sal_True, -1 );
4243 aRect.Right( aCompPt.X() );
4245 else
4247 // top of border rectangle has to be checked and adjusted
4248 Point aCompPt( 0, aRect.Top() );
4249 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4250 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4251 aRefPt, aCompPt,
4252 sal_False, +1 );
4253 aRect.Top( aCompPt.Y() );
4257 // substract width of outer bottom line.
4258 if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) )
4260 long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth());
4261 (aRect.*_rRectFn->fnAddBottom)( -nDist );
4262 // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated
4263 // top has to be adjusted.
4264 if ( nDist == 1 )
4266 if ( _rFrm.IsVertical() )
4268 // left of border rectangle has to be checked and adjusted
4269 Point aCompPt( aRect.Left(), 0 );
4270 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4271 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4272 aRefPt, aCompPt,
4273 sal_True, +1 );
4274 aRect.Left( aCompPt.X() );
4276 else
4278 // bottom of border rectangle has to be checked and adjusted
4279 Point aCompPt( 0, aRect.Bottom() );
4280 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4281 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4282 aRefPt, aCompPt,
4283 sal_False, -1 );
4284 aRect.Bottom( aCompPt.Y() );
4290 if ( !pLeftRightBorder->GetInWidth() )
4292 // OD 06.05.2003 #107169# - add 6th parameter
4293 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4296 // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4298 SwRect aPaintRect( aRect );
4299 ::SwAlignRect( aPaintRect, _rFrm.GetShell() );
4300 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4301 // to the prior left postion with width of one twip.
4302 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4304 if ( _bLeft )
4306 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4307 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4308 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4310 else
4312 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4313 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4314 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4317 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4320 if ( pLeftRightBorder->GetInWidth() )
4322 const long nDist = ::lcl_MinWidthDist( pLeftRightBorder->GetDistance() );
4323 long nWidth = ::lcl_AlignWidth( pLeftRightBorder->GetInWidth() );
4324 if ( _bLeft )
4326 (aRect.*_rRectFn->fnAddRight)( nDist + nWidth );
4327 (aRect.*_rRectFn->fnSubLeft)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4329 else
4331 (aRect.*_rRectFn->fnSubLeft)( nDist + nWidth );
4332 (aRect.*_rRectFn->fnAddRight)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4334 // OD 06.05.2003 #107169# - add 6th parameter
4335 ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4336 // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4338 SwRect aPaintRect( aRect );
4339 ::SwAlignRect( aPaintRect, _rFrm.GetShell() );
4340 // if <SwAlignRect> reveals rectangle with no width, adjust
4341 // rectangle to the prior left postion with width of one twip.
4342 if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4344 if ( _bLeft )
4346 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4347 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4348 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4350 else
4352 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4353 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4354 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4357 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4362 // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine>
4363 // into <lcl_PaintTopLine>
4364 void lcl_PaintTopBottomLine( const sal_Bool _bTop,
4365 const SwFrm& _rFrm,
4366 const SwPageFrm& _rPage,
4367 const SwRect& _rOutRect,
4368 const SwRect& _rRect,
4369 const SwBorderAttrs& _rAttrs,
4370 const SwRectFn& _rRectFn )
4372 const SvxBoxItem& rBox = _rAttrs.GetBox();
4373 const SvxBorderLine* pTopBottomBorder = 0;
4374 if ( _bTop )
4376 pTopBottomBorder = rBox.GetTop();
4378 else
4380 pTopBottomBorder = rBox.GetBottom();
4383 if ( !pTopBottomBorder )
4385 return;
4388 SwRect aRect( _rOutRect );
4389 if ( _bTop )
4391 (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4392 (aRect.*_rRectFn->fnGetHeight)() );
4394 else
4396 (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4397 (aRect.*_rRectFn->fnGetHeight)() );
4400 // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4402 SwRect aPaintRect( aRect );
4403 ::SwAlignRect( aPaintRect, _rFrm.GetShell() );
4404 // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4405 // to the prior top postion with width of one twip.
4406 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4408 if ( _bTop )
4410 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4411 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4412 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4414 else
4416 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4417 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4418 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4421 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4424 if ( pTopBottomBorder->GetInWidth() )
4426 const long nDist = ::lcl_MinHeightDist( pTopBottomBorder->GetDistance() );
4427 const long nHeight = ::lcl_AlignHeight( pTopBottomBorder->GetInWidth() );
4428 if ( _bTop )
4430 (aRect.*_rRectFn->fnAddBottom)( nDist + nHeight );
4431 (aRect.*_rRectFn->fnSubTop)( nHeight - (aRect.*_rRectFn->fnGetHeight)() );
4433 else
4435 (aRect.*_rRectFn->fnSubTop)( nDist + nHeight );
4436 (aRect.*_rRectFn->fnAddBottom)( nHeight -(aRect.*_rRectFn->fnGetHeight)() );
4438 ::lcl_SubLeftRight( aRect, rBox, _rRectFn );
4439 // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4441 SwRect aPaintRect( aRect );
4442 ::SwAlignRect( aPaintRect, _rFrm.GetShell() );
4443 // if <SwAlignRect> reveals rectangle with no width, adjust
4444 // rectangle to the prior top postion with width of one twip.
4445 if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4447 if ( _bTop )
4449 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4450 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4451 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4453 else
4455 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4456 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4457 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4460 _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4466 /*************************************************************************
4468 |* const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4470 |* No comment. #i15844#
4472 |*************************************************************************/
4474 const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4476 ASSERT( rFrm.IsCellFrm(),
4477 "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" )
4479 const SwFrm* pTmpFrm = &rFrm;
4482 if ( pTmpFrm->GetNext() )
4483 return pTmpFrm->GetNext();
4485 pTmpFrm = pTmpFrm->GetUpper()->GetUpper();
4487 while ( pTmpFrm->IsCellFrm() );
4489 return 0;
4493 /*************************************************************************
4495 |* SwFrm::PaintBorder()
4497 |* Beschreibung Malt Schatten und Umrandung
4498 |* Ersterstellung MA 23.01.92
4499 |* Letzte Aenderung MA 29. Jul. 96
4501 |*************************************************************************/
4503 /** local method to determine cell frame, from which the border attributes
4504 for paint of top/bottom border has to be used.
4506 OD 21.02.2003 #b4779636#, #107692#
4508 @author OD
4511 @param _pCellFrm
4512 input parameter - constant pointer to cell frame for which the cell frame
4513 for the border attributes has to be determined.
4515 @param _rCellBorderAttrs
4516 input parameter - constant reference to the border attributes of cell frame
4517 <_pCellFrm>.
4519 @param _bTop
4520 input parameter - boolean, that controls, if cell frame for top border or
4521 for bottom border has to be determined.
4523 @return constant pointer to cell frame, for which the border attributes has
4524 to be used
4526 const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm* _pCellFrm,
4527 const SwBorderAttrs& _rCellBorderAttrs,
4528 const bool _bTop )
4530 ASSERT( _pCellFrm, "No cell frame available, dying soon" )
4532 // determine, if cell frame is at bottom/top border of a table frame and
4533 // the table frame has/is a follow.
4534 const SwFrm* pTmpFrm = _pCellFrm;
4535 bool bCellAtBorder = true;
4536 bool bCellAtLeftBorder = !_pCellFrm->GetPrev();
4537 bool bCellAtRightBorder = !_pCellFrm->GetNext();
4538 while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() )
4540 pTmpFrm = pTmpFrm->GetUpper();
4541 if ( pTmpFrm->IsRowFrm() &&
4542 (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext())
4545 bCellAtBorder = false;
4547 if ( pTmpFrm->IsCellFrm() )
4549 if ( pTmpFrm->GetPrev() )
4551 bCellAtLeftBorder = false;
4553 if ( pTmpFrm->GetNext() )
4555 bCellAtRightBorder = false;
4559 ASSERT( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" );
4561 const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm);
4562 const SwTabFrm* pParentTabFrm =
4563 static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper());
4565 const bool bCellNeedsAttribute = bCellAtBorder &&
4566 ( _bTop ?
4567 // bCellInFirstRowWithMaster
4568 ( !pParentRowFrm->GetPrev() &&
4569 pParentTabFrm->IsFollow() &&
4570 0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) :
4571 // bCellInLastRowWithFollow
4572 ( !pParentRowFrm->GetNext() &&
4573 pParentTabFrm->GetFollow() )
4576 const SwFrm* pRet = _pCellFrm;
4577 if ( bCellNeedsAttribute )
4579 // determine, if cell frame has no borders inside the table.
4580 const SwFrm* pNextCell = 0;
4581 bool bNoBordersInside = false;
4583 if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) )
4585 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell );
4586 const SwBorderAttrs &rBorderAttrs = *aAccess.Get();
4587 const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox();
4588 bCellAtRightBorder = !lcl_HasNextCell( *pNextCell );
4589 bNoBordersInside =
4590 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) &&
4591 !rBorderBox.GetLeft() &&
4592 ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
4593 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4595 else
4597 const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox();
4598 bNoBordersInside =
4599 ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) &&
4600 ( !rBorderBox.GetLeft() || bCellAtLeftBorder ) &&
4601 ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
4602 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4605 if ( bNoBordersInside )
4607 if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() )
4609 // #b4779636#-hack:
4610 // Cell frame has no top border and no border inside the table, but
4611 // it is at the top border of a table frame, which is a follow.
4612 // Thus, use border attributes of cell frame in first row of complete table.
4613 // First, determine first table frame of complete table.
4614 SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true );
4615 // determine first row of complete table.
4616 const SwFrm* pFirstRow = pMasterTabFrm->GetLower();
4617 // return first cell in first row
4618 SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower());
4619 while ( !pLowerCell->IsCellFrm() ||
4620 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4623 pLowerCell = pLowerCell->GetLower();
4625 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4626 pRet = pLowerCell;
4628 else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() )
4630 // #b4779636#-hack:
4631 // Cell frame has no bottom border and no border inside the table,
4632 // but it is at the bottom border of a table frame, which has a follow.
4633 // Thus, use border attributes of cell frame in last row of complete table.
4634 // First, determine last table frame of complete table.
4635 SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow());
4636 while ( pLastTabFrm->GetFollow() )
4638 pLastTabFrm = pLastTabFrm->GetFollow();
4640 // determine last row of complete table.
4641 SwFrm* pLastRow = pLastTabFrm->GetLastLower();
4642 // return first bottom border cell in last row
4643 SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower());
4644 while ( !pLowerCell->IsCellFrm() ||
4645 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4648 if ( pLowerCell->IsRowFrm() )
4650 while ( pLowerCell->GetNext() )
4652 pLowerCell = pLowerCell->GetNext();
4655 pLowerCell = pLowerCell->GetLower();
4657 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4658 pRet = pLowerCell;
4663 return pRet;
4666 void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4667 const SwBorderAttrs &rAttrs ) const
4669 //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun
4670 if ( (GetType() & 0x90C5) )
4671 return;
4673 if ( (GetType() & 0x2000) && //Cell
4674 !pGlobalShell->GetViewOptions()->IsTable() )
4675 return;
4677 // --> collapsing borders FME 2005-05-27 #i29550#
4678 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
4680 const SwTabFrm* pTabFrm = FindTabFrm();
4681 if ( pTabFrm->IsCollapsingBorders() )
4682 return;
4684 if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) )
4685 return;
4687 // <--
4689 const bool bLine = rAttrs.IsLine() ? true : false;
4690 const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE;
4692 // OD 24.02.2003 #b4779636#, #107692# - flag to control,
4693 // if #b4779636#-hack has to be used.
4694 const bool bb4779636HackActive = true;
4695 // OD 21.02.2003 #b4779636#, #107692#
4696 const SwFrm* pCellFrmForBottomBorderAttrs = 0;
4697 const SwFrm* pCellFrmForTopBorderAttrs = 0;
4698 bool bFoundCellForTopOrBorderAttrs = false;
4699 if ( bb4779636HackActive && IsCellFrm() )
4701 pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false );
4702 if ( pCellFrmForBottomBorderAttrs != this )
4703 bFoundCellForTopOrBorderAttrs = true;
4704 pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true );
4705 if ( pCellFrmForTopBorderAttrs != this )
4706 bFoundCellForTopOrBorderAttrs = true;
4709 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4710 // for #b4779636#-hack
4711 if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs )
4713 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt,
4714 //so braucht kein Rand gepainted werden.
4715 //Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden,
4716 //anderfalls wuerden u.U. Teile nicht verarbeitet.
4717 SwRect aRect( Prt() );
4718 aRect += Frm().Pos();
4719 ::SwAlignRect( aRect, pGlobalShell );
4720 // OD 27.09.2002 #103636# - new local boolean variable in order to
4721 // suspend border paint under special cases - see below.
4722 // NOTE: This is a fix for the implementation of feature #99657#.
4723 bool bDrawOnlyShadowForTransparentFrame = false;
4724 if ( aRect.IsInside( rRect ) )
4726 // OD 27.09.2002 #103636# - paint shadow, if background is transparent.
4727 // Because of introduced transparent background for fly frame #99657#,
4728 // the shadow have to be drawn if the background is transparent,
4729 // in spite the fact that the paint rectangle <rRect> lies fully
4730 // in the printing area.
4731 // NOTE to chosen solution:
4732 // On transparent background, continue processing, but suspend
4733 // drawing of border by setting <bDrawOnlyShadowForTransparentFrame>
4734 // to true.
4735 if ( IsLayoutFrm() &&
4736 static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() )
4738 bDrawOnlyShadowForTransparentFrame = true;
4740 else
4742 return;
4746 if ( !pPage )
4747 pPage = FindPageFrm();
4749 ::lcl_CalcBorderRect( aRect, this, rAttrs, TRUE );
4750 rAttrs.SetGetCacheLine( TRUE );
4751 if ( bShadow )
4752 PaintShadow( rRect, aRect, rAttrs );
4753 // OD 27.09.2002 #103636# - suspend drawing of border
4754 // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
4755 // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4756 // for #b4779636#-hack.
4757 if ( ( bLine || bFoundCellForTopOrBorderAttrs ) &&
4758 !bDrawOnlyShadowForTransparentFrame )
4760 const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this;
4761 SWRECTFN( pDirRefFrm )
4762 // OD 19.05.2003 #109667# - use new method <lcl_PaintLeftRightLine(..)>
4763 //::lcl_PaintLeftLine ( this, pPage, aRect, rRect, rAttrs, fnRect );
4764 //::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs, fnRect );
4765 ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4766 ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4767 if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) )
4769 // OD 21.02.2003 #b4779636#, #107692# -
4770 // #b4779636#-hack: If another cell frame for top border
4771 // paint is found, paint its top border.
4772 if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this )
4774 SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4775 pCellFrmForTopBorderAttrs );
4776 const SwBorderAttrs &rTopAttrs = *aAccess.Get();
4777 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4778 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rTopAttrs, fnRect );
4779 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect );
4781 else
4783 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4784 //::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs, fnRect );
4785 ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4788 if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) )
4790 // OD 21.02.2003 #b4779636#, #107692# -
4791 // #b4779636#-hack: If another cell frame for bottom border
4792 // paint is found, paint its bottom border.
4793 if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this )
4795 SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4796 pCellFrmForBottomBorderAttrs );
4797 const SwBorderAttrs &rBottomAttrs = *aAccess.Get();
4798 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4799 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rBottomAttrs, fnRect);
4800 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect);
4802 else
4804 // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4805 //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rAttrs, fnRect);
4806 ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect);
4810 rAttrs.SetGetCacheLine( FALSE );
4813 /*************************************************************************
4815 |* SwFtnContFrm::PaintBorder()
4817 |* Beschreibung Spezialimplementierung wg. der Fussnotenlinie.
4818 |* Derzeit braucht nur der obere Rand beruecksichtigt werden.
4819 |* Auf andere Linien und Schatten wird verzichtet.
4820 |* Ersterstellung MA 27. Feb. 93
4821 |* Letzte Aenderung MA 08. Sep. 93
4823 |*************************************************************************/
4825 void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4826 const SwBorderAttrs & ) const
4828 //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es
4829 //keinen Rand zu painten.
4830 SwRect aRect( Prt() );
4831 aRect.Pos() += Frm().Pos();
4832 if ( !aRect.IsInside( rRect ) )
4833 PaintLine( rRect, pPage );
4835 /*************************************************************************
4837 |* SwFtnContFrm::PaintLine()
4839 |* Beschreibung Fussnotenline malen.
4840 |* Ersterstellung MA 02. Mar. 93
4841 |* Letzte Aenderung MA 28. Mar. 94
4843 |*************************************************************************/
4845 void SwFtnContFrm::PaintLine( const SwRect& rRect,
4846 const SwPageFrm *pPage ) const
4848 //Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc.
4849 //Die Position ist ebenfalls am PageDesc angegeben.
4850 //Der Pen steht direkt im PageDesc.
4852 if ( !pPage )
4853 pPage = FindPageFrm();
4854 const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
4856 SWRECTFN( this )
4857 SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)();
4858 Fraction aFract( nPrtWidth, 1 );
4859 const SwTwips nWidth = (long)(aFract *= rInf.GetWidth());
4861 SwTwips nX = (this->*fnRect->fnGetPrtLeft)();
4862 switch ( rInf.GetAdj() )
4864 case FTNADJ_CENTER:
4865 nX += nPrtWidth/2 - nWidth/2; break;
4866 case FTNADJ_RIGHT:
4867 nX += nPrtWidth - nWidth; break;
4868 case FTNADJ_LEFT:
4869 /* do nothing */; break;
4870 default:
4871 ASSERT( !this, "Neues Adjustment fuer Fussnotenlinie?" );
4873 SwTwips nLineWidth = rInf.GetLineWidth();
4874 const SwRect aLineRect = bVert ?
4875 SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth,
4876 nX), Size( nLineWidth, nWidth ) )
4877 : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ),
4878 Size( nWidth, rInf.GetLineWidth()));
4879 if ( aLineRect.HasArea() )
4880 PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() );
4883 /*************************************************************************
4885 |* SwLayoutFrm::PaintColLines()
4887 |* Beschreibung Painted die Trennlinien fuer die innenliegenden
4888 |* Spalten.
4889 |* Ersterstellung MA 21. Jun. 93
4890 |* Letzte Aenderung MA 28. Mar. 94
4892 |*************************************************************************/
4894 void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol,
4895 const SwPageFrm *pPage ) const
4897 const SwFrm *pCol = Lower();
4898 if ( !pCol || !pCol->IsColumnFrm() )
4899 return;
4901 SwRectFn fnRect = pCol->IsVertical() ? fnRectVert : fnRectHori;
4902 SwRect aLineRect = Prt();
4903 aLineRect += Frm().Pos();
4905 SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight())
4906 / 100 - (aLineRect.*fnRect->fnGetHeight)();
4907 SwTwips nBottom = 0;
4909 switch ( rFmtCol.GetLineAdj() )
4911 case COLADJ_CENTER:
4912 nBottom = nTop / 2; nTop -= nBottom; break;
4913 case COLADJ_TOP:
4914 nBottom = nTop; nTop = 0; break;
4915 case COLADJ_BOTTOM:
4916 break;
4917 default:
4918 ASSERT( !this, "Neues Adjustment fuer Spaltenlinie?" );
4921 if( nTop )
4922 (aLineRect.*fnRect->fnSubTop)( nTop );
4923 if( nBottom )
4924 (aLineRect.*fnRect->fnAddBottom)( nBottom );
4926 SwTwips nPenHalf = rFmtCol.GetLineWidth();
4927 (aLineRect.*fnRect->fnSetWidth)( nPenHalf );
4928 nPenHalf /= 2;
4930 //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein.
4931 SwRect aRect( rRect );
4932 (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW );
4933 (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW );
4934 SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight;
4935 while ( pCol->GetNext() )
4937 (aLineRect.*fnRect->fnSetPosX)
4938 ( (pCol->Frm().*fnGetX)() - nPenHalf );
4939 if ( aRect.IsOver( aLineRect ) )
4940 PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor());
4941 pCol = pCol->GetNext();
4945 void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const
4947 if( !bHasGrid || pRetoucheFly || pRetoucheFly2 )
4948 return;
4949 GETGRID( this )
4950 if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ?
4951 pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) )
4953 const SwLayoutFrm* pBody = FindBodyCont();
4954 if( pBody )
4956 SwRect aGrid( pBody->Prt() );
4957 aGrid += pBody->Frm().Pos();
4959 SwRect aInter( aGrid );
4960 aInter.Intersection( rRect );
4961 if( aInter.HasArea() )
4963 BOOL bGrid = pGrid->GetRubyTextBelow();
4964 BOOL bCell = GRID_LINES_CHARS == pGrid->GetGridType();
4965 long nGrid = pGrid->GetBaseHeight();
4966 const SwDoc* pDoc = GetFmt()->GetDoc();
4967 long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor
4968 long nRuby = pGrid->GetRubyHeight();
4969 long nSum = nGrid + nRuby;
4970 const Color *pCol = &pGrid->GetColor();
4972 SwTwips nRight = aInter.Left() + aInter.Width();
4973 SwTwips nBottom = aInter.Top() + aInter.Height();
4974 if( IsVertical() )
4976 SwTwips nOrig = aGrid.Left() + aGrid.Width();
4977 SwTwips nY = nOrig + nSum *
4978 ( ( nOrig - aInter.Left() ) / nSum );
4979 SwRect aTmp( Point( nY, aInter.Top() ),
4980 Size( 1, aInter.Height() ) );
4981 SwTwips nX = aGrid.Top() + nGrid *
4982 ( ( aInter.Top() - aGrid.Top() )/ nGrid );
4983 if( nX < aInter.Top() )
4984 nX += nGrid;
4985 SwTwips nGridBottom = aGrid.Top() + aGrid.Height();
4986 BOOL bLeft = aGrid.Top() >= aInter.Top();
4987 BOOL bRight = nGridBottom <= nBottom;
4988 BOOL bBorder = bLeft || bRight;
4989 while( nY > nRight )
4991 aTmp.Pos().X() = nY;
4992 if( bGrid )
4994 nY -= nGrid;
4995 SwTwips nPosY = Max( aInter.Left(), nY );
4996 SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY;
4997 if( nHeight > 0 )
4999 if( bCell )
5001 SwRect aVert( Point( nPosY, nX ),
5002 Size( nHeight, 1 ) );
5003 while( aVert.Top() <= nBottom )
5005 PaintBorderLine(rRect,aVert,this,pCol);
5006 aVert.Pos().Y() += nGrid;
5009 else if( bBorder )
5011 SwRect aVert( Point( nPosY, aGrid.Top() ),
5012 Size( nHeight, 1 ) );
5013 if( bLeft )
5014 PaintBorderLine(rRect,aVert,this,pCol);
5015 if( bRight )
5017 aVert.Pos().Y() = nGridBottom;
5018 PaintBorderLine(rRect,aVert,this,pCol);
5023 else
5025 nY -= nRuby;
5026 if( bBorder )
5028 SwTwips nPos = Max( aInter.Left(), nY );
5029 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5030 SwRect aVert( Point( nPos, aGrid.Top() ),
5031 Size( nW, 1 ) );
5032 if( nW > 0 )
5034 if( bLeft )
5035 PaintBorderLine(rRect,aVert,this,pCol);
5036 if( bRight )
5038 aVert.Pos().Y() = nGridBottom;
5039 PaintBorderLine(rRect,aVert,this,pCol);
5044 bGrid = !bGrid;
5046 while( nY >= aInter.Left() )
5048 aTmp.Pos().X() = nY;
5049 PaintBorderLine( rRect, aTmp, this, pCol);
5050 if( bGrid )
5052 nY -= nGrid;
5053 SwTwips nHeight = aTmp.Pos().X()
5054 - Max(aInter.Left(), nY );
5055 if( nHeight > 0 )
5057 if( bCell )
5059 SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5060 nX ), Size( nHeight, 1 ) );
5061 while( aVert.Top() <= nBottom )
5063 PaintBorderLine(rRect,aVert,this,pCol);
5064 aVert.Pos().Y() += nGrid;
5067 else if( bBorder )
5069 SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5070 aGrid.Top() ), Size( nHeight, 1 ) );
5071 if( bLeft )
5072 PaintBorderLine(rRect,aVert,this,pCol);
5073 if( bRight )
5075 aVert.Pos().Y() = nGridBottom;
5076 PaintBorderLine(rRect,aVert,this,pCol);
5081 else
5083 nY -= nRuby;
5084 if( bBorder )
5086 SwTwips nPos = Max( aInter.Left(), nY );
5087 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5088 SwRect aVert( Point( nPos, aGrid.Top() ),
5089 Size( nW, 1 ) );
5090 if( nW > 0 )
5092 if( bLeft )
5093 PaintBorderLine(rRect,aVert,this,pCol);
5094 if( bRight )
5096 aVert.Pos().Y() = nGridBottom;
5097 PaintBorderLine(rRect,aVert,this,pCol);
5102 bGrid = !bGrid;
5105 else
5107 SwTwips nOrig = aGrid.Top();
5108 SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum );
5109 SwRect aTmp( Point( aInter.Left(), nY ),
5110 Size( aInter.Width(), 1 ) );
5111 //for textgrid refactor
5112 SwTwips nX = aGrid.Left() + nGridWidth *
5113 ( ( aInter.Left() - aGrid.Left() )/ nGridWidth );
5114 if( nX < aInter.Left() )
5115 nX += nGridWidth;
5116 SwTwips nGridRight = aGrid.Left() + aGrid.Width();
5117 BOOL bLeft = aGrid.Left() >= aInter.Left();
5118 BOOL bRight = nGridRight <= nRight;
5119 BOOL bBorder = bLeft || bRight;
5120 while( nY < aInter.Top() )
5122 aTmp.Pos().Y() = nY;
5123 if( bGrid )
5125 nY += nGrid;
5126 SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() );
5127 SwTwips nHeight = Min(nBottom, nY ) - nPosY;
5128 if( nHeight )
5130 if( bCell )
5132 SwRect aVert( Point( nX, nPosY ),
5133 Size( 1, nHeight ) );
5134 while( aVert.Left() <= nRight )
5136 PaintBorderLine(rRect,aVert,this,pCol);
5137 aVert.Pos().X() += nGridWidth; //for textgrid refactor
5140 else if ( bBorder )
5142 SwRect aVert( Point( aGrid.Left(), nPosY ),
5143 Size( 1, nHeight ) );
5144 if( bLeft )
5145 PaintBorderLine(rRect,aVert,this,pCol);
5146 if( bRight )
5148 aVert.Pos().X() = nGridRight;
5149 PaintBorderLine(rRect,aVert,this,pCol);
5154 else
5156 nY += nRuby;
5157 if( bBorder )
5159 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5160 SwTwips nH = Min( nBottom, nY ) - nPos;
5161 SwRect aVert( Point( aGrid.Left(), nPos ),
5162 Size( 1, nH ) );
5163 if( nH > 0 )
5165 if( bLeft )
5166 PaintBorderLine(rRect,aVert,this,pCol);
5167 if( bRight )
5169 aVert.Pos().X() = nGridRight;
5170 PaintBorderLine(rRect,aVert,this,pCol);
5175 bGrid = !bGrid;
5177 while( nY <= nBottom )
5179 aTmp.Pos().Y() = nY;
5180 PaintBorderLine( rRect, aTmp, this, pCol);
5181 if( bGrid )
5183 nY += nGrid;
5184 SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y();
5185 if( nHeight )
5187 if( bCell )
5189 SwRect aVert( Point( nX, aTmp.Pos().Y() ),
5190 Size( 1, nHeight ) );
5191 while( aVert.Left() <= nRight )
5193 PaintBorderLine( rRect, aVert, this, pCol);
5194 aVert.Pos().X() += nGridWidth; //for textgrid refactor
5197 else if( bBorder )
5199 SwRect aVert( Point( aGrid.Left(),
5200 aTmp.Pos().Y() ), Size( 1, nHeight ) );
5201 if( bLeft )
5202 PaintBorderLine(rRect,aVert,this,pCol);
5203 if( bRight )
5205 aVert.Pos().X() = nGridRight;
5206 PaintBorderLine(rRect,aVert,this,pCol);
5211 else
5213 nY += nRuby;
5214 if( bBorder )
5216 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5217 SwTwips nH = Min( nBottom, nY ) - nPos;
5218 SwRect aVert( Point( aGrid.Left(), nPos ),
5219 Size( 1, nH ) );
5220 if( nH > 0 )
5222 if( bLeft )
5223 PaintBorderLine(rRect,aVert,this,pCol);
5224 if( bRight )
5226 aVert.Pos().X() = nGridRight;
5227 PaintBorderLine(rRect,aVert,this,pCol);
5232 bGrid = !bGrid;
5240 /** paint margin area of a page
5242 OD 20.11.2002 for #104598#:
5243 implement paint of margin area; margin area will be painted for a
5244 view shell with a window and if the document is not in online layout.
5246 @author OD
5248 @param _rOutputRect
5249 input parameter - constant instance reference of the rectangle, for
5250 which an output has to be generated.
5252 @param _pViewShell
5253 input parameter - instance of the view shell, on which the output
5254 has to be generated.
5256 void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect,
5257 ViewShell* _pViewShell ) const
5259 if ( _pViewShell->GetWin() &&
5260 !_pViewShell->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
5262 SwRect aPgPrtRect( Prt() );
5263 aPgPrtRect.Pos() += Frm().Pos();
5264 if ( !aPgPrtRect.IsInside( _rOutputRect ) )
5266 SwRect aPgRect = Frm();
5267 aPgRect._Intersection( _rOutputRect );
5268 SwRegionRects aPgRegion( aPgRect );
5269 aPgRegion -= aPgPrtRect;
5270 const SwPageFrm* pPage = static_cast<const SwPageFrm*>(this);
5271 if ( pPage->GetSortedObjs() )
5272 ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion );
5273 if ( aPgRegion.Count() )
5275 OutputDevice *pOut = _pViewShell->GetOut();
5276 if ( pOut->GetFillColor() != aGlobalRetoucheColor )
5277 pOut->SetFillColor( aGlobalRetoucheColor );
5278 for ( USHORT i = 0; i < aPgRegion.Count(); ++i )
5280 if ( 1 < aPgRegion.Count() )
5282 ::SwAlignRect( aPgRegion[i], pGlobalShell );
5283 if( !aPgRegion[i].HasArea() )
5284 continue;
5286 pOut->DrawRect(aPgRegion[i].SVRect());
5293 // ----------------------------------------------------------------------
5295 // const SwPageFrm::mnBorderPxWidth, const SwPageFrm::mnShadowPxWidth
5296 // SwPageFrm::GetBorderRect (..), SwPageFrm::GetRightShadowRect(..),
5297 // SwPageFrm::GetBottomShadowRect(..),
5298 // SwPageFrm::PaintBorderAndShadow(..),
5299 // SwPageFrm::GetBorderAndShadowBoundRect(..)
5301 // OD 12.02.2003 for #i9719# and #105645#
5302 // ----------------------------------------------------------------------
5304 const sal_Int8 SwPageFrm::mnBorderPxWidth = 1;
5305 const sal_Int8 SwPageFrm::mnShadowPxWidth = 2;
5307 /** determine rectangle for page border
5309 OD 12.02.2003 for #i9719# and #105645#
5311 @author OD
5313 /*static*/ void SwPageFrm::GetBorderRect( const SwRect& _rPageRect,
5314 ViewShell* _pViewShell,
5315 SwRect& _orBorderRect,
5316 bool bRightSidebar )
5318 SwRect aAlignedPageRect( _rPageRect );
5319 ::SwAlignRect( aAlignedPageRect, _pViewShell );
5320 Rectangle aBorderPxRect =
5321 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5323 aBorderPxRect.Left() = aBorderPxRect.Left() - mnBorderPxWidth;
5324 aBorderPxRect.Top() = aBorderPxRect.Top() - mnBorderPxWidth;
5325 aBorderPxRect.Right() = aBorderPxRect.Right() + mnBorderPxWidth;
5326 aBorderPxRect.Bottom() = aBorderPxRect.Bottom() + mnBorderPxWidth;
5328 AddSidebarBorders(aBorderPxRect,_pViewShell, bRightSidebar, true);
5330 _orBorderRect =
5331 SwRect( _pViewShell->GetOut()->PixelToLogic( aBorderPxRect ) );
5334 /** determine rectangle for right page shadow
5336 OD 12.02.2003 for #i9719# and #105645#
5338 @author OD
5340 /*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect,
5341 ViewShell* _pViewShell,
5342 SwRect& _orRightShadowRect,
5343 bool bRightSidebar )
5345 SwRect aAlignedPageRect( _rPageRect );
5346 ::SwAlignRect( aAlignedPageRect, _pViewShell );
5347 Rectangle aPagePxRect =
5348 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5350 Rectangle aRightShadowPxRect(
5351 aPagePxRect.Right() + mnShadowPxWidth,
5352 aPagePxRect.Top() + 1,
5353 aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5354 aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5356 if ( bRightSidebar )
5357 AddSidebarBorders(aRightShadowPxRect,_pViewShell, bRightSidebar, true);
5359 _orRightShadowRect =
5360 SwRect( _pViewShell->GetOut()->PixelToLogic( aRightShadowPxRect ) );
5363 /** determine rectangle for bottom page shadow
5365 OD 12.02.2003 for #i9719# and #105645#
5367 @author OD
5369 /*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect,
5370 ViewShell* _pViewShell,
5371 SwRect& _orBottomShadowRect,
5372 bool bRightSidebar )
5374 SwRect aAlignedPageRect( _rPageRect );
5375 ::SwAlignRect( aAlignedPageRect, _pViewShell );
5376 Rectangle aPagePxRect =
5377 _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5379 Rectangle aBottomShadowPxRect(
5380 aPagePxRect.Left() + 1,
5381 aPagePxRect.Bottom() + mnShadowPxWidth,
5382 aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5383 aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5385 AddSidebarBorders(aBottomShadowPxRect,_pViewShell, bRightSidebar, true);
5387 _orBottomShadowRect =
5388 SwRect( _pViewShell->GetOut()->PixelToLogic( aBottomShadowPxRect ) );
5391 /** paint page border and shadow
5393 OD 12.02.2003 for #i9719# and #105645#
5394 implement paint of page border and shadow
5396 @author OD
5398 /*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect,
5399 ViewShell* _pViewShell,
5400 bool bPaintRightShadow,
5401 bool bRightSidebar )
5403 // --> FME 2004-06-24 #i16816# tagged pdf support
5404 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() );
5405 // <--
5407 // get color for page border and shadow paint
5408 const Color& rColor = SwViewOption::GetFontColor();
5410 // save current fill and line color of output device
5411 Color aFill( _pViewShell->GetOut()->GetFillColor() );
5412 Color aLine( _pViewShell->GetOut()->GetLineColor() );
5414 // paint page border
5415 _pViewShell->GetOut()->SetFillColor(); // OD 20.02.2003 #107369# - no fill color
5416 _pViewShell->GetOut()->SetLineColor( rColor );
5417 SwRect aPaintRect;
5418 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5419 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5421 // paint right shadow
5422 if ( bPaintRightShadow )
5424 _pViewShell->GetOut()->SetFillColor( rColor );
5425 SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5426 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5429 // paint bottom shadow
5430 SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5431 _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5433 _pViewShell->GetOut()->SetFillColor( aFill );
5434 _pViewShell->GetOut()->SetLineColor( aLine );
5437 //mod #i6193# paint sidebar for notes
5438 //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit
5439 /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, USHORT nPageNum, bool bRight)
5441 //TOOD: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons
5442 if (!_pViewShell )
5443 return;
5445 SwRect aPageRect( _rPageRect );
5446 SwAlignRect( aPageRect, _pViewShell );
5448 const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
5449 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) // do not show anything in print preview
5451 sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight();
5452 const Rectangle &aVisRect = _pViewShell->VisArea().SVRect();
5453 //draw border and sidepane
5454 _pViewShell->GetOut()->SetLineColor();
5455 if (!bRight)
5457 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5458 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()))) ;
5459 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5460 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5461 else
5462 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5463 _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()))) ;
5465 else
5467 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5468 SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()));
5469 _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect());
5470 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5471 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5472 else
5473 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5474 SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()));
5475 _pViewShell->GetOut()->DrawRect(aSidebar.SVRect());
5477 if (pMgr->ShowScrollbar(nPageNum))
5479 // draw scrollbar area and arrows
5480 Point aPointBottom;
5481 Point aPointTop;
5482 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()) :
5483 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height());
5484 aPointTop = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) :
5485 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height());
5486 Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ;
5487 Rectangle aRectBottom(aPointBottom,aSize);
5488 Rectangle aRectTop(aPointTop,aSize);
5490 if (aRectBottom.IsOver(aVisRect))
5493 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5495 _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5496 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5498 else
5500 _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5501 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5503 _pViewShell->GetOut()->DrawRect(aRectBottom);
5504 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5506 _pViewShell->GetOut()->SetLineColor();
5507 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5508 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5509 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5511 if (aRectTop.IsOver(aVisRect))
5513 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5515 _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5516 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5518 else
5520 _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5521 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5523 _pViewShell->GetOut()->DrawRect(aRectTop);
5524 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5526 _pViewShell->GetOut()->SetLineColor();
5527 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5528 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5529 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5535 /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown)
5537 Polygon aTriangleUp(3);
5538 Polygon aTriangleDown(3);
5540 aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5541 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1);
5542 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5544 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5545 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1);
5546 aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5548 _pViewShell->GetOut()->SetFillColor(aColorUp);
5549 _pViewShell->GetOut()->DrawPolygon(aTriangleUp);
5550 _pViewShell->GetOut()->SetFillColor(aColorDown);
5551 _pViewShell->GetOut()->DrawPolygon(aTriangleDown);
5554 /** get bound rectangle of border and shadow for repaints
5556 OD 12.02.2003 for #i9719# and #105645#
5558 author OD
5560 /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect,
5561 ViewShell* _pViewShell,
5562 SwRect& _orBorderAndShadowBoundRect,
5563 bool bRightSidebar )
5565 SwRect aTmpRect;
5566 SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, _orBorderAndShadowBoundRect, bRightSidebar );
5567 SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5568 _orBorderAndShadowBoundRect.Union( aTmpRect );
5569 SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5570 _orBorderAndShadowBoundRect.Union( aTmpRect );
5572 AddSidebarBorders(_orBorderAndShadowBoundRect, _pViewShell, bRightSidebar, false);
5575 /*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5577 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5578 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5580 if (!bRightSidebar)
5581 aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5582 else
5583 aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5587 /*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5589 const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5590 if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5592 if (!bRightSidebar)
5593 aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5594 else
5595 aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx);
5599 /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell )
5601 const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5602 const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
5603 return nRet;
5606 /*************************************************************************
5608 |* SwFrm::PaintBaBo()
5610 |* Ersterstellung MA 22. Oct. 93
5611 |* Letzte Aenderung MA 19. Jun. 96
5613 |*************************************************************************/
5615 void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage,
5616 const BOOL bLowerBorder ) const
5618 if ( !pPage )
5619 pPage = FindPageFrm();
5621 OutputDevice *pOut = pGlobalShell->GetOut();
5623 // --> FME 2004-06-24 #i16816# tagged pdf support
5624 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
5625 // <--
5627 // OD 2004-04-23 #116347#
5628 pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
5629 pOut->SetLineColor();
5631 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
5632 const SwBorderAttrs &rAttrs = *aAccess.Get();
5634 // OD 20.11.2002 #104598# - take care of page margin area
5635 // Note: code move from <SwFrm::PaintBackground(..)> to new method
5636 // <SwPageFrm::Paintmargin(..)>.
5637 if ( IsPageFrm() )
5639 static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell );
5642 // OD 06.08.2002 #99657# - paint border before painting background
5643 // paint grid for page frame and paint border
5645 SwRect aRect( rRect );
5646 if( IsPageFrm() )
5647 ((SwPageFrm*)this)->PaintGrid( pOut, aRect );
5648 PaintBorder( aRect, pPage, rAttrs );
5651 // paint background
5653 PaintBackground( rRect, pPage, rAttrs, FALSE, bLowerBorder );
5656 pOut->Pop();
5659 /*************************************************************************
5661 |* SwFrm::PaintBackground()
5663 |* Ersterstellung MA 04. Jan. 93
5664 |* Letzte Aenderung MA 06. Feb. 97
5666 |*************************************************************************/
5667 /// OD 05.09.2002 #102912#
5668 /// Do not paint background for fly frames without a background brush by
5669 /// calling <PaintBaBo> at the page or at the fly frame its anchored
5670 void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
5671 const SwBorderAttrs & rAttrs,
5672 const BOOL bLowerMode,
5673 const BOOL bLowerBorder ) const
5675 // OD 20.01.2003 #i1837# - no paint of table background, if corresponding
5676 // option is *not* set.
5677 if( IsTabFrm() &&
5678 !pGlobalShell->GetViewOptions()->IsTable() )
5680 return;
5683 // nothing to do for covered table cells:
5684 if( IsCellFrm() && IsCoveredCell() )
5685 return;
5687 ViewShell *pSh = pGlobalShell;
5689 // --> FME 2004-06-24 #i16816# tagged pdf support
5690 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
5691 // <--
5693 const SvxBrushItem* pItem;
5694 /// OD 05.09.2002 #102912#
5695 /// temporary background brush for a fly frame without a background brush
5696 SvxBrushItem* pTmpBackBrush = 0;
5697 const Color* pCol;
5698 SwRect aOrigBackRect;
5699 const BOOL bPageFrm = IsPageFrm();
5700 BOOL bLowMode = TRUE;
5702 BOOL bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, bLowerMode );
5703 //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird.
5704 bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm();
5705 if ( bNoFlyBackground )
5707 // OD 05.09.2002 #102912# - Fly frame has no background.
5708 // Try to find background brush at parents, if previous call of
5709 // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode>
5710 if ( bLowerMode )
5712 bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, false );
5714 // If still no background found for the fly frame, initialize the
5715 // background brush <pItem> with global retouche color and set <bBack>
5716 // to TRUE, that fly frame will paint its background using this color.
5717 if ( !bBack )
5719 // OD 10.01.2003 #i6467# - on print output, pdf output and
5720 // in embedded mode not editing color COL_WHITE is used instead of
5721 // the global retouche color.
5722 if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
5723 pSh->GetViewOptions()->IsPDFExport() ||
5724 ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED &&
5725 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive()
5729 pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND );
5731 else
5733 pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND);
5735 pItem = pTmpBackBrush;
5736 bBack = true;
5740 SwRect aPaintRect( Frm() );
5741 if( IsTxtFrm() || IsSctFrm() )
5742 aPaintRect = UnionFrm( TRUE );
5744 if ( aPaintRect.IsOver( rRect ) )
5746 if ( bBack || bPageFrm || !bLowerMode )
5748 const BOOL bBrowse = pSh->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE);
5750 SwRect aRect;
5751 if ( (bPageFrm && bBrowse) ||
5752 (IsTxtFrm() && Prt().SSize() == Frm().SSize()) )
5754 aRect = Frm();
5755 ::SwAlignRect( aRect, pGlobalShell );
5757 else
5759 ::lcl_CalcBorderRect( aRect, this, rAttrs, FALSE );
5760 if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() )
5762 if ( GetPrev()->GetAttrSet()->GetBackground() ==
5763 GetAttrSet()->GetBackground() )
5765 aRect.Top( Frm().Top() );
5769 aRect.Intersection( rRect );
5771 OutputDevice *pOut = pSh->GetOut();
5773 if ( aRect.HasArea() )
5775 SvxBrushItem* pNewItem = 0;
5776 SwRegionRects aRegion( aRect );
5777 if( pCol )
5779 pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND );
5780 pItem = pNewItem;
5782 if ( pPage->GetSortedObjs() )
5783 ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
5786 /// OD 06.08.2002 #99657# - determine, if background transparency
5787 /// have to be considered for drawing.
5788 /// --> Status Quo: background transparency have to be
5789 /// considered for fly frames
5790 const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm();
5791 for ( USHORT i = 0; i < aRegion.Count(); ++i )
5793 if ( 1 < aRegion.Count() )
5795 ::SwAlignRect( aRegion[i], pGlobalShell );
5796 if( !aRegion[i].HasArea() )
5797 continue;
5799 /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if
5800 /// background transparency have to be considered
5801 /// Set missing 5th parameter to the default value GRFNUM_NO
5802 /// - see declaration in /core/inc/frmtool.hxx.
5803 ::DrawGraphic( pItem, pOut, aOrigBackRect, aRegion[i], GRFNUM_NO,
5804 bConsiderBackgroundTransparency );
5807 if( pCol )
5808 delete pNewItem;
5811 else
5812 bLowMode = bLowerMode ? TRUE : FALSE;
5815 /// OD 05.09.2002 #102912#
5816 /// delete temporary background brush.
5817 delete pTmpBackBrush;
5819 //Jetzt noch Lower und dessen Nachbarn.
5820 //Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist
5821 //so hoert der Spass auf.
5822 const SwFrm *pFrm = GetLower();
5823 if ( pFrm )
5825 SwRect aFrmRect;
5826 SwRect aRect( PaintArea() );
5827 aRect._Intersection( rRect );
5828 SwRect aBorderRect( aRect );
5829 SwShortCut aShortCut( *pFrm, aBorderRect );
5831 { if ( pProgress )
5832 pProgress->Reschedule();
5834 aFrmRect = pFrm->PaintArea();
5835 if ( aFrmRect.IsOver( aBorderRect ) )
5837 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
5838 const SwBorderAttrs &rTmpAttrs = *aAccess.Get();
5839 /// OD 06.08.2002 #99657# - paint border before painting background
5840 if ( bLowerBorder )
5841 pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs );
5842 if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) ||
5843 aFrmRect.IsOver( aRect ) )
5844 pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode,
5845 bLowerBorder );
5847 pFrm = pFrm->GetNext();
5848 } while ( pFrm && pFrm->GetUpper() == this &&
5849 !aShortCut.Stop( aFrmRect ) );
5853 /*************************************************************************
5855 |* SwPageFrm::RefreshSubsidiary()
5857 |* Beschreibung Erneuert alle Hilfslinien der Seite.
5858 |* Ersterstellung MA 04. Nov. 92
5859 |* Letzte Aenderung MA 10. May. 95
5861 |*************************************************************************/
5863 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
5865 if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS )
5867 SwRect aRect( rRect );
5868 // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of
5869 // the output rectangle.
5870 //::SwAlignRect( aRect, pGlobalShell );
5871 if ( aRect.HasArea() )
5873 //Beim Paint ueber die Root wird das Array von dort gesteuert.
5874 //Anderfalls kuemmern wir uns selbst darum.
5875 BOOL bDelSubs = FALSE;
5876 if ( !pSubsLines )
5878 pSubsLines = new SwSubsRects;
5879 // OD 20.12.2002 #106318# - create container for special subsidiary lines
5880 pSpecSubsLines = new SwSubsRects;
5881 bDelSubs = TRUE;
5884 RefreshLaySubsidiary( this, aRect );
5886 if ( bDelSubs )
5888 // OD 20.12.2002 #106318# - paint special subsidiary lines
5889 // and delete its container
5890 pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL );
5891 DELETEZ( pSpecSubsLines );
5893 pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines );
5894 DELETEZ( pSubsLines );
5900 /*************************************************************************
5902 |* SwLayoutFrm::RefreshLaySubsidiary()
5904 |* Ersterstellung MA 04. Nov. 92
5905 |* Letzte Aenderung MA 22. Jan. 95
5907 |*************************************************************************/
5908 void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage,
5909 const SwRect &rRect ) const
5911 const BOOL bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm();
5912 const BOOL bSubsOpt = IS_SUBS;
5913 const BOOL bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE);
5914 const BOOL bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt;
5915 const BOOL bSubsSect = IsSctFrm() &&
5916 bNoLowerColumn &&
5917 IS_SUBS_SECTION;
5918 const BOOL bSubsFly = IS_SUBS_FLYS &&
5919 (GetType() & FRM_FLY) &&
5920 bNoLowerColumn &&
5921 (!Lower() || !Lower()->IsNoTxtFrm() ||
5922 !((SwNoTxtFrm*)Lower())->HasAnimation());
5923 BOOL bSubsBody = FALSE;
5924 if ( GetType() & FRM_BODY )
5926 if ( IsPageBodyFrm() )
5927 bSubsBody = bSubsOpt && bNoLowerColumn; //nur ohne Spalten
5928 else //Spaltenbody
5930 if ( GetUpper()->GetUpper()->IsSctFrm() )
5931 bSubsBody = IS_SUBS_SECTION;
5932 else
5933 bSubsBody = bSubsOpt;
5937 if ( bSubsOther || bSubsSect || bSubsBody || bSubsTable || bSubsFly )
5938 PaintSubsidiaryLines( pPage, rRect );
5940 const SwFrm *pLow = Lower();
5941 if( !pLow )
5942 return;
5943 SwShortCut aShortCut( *pLow, rRect );
5944 while( pLow && !aShortCut.Stop( pLow->Frm() ) )
5946 if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() )
5948 if ( pLow->IsLayoutFrm() )
5949 ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect);
5950 else if ( pLow->GetDrawObjs() )
5952 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs());
5953 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
5955 const SwAnchoredObject* pAnchoredObj = rObjs[i];
5956 if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
5957 pAnchoredObj->GetDrawObj()->GetLayer() ) &&
5958 pAnchoredObj->ISA(SwFlyFrm) )
5960 const SwFlyFrm *pFly =
5961 static_cast<const SwFlyFrm*>(pAnchoredObj);
5962 if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) )
5964 if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
5965 !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
5966 pFly->RefreshLaySubsidiary( pPage, rRect );
5972 pLow = pLow->GetNext();
5976 /*************************************************************************
5978 |* SwLayoutFrm::PaintSubsidiaryLines()
5980 |* Beschreibung Hilfslinien um die PrtAreas malen
5981 |* Nur die LayoutFrm's die direkt Cntnt enthalten.
5982 |* Ersterstellung MA 21. May. 92
5983 |* Letzte Aenderung MA 22. Jan. 95
5985 |*************************************************************************/
5987 //Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden.
5989 typedef long Size::* SizePtr;
5990 typedef long Point::* PointPtr;
5992 PointPtr pX = &Point::nA;
5993 PointPtr pY = &Point::nB;
5994 SizePtr pWidth = &Size::nA;
5995 SizePtr pHeight = &Size::nB;
5997 // OD 18.11.2002 #99672# - new parameter <_pSubsLines>
5998 void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay,
5999 const SwPageFrm *pPage,
6000 const Point &rP1,
6001 const Point &rP2,
6002 const BYTE nSubColor,
6003 SwLineRects* _pSubsLines )
6005 //In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein.
6006 ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
6007 "Schraege Hilfslinien sind nicht erlaubt." );
6008 const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX;
6009 const PointPtr pOthPt = pDirPt == pX ? pY : pX;
6010 const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight;
6011 const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth;
6012 Point aP1( rP1 ),
6013 aP2( rP2 );
6015 while ( aP1.*pDirPt < aP2.*pDirPt )
6016 { //Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt
6017 //hinter den Fly gesetzt.
6018 //Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt
6019 //ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen.
6020 //Auf diese art und weise wird eine Portion nach der anderen
6021 //ausgegeben.
6023 //Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus,
6024 //die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen.
6025 //Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche
6026 //ich keinem dieser Flys aus.
6027 SwOrderIter aIter( pPage );
6028 const SwFlyFrm *pMyFly = pLay->FindFlyFrm();
6029 if ( pMyFly )
6031 aIter.Current( pMyFly->GetVirtDrawObj() );
6032 while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) )
6034 if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
6035 aIter.Current( pMyFly->GetVirtDrawObj() );
6038 else
6039 aIter.Bottom();
6041 while ( aIter() )
6043 const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
6044 const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
6046 //Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich
6047 //_in_ dem Fly sitze weiche ich nicht aus.
6048 if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
6050 aIter.Next();
6051 continue;
6054 // OD 19.12.2002 #106318# - do *not* consider fly frames with
6055 // a transparent background.
6056 // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which
6057 // belongs to a invisible layer
6058 if ( pFly->IsBackgroundTransparent() ||
6059 !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) )
6061 aIter.Next();
6062 continue;
6065 //Sitzt das Obj auf der Linie
6066 const Rectangle &rBound = pObj->GetCurrentBoundRect();
6067 const Point aDrPt( rBound.TopLeft() );
6068 const Size aDrSz( rBound.GetSize() );
6069 if ( rP1.*pOthPt >= aDrPt.*pOthPt &&
6070 rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) )
6072 if ( aP1.*pDirPt >= aDrPt.*pDirPt &&
6073 aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) )
6074 aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz;
6076 if ( aP2.*pDirPt >= aDrPt.*pDirPt &&
6077 aP1.*pDirPt < (aDrPt.*pDirPt - 1) )
6078 aP2.*pDirPt = aDrPt.*pDirPt - 1;
6080 aIter.Next();
6083 if ( aP1.*pDirPt < aP2.*pDirPt )
6085 SwRect aRect( aP1, aP2 );
6086 // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of
6087 // global variable <pSubsLines>.
6088 _pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6090 aP1 = aP2;
6091 aP1.*pDirPt += 1;
6092 aP2 = rP2;
6096 void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage,
6097 const SwRect &rRect ) const
6099 bool bNewTableModel = false;
6101 // --> collapsing borders FME 2005-05-27 #i29550#
6102 if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
6104 const SwTabFrm* pTabFrm = FindTabFrm();
6105 if ( pTabFrm->IsCollapsingBorders() )
6106 return;
6108 bNewTableModel = pTabFrm->GetTable()->IsNewModel();
6109 // in the new table model, we have an early return for all cell-related
6110 // frames, except from non-covered table cells
6111 if ( bNewTableModel )
6112 if ( IsTabFrm() ||
6113 IsRowFrm() ||
6114 ( IsCellFrm() && IsCoveredCell() ) )
6115 return;
6117 // <-- collapsing
6119 const bool bFlys = pPage->GetSortedObjs() ? true : false;
6121 const bool bCell = IsCellFrm() ? true : false;
6122 // use frame area for cells
6123 // OD 13.02.2003 #i3662# - for section use also frame area
6124 const bool bUseFrmArea = bCell || IsSctFrm();
6125 SwRect aOriginal( bUseFrmArea ? Frm() : Prt() );
6126 if ( !bUseFrmArea )
6127 aOriginal.Pos() += Frm().Pos();
6129 // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area
6130 // in sections to top of section frame.
6131 const bool bColBodyInSection = IsBodyFrm() &&
6132 !IsPageBodyFrm() &&
6133 GetUpper()->GetUpper()->IsSctFrm();
6134 if ( bColBodyInSection )
6136 if ( IsVertical() )
6137 aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() );
6138 else
6139 aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() );
6142 ::SwAlignRect( aOriginal, pGlobalShell );
6144 if ( !aOriginal.IsOver( rRect ) )
6145 return;
6147 SwRect aOut( aOriginal );
6148 aOut._Intersection( rRect );
6149 // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's
6150 // printing area with the paint area of the body frame. Otherwise enlargement
6151 // will get lost.
6152 if ( !bColBodyInSection )
6154 aOut.Intersection( PaintArea() );
6157 const SwTwips nRight = aOut.Right();
6158 const SwTwips nBottom= aOut.Bottom();
6160 const Point aRT( nRight, aOut.Top() );
6161 const Point aRB( nRight, nBottom );
6162 const Point aLB( aOut.Left(), nBottom );
6164 BYTE nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB :
6165 ( IsInSct() ? SUBCOL_SECT :
6166 ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
6168 // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks.
6169 BOOL bBreak = FALSE;
6170 if ( IsBodyFrm() )
6172 const SwCntntFrm *pCnt = ContainsCntnt();
6173 if ( pCnt )
6175 // OD 05.11.2002 #102406# - adjust setting of <bBreak>.
6176 bBreak = pCnt->IsPageBreak( TRUE ) ||
6177 ( IsColBodyFrm() && pCnt->IsColBreak( TRUE ) );
6181 // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section
6182 // sub-lines in <pSpecSubsLine> array.
6183 const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() ||
6184 IsFtnFrm() || IsSctFrm();
6185 SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines;
6187 // NOTE: for cell frames only left and right (horizontal layout) respectively
6188 // top and bottom (vertical layout) lines painted.
6189 // NOTE2: this does not hold for the new table model!!! We paint the top border
6190 // of each non-covered table cell.
6191 const bool bVert = IsVertical() ? true : false;
6192 if ( bFlys )
6194 // OD 14.11.2002 #104822# - add control for drawing left and right lines
6195 if ( !bCell || bNewTableModel || !bVert )
6197 if ( aOriginal.Left() == aOut.Left() )
6198 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor,
6199 pUsedSubsLines );
6200 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6201 if ( aOriginal.Right() == nRight )
6202 ::lcl_RefreshLine( this, pPage, aRT, aRB,
6203 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor,
6204 pUsedSubsLines );
6206 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6207 if ( !bCell || bNewTableModel || bVert )
6209 if ( aOriginal.Top() == aOut.Top() )
6210 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6211 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT,
6212 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor,
6213 pUsedSubsLines );
6214 if ( aOriginal.Bottom() == nBottom )
6215 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor,
6216 pUsedSubsLines );
6219 else
6221 // OD 14.11.2002 #104822# - add control for drawing left and right lines
6222 if ( !bCell || bNewTableModel || !bVert )
6224 if ( aOriginal.Left() == aOut.Left() )
6226 const SwRect aRect( aOut.Pos(), aLB );
6227 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6229 // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6230 if ( aOriginal.Right() == nRight )
6232 const SwRect aRect( aRT, aRB );
6233 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6234 (bBreak && bVert) ? SUBCOL_BREAK : nSubColor );
6237 // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6238 if ( !bCell || bNewTableModel || bVert )
6240 if ( aOriginal.Top() == aOut.Top() )
6242 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6243 const SwRect aRect( aOut.Pos(), aRT );
6244 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6245 (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor );
6247 if ( aOriginal.Bottom() == nBottom )
6249 const SwRect aRect( aLB, aRB );
6250 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6256 /*************************************************************************
6258 |* SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData()
6260 |* Beschreibung Erneuert alle Extradaten (Zeilennummern usw) der Seite.
6261 |* Grundsaetzlich sind nur diejenigen Objekte beruecksichtig,
6262 |* die in die seitliche Ausdehnung des Rects ragen.
6263 |* Ersterstellung MA 20. Jan. 98
6264 |* Letzte Aenderung MA 18. Feb. 98
6266 |*************************************************************************/
6268 void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const
6270 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6271 BOOL bLineInFly = rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys()
6272 || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE;
6274 SwRect aRect( rRect );
6275 ::SwAlignRect( aRect, pGlobalShell );
6276 if ( aRect.HasArea() )
6278 SwLayoutFrm::RefreshExtraData( aRect );
6280 if ( bLineInFly && GetSortedObjs() )
6281 for ( USHORT i = 0; i < GetSortedObjs()->Count(); ++i )
6283 const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
6284 if ( pAnchoredObj->ISA(SwFlyFrm) )
6286 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6287 if ( pFly->Frm().Top() <= aRect.Bottom() &&
6288 pFly->Frm().Bottom() >= aRect.Top() )
6289 pFly->RefreshExtraData( aRect );
6295 void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const
6298 const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6299 BOOL bLineInBody = rInfo.IsPaintLineNumbers(),
6300 bLineInFly = bLineInBody && rInfo.IsCountInFlys(),
6301 bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE;
6303 const SwCntntFrm *pCnt = ContainsCntnt();
6304 while ( pCnt && IsAnLower( pCnt ) )
6306 if ( pCnt->IsTxtFrm() && ( bRedLine ||
6307 ( !pCnt->IsInTab() &&
6308 ((bLineInBody && pCnt->IsInDocBody()) ||
6309 (bLineInFly && pCnt->IsInFly())) ) ) &&
6310 pCnt->Frm().Top() <= rRect.Bottom() &&
6311 pCnt->Frm().Bottom() >= rRect.Top() )
6313 ((SwTxtFrm*)pCnt)->PaintExtraData( rRect );
6315 if ( bLineInFly && pCnt->GetDrawObjs() )
6316 for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i )
6318 const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i];
6319 if ( pAnchoredObj->ISA(SwFlyFrm) )
6321 const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6322 if ( pFly->IsFlyInCntFrm() &&
6323 pFly->Frm().Top() <= rRect.Bottom() &&
6324 pFly->Frm().Bottom() >= rRect.Top() )
6325 pFly->RefreshExtraData( rRect );
6328 pCnt = pCnt->GetNextCntntFrm();
6332 /** SwPageFrm::GetDrawBackgrdColor - for #102450#
6334 determine the color, that is respectively will be drawn as background
6335 for the page frame.
6336 Using existing method SwFrm::GetBackgroundBrush to determine the color
6337 that is set at the page frame respectively is parent. If none is found
6338 return the global retouche color
6340 @author OD
6342 @return Color
6344 const Color& SwPageFrm::GetDrawBackgrdColor() const
6346 const SvxBrushItem* pBrushItem;
6347 const Color* pDummyColor;
6348 SwRect aDummyRect;
6349 if ( GetBackgroundBrush( pBrushItem, pDummyColor, aDummyRect, true) )
6350 return pBrushItem->GetColor();
6351 else
6352 return aGlobalRetoucheColor;
6355 /*************************************************************************
6357 |* SwPageFrm::GetEmptyPageFont()
6359 |* create/return font used to paint the "empty page" string
6361 |*************************************************************************/
6363 const Font& SwPageFrm::GetEmptyPageFont()
6365 static Font* pEmptyPgFont = 0;
6366 if ( 0 == pEmptyPgFont )
6368 pEmptyPgFont = new Font;
6369 pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt
6370 pEmptyPgFont->SetWeight( WEIGHT_BOLD );
6371 pEmptyPgFont->SetStyleName( aEmptyStr );
6372 pEmptyPgFont->SetName( String::CreateFromAscii(
6373 RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) );
6374 pEmptyPgFont->SetFamily( FAMILY_SWISS );
6375 pEmptyPgFont->SetTransparent( TRUE );
6376 pEmptyPgFont->SetColor( COL_GRAY );
6379 return *pEmptyPgFont;
6382 /*************************************************************************
6384 |* SwFrm::Retouche
6386 |* Beschreibung Retouche fuer einen Bereich.
6387 |* Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner
6388 |* Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird
6389 |* per PaintBackground gecleared.
6390 |* Ersterstellung MA 13. Apr. 93
6391 |* Letzte Aenderung MA 25. Jul. 96
6393 |*************************************************************************/
6395 void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const
6397 if ( bFlyMetafile )
6398 return;
6400 ASSERT( GetUpper(), "Retoucheversuch ohne Upper." );
6401 ASSERT( GetShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" );
6403 SwRect aRetouche( GetUpper()->PaintArea() );
6404 aRetouche.Top( Frm().Top() + Frm().Height() );
6405 aRetouche.Intersection( pGlobalShell->VisArea() );
6407 if ( aRetouche.HasArea() )
6409 //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region
6410 //zum ausstanzen.
6411 SwRegionRects aRegion( aRetouche );
6412 aRegion -= rRect;
6413 ViewShell *pSh = GetShell();
6415 // --> FME 2004-06-24 #i16816# tagged pdf support
6416 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
6417 // <--
6419 for ( USHORT i = 0; i < aRegion.Count(); ++i )
6421 SwRect &rRetouche = aRegion[i];
6423 GetUpper()->PaintBaBo( rRetouche, pPage, TRUE );
6425 //Hoelle und Himmel muessen auch refreshed werden.
6426 //Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst
6427 //zurueckgesetzt werden!
6428 ResetRetouche();
6429 SwRect aRetouchePart( rRetouche );
6430 if ( aRetouchePart.HasArea() )
6432 // OD 30.08.2002 #102450#
6433 // determine background color of page for <PaintLayer> method
6434 // calls, painting <hell> or <heaven>
6435 const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
6436 // OD 29.08.2002 #102450#
6437 // add 3rd parameter to <PaintLayer> method calls
6438 // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
6439 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6441 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(),
6442 aRetouchePart, &aPageBackgrdColor,
6443 (pPage->IsRightToLeft() ? true : false) );
6444 pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(),
6445 aRetouchePart, &aPageBackgrdColor,
6446 (pPage->IsRightToLeft() ? true : false) );
6449 SetRetouche();
6451 //Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier
6452 //leider die Hilfslinien erneuert werden.
6453 pPage->RefreshSubsidiary( aRetouchePart );
6456 if ( ViewShell::IsLstEndAction() )
6457 ResetRetouche();
6460 /** SwFrm::GetBackgroundBrush
6462 @descr
6463 determine the background brush for the frame:
6464 the background brush is taken from it-self or from its parent (anchor/upper).
6465 Normally, the background brush is taken, which has no transparent color or
6466 which has a background graphic. But there are some special cases:
6467 (1) No background brush is taken from a page frame, if view option "IsPageBack"
6468 isn't set.
6469 (2) Background brush from a index section is taken under special conditions.
6470 In this case parameter <rpCol> is set to the index shading color.
6471 (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing
6472 of the frame transparency is considered and its color is not "no fill"/"auto fill"
6473 ---- old description in german:
6474 Beschreibung Liefert die Backgroundbrush fuer den Bereich des
6475 des Frm. Die Brush wird entweder von ihm selbst oder von einem
6476 Upper vorgegeben, die erste Brush wird benutzt.
6477 Ist fuer keinen Frm eine Brush angegeben, so wird FALSE zurueck-
6478 geliefert.
6479 Ersterstellung MA 23. Dec. 92
6480 Letzte Aenderung MA 04. Feb. 97
6482 @param rpBrush
6483 output parameter - constant reference pointer the found background brush
6485 @param rpCol
6486 output parameter - constant reference pointer to the color of the index shading
6487 set under special conditions, if background brush is taken from an index section.
6489 @param rOrigRect
6490 in-/output parameter - reference to the retangle the background brush is
6491 considered for - adjusted to the frame, from which the background brush is
6492 taken.
6494 @parem bLowerMode
6495 input parameter - boolean indicating, if background brush should *not* be
6496 taken from parent.
6498 @author MA
6499 @change 20.08.2002 by OD
6500 @docdate 20.08.2002
6502 @return true, if a background brush for the frame is found
6504 BOOL SwFrm::GetBackgroundBrush( const SvxBrushItem* & rpBrush,
6505 const Color*& rpCol,
6506 SwRect &rOrigRect,
6507 BOOL bLowerMode ) const
6509 const SwFrm *pFrm = this;
6510 ViewShell *pSh = GetShell();
6511 const SwViewOption *pOpt = pSh->GetViewOptions();
6512 rpBrush = 0;
6513 rpCol = NULL;
6515 { if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() )
6516 return FALSE;
6518 const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
6519 if( pFrm->IsSctFrm() )
6521 const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
6522 /// OD 20.08.2002 #99657# #GetTransChg#
6523 /// Note: If frame <pFrm> is a section of the index and
6524 /// it its background color is "no fill"/"auto fill" and
6525 /// it has no background graphic and
6526 /// we are not in the page preview and
6527 /// we are not in read-only mode and
6528 /// option "index shadings" is set and
6529 /// the output is not the printer
6530 /// then set <rpCol> to the color of the index shading
6531 if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
6532 TOX_CONTENT_SECTION == pSection->GetType() ) &&
6533 (rBack.GetColor() == COL_TRANSPARENT) &&
6534 ///rBack.GetColor().GetTransparency() &&
6535 rBack.GetGraphicPos() == GPOS_NONE &&
6536 !pOpt->IsPagePreview() &&
6537 !pOpt->IsReadonly() &&
6538 // --> FME 2004-06-29 #114856# Formular view
6539 !pOpt->IsFormView() &&
6540 // <--
6541 SwViewOption::IsIndexShadings() &&
6542 !pOpt->IsPDFExport() &&
6543 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
6545 rpCol = &SwViewOption::GetIndexShadingsColor();
6549 /// OD 20.08.2002 #99657#
6550 /// determine, if background draw of frame <pFrm> considers transparency
6551 /// --> Status Quo: background transparency have to be
6552 /// considered for fly frames
6553 const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm();
6554 /// OD 20.08.2002 #99657#
6555 /// add condition:
6556 /// If <bConsiderBackgroundTransparency> is set - see above -,
6557 /// return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill"
6558 if ( !rBack.GetColor().GetTransparency() ||
6559 rBack.GetGraphicPos() != GPOS_NONE ||
6560 rpCol ||
6561 (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT))
6564 rpBrush = &rBack;
6565 if ( pFrm->IsPageFrm() &&
6566 pSh->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
6567 rOrigRect = pFrm->Frm();
6568 else
6570 if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() )
6572 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
6573 const SwBorderAttrs &rAttrs = *aAccess.Get();
6574 ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, FALSE );
6576 else
6578 rOrigRect = pFrm->Prt();
6579 rOrigRect += pFrm->Frm().Pos();
6582 return TRUE;
6585 if ( bLowerMode )
6586 /// Do not try to get background brush from parent (anchor/upper)
6587 return FALSE;
6589 /// get parent frame - anchor or upper - for next loop
6590 if ( pFrm->IsFlyFrm() )
6591 /// OD 20.08.2002 - use "static_cast" instead of "old C-cast"
6592 pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm();
6593 ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
6594 else
6595 pFrm = pFrm->GetUpper();
6597 } while ( pFrm );
6599 return FALSE;
6602 /*************************************************************************
6604 |* SwFrmFmt::GetGraphic()
6606 |* Ersterstellung MA 23. Jul. 96
6607 |* Letzte Aenderung MA 23. Jul. 96
6609 |*************************************************************************/
6611 void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO,
6612 Window *pW, USHORT nZoom )
6614 pSh->pOut = pO;
6615 pSh->pWin = pW;
6616 pSh->pOpt->SetZoom( nZoom );
6619 Graphic SwFrmFmt::MakeGraphic( ImageMap* )
6621 return Graphic();
6624 Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap )
6626 Graphic aRet;
6627 //irgendeinen Fly suchen!
6628 SwClientIter aIter( *this );
6629 SwClient *pFirst = aIter.First( TYPE(SwFrm) );
6630 ViewShell *pSh;
6631 if ( pFirst && 0 != ( pSh = ((SwFrm*)pFirst)->GetShell()) )
6633 ViewShell *pOldGlobal = pGlobalShell;
6634 pGlobalShell = pSh;
6636 BOOL bNoteURL = pMap &&
6637 SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, TRUE );
6638 if( bNoteURL )
6640 ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
6641 pNoteURL = new SwNoteURL;
6643 SwFlyFrm *pFly = (SwFlyFrm*)pFirst;
6645 OutputDevice *pOld = pSh->GetOut();
6646 VirtualDevice aDev( *pOld );
6647 aDev.EnableOutput( FALSE );
6649 GDIMetaFile aMet;
6650 MapMode aMap( pOld->GetMapMode().GetMapUnit() );
6651 aDev.SetMapMode( aMap );
6652 aMet.SetPrefMapMode( aMap );
6654 ::SwCalcPixStatics( pSh->GetOut() );
6655 aMet.SetPrefSize( pFly->Frm().SSize() );
6657 aMet.Record( &aDev );
6658 aDev.SetLineColor();
6659 aDev.SetFillColor();
6660 aDev.SetFont( pOld->GetFont() );
6662 //Rechteck ggf. ausdehnen, damit die Umrandunge mit aufgezeichnet werden.
6663 SwRect aOut( pFly->Frm() );
6664 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
6665 const SwBorderAttrs &rAttrs = *aAccess.Get();
6666 if ( rAttrs.CalcRightLine() )
6667 aOut.SSize().Width() += 2*nPixelSzW;
6668 if ( rAttrs.CalcBottomLine() )
6669 aOut.SSize().Height()+= 2*nPixelSzH;
6671 // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
6672 const Region aRepaintRegion(aOut.SVRect());
6673 pSh->DLPrePaint2(aRepaintRegion);
6675 Window *pWin = pSh->GetWin();
6676 USHORT nZoom = pSh->GetViewOptions()->GetZoom();
6677 ::SetOutDevAndWin( pSh, &aDev, 0, 100 );
6678 bFlyMetafile = TRUE;
6679 pFlyMetafileOut = pWin;
6681 SwViewImp *pImp = pSh->Imp();
6682 pFlyOnlyDraw = pFly;
6683 pLines = new SwLineRects;
6685 // OD 09.12.2002 #103045# - determine page, fly frame is on
6686 const SwPageFrm* pFlyPage = pFly->FindPageFrm();
6687 // OD 30.08.2002 #102450#
6688 // determine color of page, the fly frame is on, for <PaintLayer> method
6689 // calls, painting <hell> or <heaven>
6690 const Color aPageBackgrdColor = pFlyPage->GetDrawBackgrdColor();
6691 // OD 30.08.2002 #102450# - add 3rd parameter
6692 // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
6693 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6694 pImp->PaintLayer( pIDDMA->GetHellId(), aOut, &aPageBackgrdColor,
6695 (pFlyPage->IsRightToLeft() ? true : false) );
6696 pLines->PaintLines( &aDev );
6697 if ( pFly->IsFlyInCntFrm() )
6698 pFly->Paint( aOut );
6699 pLines->PaintLines( &aDev );
6700 /// OD 30.08.2002 #102450# - add 3rd parameter
6701 pImp->PaintLayer( pIDDMA->GetHeavenId(), aOut, &aPageBackgrdColor,
6702 (pFlyPage->IsRightToLeft() ? true : false) );
6703 pLines->PaintLines( &aDev );
6704 DELETEZ( pLines );
6705 pFlyOnlyDraw = 0;
6707 pFlyMetafileOut = 0;
6708 bFlyMetafile = FALSE;
6709 ::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
6711 // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted
6712 pSh->DLPostPaint2(true);
6714 aMet.Stop();
6715 aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() );
6716 aRet = Graphic( aMet );
6718 if( bNoteURL )
6720 ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
6721 pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap );
6722 delete pNoteURL;
6723 pNoteURL = NULL;
6725 pGlobalShell = pOldGlobal;
6727 return aRet;
6730 Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* )
6732 Graphic aRet;
6733 SdrModel *pMod = getIDocumentDrawModelAccess()->GetDrawModel();
6734 if ( pMod )
6736 SdrObject *pObj = FindSdrObject();
6737 SdrView *pView = new SdrView( pMod );
6738 SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0));
6739 pView->MarkObj( pObj, pPgView );
6740 aRet = pView->GetMarkedObjBitmap();
6741 pView->HideSdrPage();
6742 delete pView;
6744 return aRet;