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