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