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