xref: /trunk/main/sw/source/core/layout/paintfrm.cxx (revision b740b198)
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                 // check if the new fill attributes are used
3672                 if(aFillAttributes.get() && aFillAttributes->isUsed())
3673                 {
3674                     bPaintCompleteBack = true;
3675                 }
3676             }
3677             else
3678             {
3679 			    const SvxBrushItem &rBack = GetFmt()->GetBackground();
3680                 // OD 07.08.2002 #99657# #GetTransChg#
3681                 //     to determine, if background has to be painted, by checking, if
3682                 //     background color is not COL_TRANSPARENT ("no fill"/"auto fill")
3683                 //     or a background graphic exists.
3684                 bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) ||
3685                                      rBack.GetGraphicPos() != GPOS_NONE;
3686             }
3687 		}
3688         // paint of margin needed.
3689         const bool bPaintMarginOnly( !bPaintCompleteBack &&
3690                                      Prt().SSize() != Frm().SSize() );
3691 
3692         // --> OD 2005-06-08 #i47804# - paint background of parent fly frame
3693         // for transparent graphics in layer Hell, if parent fly frame isn't
3694         // in layer Hell. It's only painted the intersection between the
3695         // parent fly frame area and the paint area <aRect>
3696         const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
3697 
3698         if ( bIsGraphicTransparent &&
3699             GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() &&
3700             GetAnchorFrm()->FindFlyFrm() )
3701         {
3702             const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm();
3703             if ( pParentFlyFrm->GetDrawObj()->GetLayer() !=
3704                                             pIDDMA->GetHellId() )
3705             {
3706                 SwFlyFrm* pOldRet = pRetoucheFly2;
3707                 pRetoucheFly2 = const_cast<SwFlyFrm*>(this);
3708 
3709                 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm );
3710                 const SwBorderAttrs &rAttrs = *aAccess.Get();
3711                 SwRect aPaintRect( aRect );
3712                 aPaintRect._Intersection( pParentFlyFrm->Frm() );
3713                 pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False );
3714 
3715                 pRetoucheFly2 = pOldRet;
3716             }
3717         }
3718 
3719         if ( bPaintCompleteBack || bPaintMarginOnly )
3720 		{
3721 			//#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder
3722 			//das orig. Rect bekommt, aber PaintBackground das begrenzte.
3723 
3724             // OD 2004-04-23 #116347#
3725             pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
3726             pOut->SetLineColor();
3727 
3728 			pPage = FindPageFrm();
3729 
3730 			SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3731 			const SwBorderAttrs &rAttrs = *aAccess.Get();
3732 
3733             // OD 06.08.2002 #99657# - paint border before painting background
3734             // paint border
3735             {
3736                 SwRect aTmp( rRect );
3737                 PaintBorder( aTmp, pPage, rAttrs );
3738             }
3739 
3740             // paint background
3741             {
3742                 SwRegionRects aRegion( aRect );
3743                 // --> OD 2007-12-13 #i80822#
3744                 // suppress painting of background in printing area for
3745                 // non-transparent graphics.
3746 //                if ( bPaintMarginOnly )
3747                 if ( bPaintMarginOnly ||
3748                      ( pNoTxt && !bIsGraphicTransparent ) )
3749                 // <--
3750                 {
3751                     //Was wir eigentlich Painten wollen ist der schmale Streifen
3752                     //zwischen PrtArea und aeusserer Umrandung.
3753                     SwRect aTmp( Prt() ); aTmp += Frm().Pos();
3754                     aRegion -= aTmp;
3755                 }
3756                 if ( bContour )
3757                 {
3758                     pOut->Push();
3759                     // --> OD 2007-12-13 #i80822#
3760                     // apply clip region under the same conditions, which are
3761                     // used in <SwNoTxtFrm::Paint(..)> to set the clip region
3762                     // for painting the graphic/OLE. Thus, the clip region is
3763                     // also applied for the PDF export.
3764 //                    if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER )
3765                 	ViewShell *pSh = getRootFrm()->GetCurrShell();
3766                     if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() )
3767                     // <--
3768                     {
3769                         pOut->SetClipRegion( aPoly );
3770                     }
3771                     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
3772                         PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
3773                     pOut->Pop();
3774                 }
3775                 else
3776                     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
3777                         PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
3778             }
3779 
3780 			pOut->Pop();
3781 		}
3782 	}
3783 
3784     // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and
3785     // the subsidiary lines of its lowers on its own, due to overlapping with
3786     // other fly frames or other objects.
3787     if( pGlobalShell->GetWin()
3788         && !bIsChart ) //#i102950# don't paint additional borders for charts
3789     {
3790         bool bSubsLineRectsCreated;
3791         if ( pSubsLines )
3792         {
3793             // Lock already existing subsidiary lines
3794             pSubsLines->LockLines( sal_True );
3795             bSubsLineRectsCreated = false;
3796         }
3797         else
3798         {
3799             // create new subsidiardy lines
3800             pSubsLines = new SwSubsRects;
3801             bSubsLineRectsCreated = true;
3802         }
3803 
3804         bool bSpecSubsLineRectsCreated;
3805         if ( pSpecSubsLines )
3806         {
3807             // Lock already existing special subsidiary lines
3808             pSpecSubsLines->LockLines( sal_True );
3809             bSpecSubsLineRectsCreated = false;
3810         }
3811         else
3812         {
3813             // create new special subsidiardy lines
3814             pSpecSubsLines = new SwSubsRects;
3815             bSpecSubsLineRectsCreated = true;
3816         }
3817         // Add subsidiary lines of fly frame and its lowers
3818         RefreshLaySubsidiary( pPage, aRect );
3819         // paint subsidiary lines of fly frame and its lowers
3820         pSpecSubsLines->PaintSubsidiary( pOut, NULL );
3821         pSubsLines->PaintSubsidiary( pOut, pLines );
3822         if ( !bSubsLineRectsCreated )
3823             // unlock subsidiary lines
3824             pSubsLines->LockLines( sal_False );
3825         else
3826             // delete created subsidiary lines container
3827             DELETEZ( pSubsLines );
3828 
3829         if ( !bSpecSubsLineRectsCreated )
3830             // unlock special subsidiary lines
3831             pSpecSubsLines->LockLines( sal_False );
3832         else
3833         {
3834             // delete created special subsidiary lines container
3835             DELETEZ( pSpecSubsLines );
3836         }
3837     }
3838 
3839     SwLayoutFrm::Paint( aRect );
3840 
3841     Validate();
3842 
3843     // OD 19.12.2002 #106318# - first paint lines added by fly frame paint
3844     // and then unlock other lines.
3845     pLines->PaintLines( pOut );
3846     pLines->LockLines( sal_False );
3847 
3848     pOut->Pop();
3849 
3850 	if ( pProgress && pNoTxt )
3851 		pProgress->Reschedule();
3852 }
3853 /*************************************************************************
3854 |*
3855 |*	  SwTabFrm::Paint()
3856 |*
3857 |*	  Ersterstellung	MA 11. May. 93
3858 |*	  Letzte Aenderung	MA 23. Mar. 95
3859 |*
3860 |*************************************************************************/
3861 
3862 void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3863 {
3864     if ( pGlobalShell->GetViewOptions()->IsTable() )
3865     {
3866         // --> collapsing borders FME 2005-05-27 #i29550#
3867         if ( IsCollapsingBorders() )
3868         {
3869             SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3870             const SwBorderAttrs &rAttrs = *aAccess.Get();
3871 
3872             // paint shadow
3873             if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
3874             {
3875                 SwRect aRect;
3876                 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
3877                 PaintShadow( rRect, aRect, rAttrs );
3878             }
3879 
3880             // paint lines
3881             SwTabFrmPainter aHelper( *this );
3882             aHelper.PaintLines( *pGlobalShell->GetOut(), rRect );
3883         }
3884         // <-- collapsing
3885 
3886 		SwLayoutFrm::Paint( rRect );
3887     }
3888     // OD 10.01.2003 #i6467# - no light grey rectangle for page preview
3889     else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() )
3890 	{
3891         // OD 10.01.2003 #i6467# - intersect output rectangle with table frame
3892         SwRect aTabRect( Prt() );
3893         aTabRect.Pos() += Frm().Pos();
3894         SwRect aTabOutRect( rRect );
3895         aTabOutRect.Intersection( aTabRect );
3896         pGlobalShell->GetViewOptions()->
3897                 DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY );
3898 	}
3899 	((SwTabFrm*)this)->ResetComplete();
3900 }
3901 
3902 /*************************************************************************
3903 |*
3904 |*	SwFrm::PaintShadow()
3905 |*
3906 |*	Beschreibung		Malt einen Schatten wenns das FrmFormat fordert.
3907 |* 		Der Schatten wird immer an den auesseren Rand des OutRect gemalt.
3908 |* 		Das OutRect wird ggf. so verkleinert, dass auf diesem das
3909 |* 		malen der Umrandung stattfinden kann.
3910 |*	Ersterstellung		MA 21. Dec. 92
3911 |*	Letzte Aenderung	MA 29. May. 97
3912 |*
3913 |*************************************************************************/
3914 /// OD 23.08.2002 #99657#
3915 ///     draw full shadow rectangle for frames with transparent drawn backgrounds.
3916 void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
3917                          const SwBorderAttrs &rAttrs ) const
3918 {
3919 	const SvxShadowItem &rShadow = rAttrs.GetShadow();
3920 	const long nWidth  = ::lcl_AlignWidth ( rShadow.GetWidth() );
3921 	const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() );
3922 
3923 	SwRects aRegion( 2, 2 );
3924 	SwRect aOut( rOutRect );
3925 
3926 	const sal_Bool bCnt	   = IsCntntFrm();
3927     const sal_Bool bTop    = !bCnt || rAttrs.GetTopLine  ( *(this) ) ? sal_True : sal_False;
3928     const sal_Bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? sal_True : sal_False;
3929 
3930     SvxShadowLocation eLoc = rShadow.GetLocation();
3931 
3932     SWRECTFN( this )
3933     if( IsVertical() )
3934     {
3935         switch( eLoc )
3936         {
3937             case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;  break;
3938             case SVX_SHADOW_TOPLEFT:     eLoc = SVX_SHADOW_TOPRIGHT;    break;
3939             case SVX_SHADOW_TOPRIGHT:    eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
3940             case SVX_SHADOW_BOTTOMLEFT:  eLoc = SVX_SHADOW_TOPLEFT;     break;
3941             default: break;
3942         }
3943     }
3944 
3945     /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to
3946     ///     be drawn or only two shadow rectangles beside the frame.
3947     ///     draw full shadow rectangle, if frame background is drawn transparent.
3948     ///     Status Quo:
3949     ///         SwLayoutFrm can have transparent drawn backgrounds. Thus,
3950     ///         "asked" their frame format.
3951     sal_Bool bDrawFullShadowRectangle =
3952             ( IsLayoutFrm() &&
3953               (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent()
3954             );
3955     switch ( eLoc )
3956 	{
3957 		case SVX_SHADOW_BOTTOMRIGHT:
3958 			{
3959                 if ( bDrawFullShadowRectangle )
3960                 {
3961                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
3962                     aOut.Top( aOut.Top() + nHeight );
3963                     aOut.Left( aOut.Left() + nWidth );
3964                     aRegion.Insert( aOut, aRegion.Count() );
3965                 }
3966                 else
3967                 {
3968                     aOut.Top ( aOut.Bottom() - nHeight );
3969                     aOut.Left( aOut.Left()   + nWidth );
3970                     if ( bBottom )
3971                         aRegion.Insert( aOut, aRegion.Count() );
3972                     aOut.Left( aOut.Right()   - nWidth );
3973                     aOut.Top ( rOutRect.Top() + nHeight );
3974                     if ( bBottom )
3975                         aOut.Bottom( aOut.Bottom() - nHeight );
3976                     if ( bCnt && (!bTop || !bBottom) )
3977                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3978                     aRegion.Insert( aOut, aRegion.Count() );
3979                 }
3980 
3981 				rOutRect.Right ( rOutRect.Right() - nWidth );
3982 				rOutRect.Bottom( rOutRect.Bottom()- nHeight );
3983 			}
3984 			break;
3985 		case SVX_SHADOW_TOPLEFT:
3986 			{
3987                 if ( bDrawFullShadowRectangle )
3988                 {
3989                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
3990                     aOut.Bottom( aOut.Bottom() - nHeight );
3991                     aOut.Right( aOut.Right() - nWidth );
3992                     aRegion.Insert( aOut, aRegion.Count() );
3993                 }
3994                 else
3995                 {
3996                     aOut.Bottom( aOut.Top()   + nHeight );
3997                     aOut.Right ( aOut.Right() - nWidth );
3998                     if ( bTop )
3999                         aRegion.Insert( aOut, aRegion.Count() );
4000                     aOut.Right ( aOut.Left() + nWidth );
4001                     aOut.Bottom( rOutRect.Bottom() - nHeight );
4002                     if ( bTop )
4003                         aOut.Top( aOut.Top() + nHeight );
4004                     if ( bCnt && (!bBottom || !bTop) )
4005                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
4006                     aRegion.Insert( aOut, aRegion.Count() );
4007                 }
4008 
4009 				rOutRect.Left( rOutRect.Left() + nWidth );
4010 				rOutRect.Top(  rOutRect.Top() + nHeight );
4011 			}
4012 			break;
4013 		case SVX_SHADOW_TOPRIGHT:
4014 			{
4015                 if ( bDrawFullShadowRectangle )
4016                 {
4017                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
4018                     aOut.Bottom( aOut.Bottom() - nHeight);
4019                     aOut.Left( aOut.Left() + nWidth );
4020                     aRegion.Insert( aOut, aRegion.Count() );
4021                 }
4022                 else
4023                 {
4024                     aOut.Bottom( aOut.Top() + nHeight );
4025                     aOut.Left (  aOut.Left()+ nWidth );
4026                     if ( bTop )
4027                         aRegion.Insert( aOut, aRegion.Count() );
4028                     aOut.Left  ( aOut.Right() - nWidth );
4029                     aOut.Bottom( rOutRect.Bottom() - nHeight );
4030                     if ( bTop )
4031                         aOut.Top( aOut.Top() + nHeight );
4032                     if ( bCnt && (!bBottom || bTop) )
4033                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
4034                     aRegion.Insert( aOut, aRegion.Count() );
4035                 }
4036 
4037                 rOutRect.Right( rOutRect.Right() - nWidth );
4038 				rOutRect.Top( rOutRect.Top() + nHeight );
4039 			}
4040 			break;
4041 		case SVX_SHADOW_BOTTOMLEFT:
4042 			{
4043                 if ( bDrawFullShadowRectangle )
4044                 {
4045                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
4046                     aOut.Top( aOut.Top() + nHeight );
4047                     aOut.Right( aOut.Right() - nWidth );
4048                     aRegion.Insert( aOut, aRegion.Count() );
4049                 }
4050                 else
4051                 {
4052                     aOut.Top  ( aOut.Bottom()- nHeight );
4053                     aOut.Right( aOut.Right() - nWidth );
4054                     if ( bBottom )
4055                         aRegion.Insert( aOut, aRegion.Count() );
4056                     aOut.Right( aOut.Left() + nWidth );
4057                     aOut.Top( rOutRect.Top() + nHeight );
4058                     if ( bBottom )
4059                         aOut.Bottom( aOut.Bottom() - nHeight );
4060                     if ( bCnt && (!bTop || !bBottom) )
4061                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
4062                     aRegion.Insert( aOut, aRegion.Count() );
4063                 }
4064 
4065 				rOutRect.Left( rOutRect.Left() + nWidth );
4066 				rOutRect.Bottom( rOutRect.Bottom() - nHeight );
4067 			}
4068 			break;
4069         default:
4070             ASSERT( !this, "new ShadowLocation() ?" )
4071             break;
4072     }
4073 
4074 	OutputDevice *pOut = pGlobalShell->GetOut();
4075 
4076     sal_uLong nOldDrawMode = pOut->GetDrawMode();
4077     Color aShadowColor( rShadow.GetColor() );
4078     if( aRegion.Count() && pGlobalShell->GetWin() &&
4079         Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4080     {
4081         // Is heigh contrast mode, the output device has already set the
4082         // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function
4083         // to ignore the setting of a new color. Therefore we have to reset
4084         // the drawing mode
4085         pOut->SetDrawMode( 0 );
4086         aShadowColor = SwViewOption::GetFontColor();
4087     }
4088 
4089     if ( pOut->GetFillColor() != aShadowColor )
4090         pOut->SetFillColor( aShadowColor );
4091 
4092     pOut->SetDrawMode( nOldDrawMode );
4093 
4094 	for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
4095 	{
4096 		SwRect &rOut = aRegion[i];
4097 		aOut = rOut;
4098         // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle
4099         // no alignment necessary, because (1) <rRect> is already aligned
4100         // and because (2) paint of border and background will occur later.
4101         // Thus, (1) assures that no conflicts with neighbour object will occure
4102         // and (2) assures that border and background is not affected by the
4103         // shadow paint.
4104         /*
4105         ::SwAlignRect( aOut, pGlobalShell );
4106         */
4107 		if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
4108 		{
4109 			aOut._Intersection( rRect );
4110 			pOut->DrawRect( aOut.SVRect() );
4111 		}
4112 	}
4113 }
4114 
4115 /*************************************************************************
4116 |*
4117 |*	SwFrm::PaintBorderLine()
4118 |*
4119 |*	Ersterstellung		MA 22. Dec. 92
4120 |*	Letzte Aenderung	MA 22. Jan. 95
4121 |*
4122 |*************************************************************************/
4123 
4124 void SwFrm::PaintBorderLine( const SwRect& rRect,
4125 							 const SwRect& rOutRect,
4126 							 const SwPageFrm* /*pPage*/,
4127 							 const Color *pColor ) const
4128 {
4129 	if ( !rOutRect.IsOver( rRect ) )
4130 		return;
4131 
4132 	SwRect aOut( rOutRect );
4133 	aOut._Intersection( rRect );
4134 
4135 	const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0;
4136     sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB :
4137                    ( IsInSct() ? SUBCOL_SECT :
4138                    ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
4139     if( pColor && pGlobalShell->GetWin() &&
4140         Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4141     {
4142         pColor = &SwViewOption::GetFontColor();
4143     }
4144 
4145 	//if ( pPage->GetSortedObjs() )
4146 	//{
4147 	//	SwRegionRects aRegion( aOut, 4, 1 );
4148 	//	::lcl_SubtractFlys( this, pPage, aOut, aRegion );
4149 	//	for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
4150     //        pLines->AddLineRect( aRegion[i], pColor, pTab, nSubCol );
4151 	//}
4152 	//else
4153         pLines->AddLineRect( aOut, pColor, pTab, nSubCol );
4154 }
4155 
4156 /*************************************************************************
4157 |*
4158 |*	SwFrm::PaintBorderLines()
4159 |*
4160 |*	Beschreibung		Nur alle Linien einfach oder alle Linien doppelt!!!!
4161 |*	Ersterstellung		MA 22. Dec. 92
4162 |*	Letzte Aenderung	MA 22. Mar. 95
4163 |*
4164 |*************************************************************************/
4165 
4166 // OD 29.04.2003 #107169# - method called for left and right border rectangles.
4167 // For a printer output device perform adjustment for non-overlapping top and
4168 // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate
4169 // printer output device.
4170 // NOTE: For printer output device left/right border rectangle <_iorRect>
4171 //       has to be already non-overlapping the outer top/bottom border rectangle.
4172 void MA_FASTCALL lcl_SubTopBottom( SwRect&              _iorRect,
4173                                    const SvxBoxItem&    _rBox,
4174                                    const SwBorderAttrs& _rAttrs,
4175                                    const SwFrm&         _rFrm,
4176                                    const SwRectFn&      _rRectFn,
4177                                    const sal_Bool       _bPrtOutputDev )
4178 {
4179     const sal_Bool bCnt = _rFrm.IsCntntFrm();
4180     if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() &&
4181          ( !bCnt || _rAttrs.GetTopLine( _rFrm ) )
4182        )
4183 	{
4184         // substract distance between outer and inner line.
4185         SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() );
4186         // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4187         // adjust x-/y-position, if inner top line is a hair line (width = 1)
4188         sal_Bool bIsInnerTopLineHairline = sal_False;
4189         if ( !_bPrtOutputDev )
4190         {
4191             // additionally substract width of top outer line
4192             // --> left/right inner/outer line doesn't overlap top outer line.
4193             nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() );
4194         }
4195         else
4196         {
4197             // OD 29.04.2003 #107169# - additionally substract width of top inner line
4198             // --> left/right inner/outer line doesn't overlap top inner line.
4199             nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() );
4200             bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1;
4201         }
4202         (_iorRect.*_rRectFn->fnSubTop)( -nDist );
4203         // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line
4204         // is a hair line
4205         if ( bIsInnerTopLineHairline )
4206         {
4207             if ( _rFrm.IsVertical() )
4208             {
4209                 // right of border rectangle has to be checked and adjusted
4210                 Point aCompPt( _iorRect.Right(), 0 );
4211                 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4212                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4213                                           aRefPt, aCompPt,
4214                                           sal_True, -1 );
4215                 _iorRect.Right( aCompPt.X() );
4216             }
4217             else
4218             {
4219                 // top of border rectangle has to be checked and adjusted
4220                 Point aCompPt( 0, _iorRect.Top() );
4221                 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4222                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4223                                           aRefPt, aCompPt,
4224                                           sal_False, +1 );
4225                 _iorRect.Top( aCompPt.Y() );
4226             }
4227         }
4228 	}
4229 
4230     if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() &&
4231          ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) )
4232        )
4233 	{
4234         // substract distance between outer and inner line.
4235         SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() );
4236         // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4237         // adjust x-/y-position, if inner bottom line is a hair line (width = 1)
4238         sal_Bool bIsInnerBottomLineHairline = sal_False;
4239         if ( !_bPrtOutputDev )
4240         {
4241             // additionally substract width of bottom outer line
4242             // --> left/right inner/outer line doesn't overlap bottom outer line.
4243             nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() );
4244         }
4245         else
4246         {
4247             // OD 29.04.2003 #107169# - additionally substract width of bottom inner line
4248             // --> left/right inner/outer line doesn't overlap bottom inner line.
4249             nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() );
4250             bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1;
4251         }
4252         (_iorRect.*_rRectFn->fnAddBottom)( -nDist );
4253         // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner
4254         // bottom line is a hair line.
4255         if ( bIsInnerBottomLineHairline )
4256         {
4257             if ( _rFrm.IsVertical() )
4258             {
4259                 // left of border rectangle has to be checked and adjusted
4260                 Point aCompPt( _iorRect.Left(), 0 );
4261                 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4262                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4263                                           aRefPt, aCompPt,
4264                                           sal_True, +1 );
4265                 _iorRect.Left( aCompPt.X() );
4266             }
4267             else
4268             {
4269                 // bottom of border rectangle has to be checked and adjusted
4270                 Point aCompPt( 0, _iorRect.Bottom() );
4271                 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4272                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4273                                           aRefPt, aCompPt,
4274                                           sal_False, -1 );
4275                 _iorRect.Bottom( aCompPt.Y() );
4276             }
4277         }
4278 	}
4279 }
4280 
4281 // method called for top and bottom border rectangles.
4282 void MA_FASTCALL lcl_SubLeftRight( SwRect&           rRect,
4283                                    const SvxBoxItem& rBox,
4284                                    const SwRectFn&   rRectFn )
4285 {
4286 	if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() )
4287 	{
4288         const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() )
4289                            + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() );
4290         (rRect.*rRectFn->fnSubLeft)( -nDist );
4291 	}
4292 
4293 	if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() )
4294 	{
4295         const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() )
4296                            + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() );
4297         (rRect.*rRectFn->fnAddRight)( -nDist );
4298 	}
4299 }
4300 
4301 // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine>
4302 // into new method <lcl_PaintLeftRightLine(..)>
4303 void lcl_PaintLeftRightLine( const sal_Bool         _bLeft,
4304                              const SwFrm&           _rFrm,
4305                              const SwPageFrm&       _rPage,
4306                              const SwRect&          _rOutRect,
4307                              const SwRect&          _rRect,
4308                              const SwBorderAttrs&   _rAttrs,
4309                              const SwRectFn&        _rRectFn )
4310 {
4311     const SvxBoxItem& rBox = _rAttrs.GetBox();
4312     const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft();
4313     const SvxBorderLine* pLeftRightBorder = 0;
4314     if ( _bLeft )
4315     {
4316         pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft();
4317     }
4318     else
4319     {
4320         pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight();
4321     }
4322     // OD 06.05.2003 #107169# - init boolean indicating printer output device.
4323     const sal_Bool bPrtOutputDev =
4324             ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() );
4325 
4326     if ( !pLeftRightBorder )
4327     {
4328         return;
4329     }
4330 
4331     SwRect aRect( _rOutRect );
4332     if ( _bLeft )
4333     {
4334         (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4335                                        (aRect.*_rRectFn->fnGetWidth)() );
4336     }
4337     else
4338     {
4339         (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4340                                       (aRect.*_rRectFn->fnGetWidth)() );
4341     }
4342 
4343     const sal_Bool bCnt = _rFrm.IsCntntFrm();
4344 
4345     if ( bCnt )
4346     {
4347         ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn );
4348     }
4349 
4350     // OD 06.05.2003 #107169# - adjustments for printer output device
4351     if ( bPrtOutputDev )
4352     {
4353         // substract width of outer top line.
4354         if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) )
4355         {
4356             long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() );
4357             (aRect.*_rRectFn->fnSubTop)( -nDist );
4358             // OD 19.05.2003 #109667# - If outer top line is hair line, calculated
4359             // top has to be adjusted.
4360             if ( nDist == 1 )
4361             {
4362                 if ( _rFrm.IsVertical() )
4363                 {
4364                     // right of border rectangle has to be checked and adjusted
4365                     Point aCompPt( aRect.Right(), 0 );
4366                     Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4367                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4368                                               aRefPt, aCompPt,
4369                                               sal_True, -1 );
4370                     aRect.Right( aCompPt.X() );
4371                 }
4372                 else
4373                 {
4374                     // top of border rectangle has to be checked and adjusted
4375                     Point aCompPt( 0, aRect.Top() );
4376                     Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4377                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4378                                               aRefPt, aCompPt,
4379                                               sal_False, +1 );
4380                     aRect.Top( aCompPt.Y() );
4381                 }
4382             }
4383         }
4384         // substract width of outer bottom line.
4385         if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) )
4386         {
4387             long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth());
4388             (aRect.*_rRectFn->fnAddBottom)( -nDist );
4389             // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated
4390             // top has to be adjusted.
4391             if ( nDist == 1 )
4392             {
4393                 if ( _rFrm.IsVertical() )
4394                 {
4395                     // left of border rectangle has to be checked and adjusted
4396                     Point aCompPt( aRect.Left(), 0 );
4397                     Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4398                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4399                                               aRefPt, aCompPt,
4400                                               sal_True, +1 );
4401                     aRect.Left( aCompPt.X() );
4402                 }
4403                 else
4404                 {
4405                     // bottom of border rectangle has to be checked and adjusted
4406                     Point aCompPt( 0, aRect.Bottom() );
4407                     Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4408                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4409                                               aRefPt, aCompPt,
4410                                               sal_False, -1 );
4411                     aRect.Bottom( aCompPt.Y() );
4412                 }
4413             }
4414         }
4415     }
4416 
4417     if ( !pLeftRightBorder->GetInWidth() )
4418     {
4419         // OD 06.05.2003 #107169# - add 6th parameter
4420         ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4421     }
4422 
4423     // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4424     {
4425         SwRect aPaintRect( aRect );
4426         ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4427         // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4428         // to the prior left postion with width of one twip.
4429         if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4430         {
4431             if ( _bLeft )
4432             {
4433                 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4434                 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4435                 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4436             }
4437             else
4438             {
4439                 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4440                 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4441                 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4442             }
4443         }
4444         _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4445     }
4446 
4447     if ( pLeftRightBorder->GetInWidth() )
4448     {
4449         const long nDist = ::lcl_MinWidthDist( pLeftRightBorder->GetDistance() );
4450         long nWidth = ::lcl_AlignWidth( pLeftRightBorder->GetInWidth() );
4451         if ( _bLeft )
4452         {
4453             (aRect.*_rRectFn->fnAddRight)( nDist + nWidth );
4454             (aRect.*_rRectFn->fnSubLeft)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4455         }
4456         else
4457         {
4458             (aRect.*_rRectFn->fnSubLeft)( nDist + nWidth );
4459             (aRect.*_rRectFn->fnAddRight)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4460         }
4461         // OD 06.05.2003 #107169# - add 6th parameter
4462         ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4463         // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4464         {
4465             SwRect aPaintRect( aRect );
4466             ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4467             // if <SwAlignRect> reveals rectangle with no width, adjust
4468             // rectangle to the prior left postion with width of one twip.
4469             if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4470             {
4471                 if ( _bLeft )
4472                 {
4473                     (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4474                     (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4475                     (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4476                 }
4477                 else
4478                 {
4479                     (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4480                     (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4481                     (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4482                 }
4483             }
4484             _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4485         }
4486     }
4487 }
4488 
4489 // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine>
4490 // into <lcl_PaintTopLine>
4491 void lcl_PaintTopBottomLine( const sal_Bool         _bTop,
4492                              const SwFrm&           _rFrm,
4493                              const SwPageFrm&       _rPage,
4494                              const SwRect&          _rOutRect,
4495                              const SwRect&          _rRect,
4496                              const SwBorderAttrs&   _rAttrs,
4497                              const SwRectFn&        _rRectFn )
4498 {
4499     const SvxBoxItem& rBox = _rAttrs.GetBox();
4500     const SvxBorderLine* pTopBottomBorder = 0;
4501     if ( _bTop )
4502     {
4503         pTopBottomBorder = rBox.GetTop();
4504     }
4505     else
4506     {
4507         pTopBottomBorder = rBox.GetBottom();
4508     }
4509 
4510     if ( !pTopBottomBorder )
4511     {
4512 		return;
4513     }
4514 
4515     SwRect aRect( _rOutRect );
4516     if ( _bTop )
4517     {
4518         (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4519                                         (aRect.*_rRectFn->fnGetHeight)() );
4520     }
4521     else
4522     {
4523         (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4524                                      (aRect.*_rRectFn->fnGetHeight)() );
4525     }
4526 
4527     // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4528     {
4529         SwRect aPaintRect( aRect );
4530         ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4531         // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4532         // to the prior top postion with width of one twip.
4533         if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4534         {
4535             if ( _bTop )
4536             {
4537                 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4538                 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4539                 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4540             }
4541             else
4542             {
4543                 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4544                 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4545                 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4546             }
4547         }
4548         _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4549     }
4550 
4551     if ( pTopBottomBorder->GetInWidth() )
4552 	{
4553         const long nDist = ::lcl_MinHeightDist( pTopBottomBorder->GetDistance() );
4554         const long nHeight = ::lcl_AlignHeight( pTopBottomBorder->GetInWidth() );
4555         if ( _bTop )
4556         {
4557             (aRect.*_rRectFn->fnAddBottom)( nDist + nHeight );
4558             (aRect.*_rRectFn->fnSubTop)( nHeight - (aRect.*_rRectFn->fnGetHeight)() );
4559         }
4560         else
4561         {
4562             (aRect.*_rRectFn->fnSubTop)( nDist + nHeight );
4563             (aRect.*_rRectFn->fnAddBottom)( nHeight -(aRect.*_rRectFn->fnGetHeight)() );
4564         }
4565         ::lcl_SubLeftRight( aRect, rBox, _rRectFn );
4566         // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4567         {
4568             SwRect aPaintRect( aRect );
4569             ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4570             // if <SwAlignRect> reveals rectangle with no width, adjust
4571             // rectangle to the prior top postion with width of one twip.
4572             if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4573             {
4574                 if ( _bTop )
4575                 {
4576                     (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4577                     (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4578                     (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4579                 }
4580                 else
4581                 {
4582                     (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4583                     (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4584                     (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4585                 }
4586             }
4587             _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4588         }
4589 	}
4590 }
4591 
4592 
4593 /*************************************************************************
4594 |*
4595 |*  const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4596 |*
4597 |* No comment. #i15844#
4598 |*
4599 |*************************************************************************/
4600 
4601 const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4602 {
4603     ASSERT( rFrm.IsCellFrm(),
4604             "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" )
4605 
4606     const SwFrm* pTmpFrm = &rFrm;
4607     do
4608     {
4609         if ( pTmpFrm->GetNext() )
4610             return pTmpFrm->GetNext();
4611 
4612         pTmpFrm = pTmpFrm->GetUpper()->GetUpper();
4613     }
4614     while ( pTmpFrm->IsCellFrm() );
4615 
4616     return 0;
4617 }
4618 
4619 
4620 /*************************************************************************
4621 |*
4622 |*	SwFrm::PaintBorder()
4623 |*
4624 |*	Beschreibung		Malt Schatten und Umrandung
4625 |*	Ersterstellung		MA 23.01.92
4626 |*	Letzte Aenderung	MA 29. Jul. 96
4627 |*
4628 |*************************************************************************/
4629 
4630 /** local method to determine cell frame, from which the border attributes
4631     for paint of top/bottom border has to be used.
4632 
4633     OD 21.02.2003 #b4779636#, #107692#
4634 
4635     @author OD
4636 
4637 
4638     @param _pCellFrm
4639     input parameter - constant pointer to cell frame for which the cell frame
4640     for the border attributes has to be determined.
4641 
4642     @param _rCellBorderAttrs
4643     input parameter - constant reference to the border attributes of cell frame
4644     <_pCellFrm>.
4645 
4646     @param _bTop
4647     input parameter - boolean, that controls, if cell frame for top border or
4648     for bottom border has to be determined.
4649 
4650     @return constant pointer to cell frame, for which the border attributes has
4651     to be used
4652 */
4653 const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm*         _pCellFrm,
4654                                            const SwBorderAttrs& _rCellBorderAttrs,
4655                                            const bool           _bTop )
4656 {
4657     ASSERT( _pCellFrm, "No cell frame available, dying soon" )
4658 
4659     // determine, if cell frame is at bottom/top border of a table frame and
4660     // the table frame has/is a follow.
4661     const SwFrm* pTmpFrm = _pCellFrm;
4662     bool bCellAtBorder = true;
4663     bool bCellAtLeftBorder = !_pCellFrm->GetPrev();
4664     bool bCellAtRightBorder = !_pCellFrm->GetNext();
4665     while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() )
4666     {
4667         pTmpFrm = pTmpFrm->GetUpper();
4668         if ( pTmpFrm->IsRowFrm() &&
4669              (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext())
4670            )
4671         {
4672             bCellAtBorder = false;
4673         }
4674         if ( pTmpFrm->IsCellFrm() )
4675         {
4676             if ( pTmpFrm->GetPrev() )
4677             {
4678                 bCellAtLeftBorder = false;
4679             }
4680             if ( pTmpFrm->GetNext() )
4681             {
4682                 bCellAtRightBorder = false;
4683             }
4684         }
4685     }
4686     ASSERT( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" );
4687 
4688     const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm);
4689     const SwTabFrm* pParentTabFrm =
4690             static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper());
4691 
4692     const bool bCellNeedsAttribute = bCellAtBorder &&
4693                                      ( _bTop ?
4694                                       // bCellInFirstRowWithMaster
4695                                        ( !pParentRowFrm->GetPrev() &&
4696                                          pParentTabFrm->IsFollow() &&
4697                                          0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) :
4698                                       // bCellInLastRowWithFollow
4699                                        ( !pParentRowFrm->GetNext() &&
4700                                          pParentTabFrm->GetFollow() )
4701                                      );
4702 
4703     const SwFrm* pRet = _pCellFrm;
4704     if ( bCellNeedsAttribute )
4705     {
4706         // determine, if cell frame has no borders inside the table.
4707         const SwFrm* pNextCell = 0;
4708         bool bNoBordersInside = false;
4709 
4710         if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) )
4711         {
4712             SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell );
4713             const SwBorderAttrs &rBorderAttrs = *aAccess.Get();
4714             const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox();
4715             bCellAtRightBorder = !lcl_HasNextCell( *pNextCell );
4716             bNoBordersInside =
4717                 ( !rBorderBox.GetTop()    || !pParentRowFrm->GetPrev() ) &&
4718                   !rBorderBox.GetLeft() &&
4719                 ( !rBorderBox.GetRight()  || bCellAtRightBorder ) &&
4720                 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4721         }
4722         else
4723         {
4724             const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox();
4725             bNoBordersInside =
4726                 ( !rBorderBox.GetTop()    || !pParentRowFrm->GetPrev() ) &&
4727                 ( !rBorderBox.GetLeft()   || bCellAtLeftBorder ) &&
4728                 ( !rBorderBox.GetRight()  || bCellAtRightBorder ) &&
4729                 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4730         }
4731 
4732         if ( bNoBordersInside )
4733         {
4734             if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() )
4735             {
4736                 // #b4779636#-hack:
4737                 // Cell frame has no top border and no border inside the table, but
4738                 // it is at the top border of a table frame, which is a follow.
4739                 // Thus, use border attributes of cell frame in first row of complete table.
4740                 // First, determine first table frame of complete table.
4741                 SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true );
4742                 // determine first row of complete table.
4743                 const SwFrm* pFirstRow = pMasterTabFrm->GetLower();
4744                 // return first cell in first row
4745                 SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower());
4746                 while ( !pLowerCell->IsCellFrm() ||
4747                         ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4748                       )
4749                 {
4750                     pLowerCell = pLowerCell->GetLower();
4751                 }
4752                 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4753                 pRet = pLowerCell;
4754             }
4755             else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() )
4756             {
4757                 // #b4779636#-hack:
4758                 // Cell frame has no bottom border and no border inside the table,
4759                 // but it is at the bottom border of a table frame, which has a follow.
4760                 // Thus, use border attributes of cell frame in last row of complete table.
4761                 // First, determine last table frame of complete table.
4762                 SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow());
4763                 while ( pLastTabFrm->GetFollow() )
4764                 {
4765                     pLastTabFrm = pLastTabFrm->GetFollow();
4766                 }
4767                 // determine last row of complete table.
4768                 SwFrm* pLastRow = pLastTabFrm->GetLastLower();
4769                 // return first bottom border cell in last row
4770                 SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower());
4771                 while ( !pLowerCell->IsCellFrm() ||
4772                         ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4773                       )
4774                 {
4775                     if ( pLowerCell->IsRowFrm() )
4776                     {
4777                         while ( pLowerCell->GetNext() )
4778                         {
4779                             pLowerCell = pLowerCell->GetNext();
4780                         }
4781                     }
4782                     pLowerCell = pLowerCell->GetLower();
4783                 }
4784                 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4785                 pRet = pLowerCell;
4786             }
4787         }
4788     }
4789 
4790     return pRet;
4791 }
4792 
4793 void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4794 						 const SwBorderAttrs &rAttrs ) const
4795 {
4796     //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun
4797     if ( (GetType() & 0x90C5) || (Prt().SSize() == Frm().SSize()) )
4798         return;
4799 
4800 	if ( (GetType() & 0x2000) && 	//Cell
4801 		 !pGlobalShell->GetViewOptions()->IsTable() )
4802 		return;
4803 
4804     // --> collapsing borders FME 2005-05-27 #i29550#
4805     if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
4806     {
4807         const SwTabFrm* pTabFrm = FindTabFrm();
4808         if ( pTabFrm->IsCollapsingBorders() )
4809             return;
4810 
4811         if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) )
4812             return;
4813     }
4814     // <--
4815 
4816     const bool bLine = rAttrs.IsLine() ? true : false;
4817     const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE;
4818 
4819     // OD 24.02.2003 #b4779636#, #107692# - flag to control,
4820     // if #b4779636#-hack has to be used.
4821     const bool bb4779636HackActive = true;
4822     // OD 21.02.2003 #b4779636#, #107692#
4823     const SwFrm* pCellFrmForBottomBorderAttrs = 0;
4824     const SwFrm* pCellFrmForTopBorderAttrs = 0;
4825     bool         bFoundCellForTopOrBorderAttrs = false;
4826     if ( bb4779636HackActive && IsCellFrm() )
4827     {
4828         pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false );
4829         if ( pCellFrmForBottomBorderAttrs != this )
4830             bFoundCellForTopOrBorderAttrs = true;
4831         pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true );
4832         if ( pCellFrmForTopBorderAttrs != this )
4833             bFoundCellForTopOrBorderAttrs = true;
4834     }
4835 
4836     // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4837     // for #b4779636#-hack
4838     if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs )
4839 	{
4840 		//Wenn das Rechteck vollstandig innerhalb der PrtArea liegt,
4841 		//so braucht kein Rand gepainted werden.
4842 		//Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden,
4843 		//anderfalls wuerden u.U. Teile nicht verarbeitet.
4844 		SwRect aRect( Prt() );
4845 		aRect += Frm().Pos();
4846 		::SwAlignRect( aRect, pGlobalShell );
4847         // OD 27.09.2002 #103636# - new local boolean variable in order to
4848         // suspend border paint under special cases - see below.
4849         // NOTE: This is a fix for the implementation of feature #99657#.
4850         bool bDrawOnlyShadowForTransparentFrame = false;
4851         if ( aRect.IsInside( rRect ) )
4852         {
4853             // OD 27.09.2002 #103636# - paint shadow, if background is transparent.
4854             // Because of introduced transparent background for fly frame #99657#,
4855             // the shadow have to be drawn if the background is transparent,
4856             // in spite the fact that the paint rectangle <rRect> lies fully
4857             // in the printing area.
4858             // NOTE to chosen solution:
4859             //     On transparent background, continue processing, but suspend
4860             //     drawing of border by setting <bDrawOnlyShadowForTransparentFrame>
4861             //     to true.
4862             if ( IsLayoutFrm() &&
4863                  static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() )
4864             {
4865                  bDrawOnlyShadowForTransparentFrame = true;
4866             }
4867             else
4868             {
4869                 return;
4870             }
4871         }
4872 
4873 		if ( !pPage )
4874 			pPage = FindPageFrm();
4875 
4876 		::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
4877 		rAttrs.SetGetCacheLine( sal_True );
4878 		if ( bShadow )
4879             PaintShadow( rRect, aRect, rAttrs );
4880         // OD 27.09.2002 #103636# - suspend drawing of border
4881         // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
4882         // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4883         // for #b4779636#-hack.
4884         if ( ( bLine || bFoundCellForTopOrBorderAttrs ) &&
4885              !bDrawOnlyShadowForTransparentFrame )
4886 		{
4887             const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this;
4888             SWRECTFN( pDirRefFrm )
4889             // OD 19.05.2003 #109667# - use new method <lcl_PaintLeftRightLine(..)>
4890             //::lcl_PaintLeftLine  ( this, pPage, aRect, rRect, rAttrs, fnRect );
4891             //::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs, fnRect );
4892             ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4893             ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4894             if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) )
4895             {
4896                 // OD 21.02.2003 #b4779636#, #107692# -
4897                 // #b4779636#-hack: If another cell frame for top border
4898                 // paint is found, paint its top border.
4899                 if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this )
4900                 {
4901                     SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4902                                                 pCellFrmForTopBorderAttrs );
4903                     const SwBorderAttrs &rTopAttrs = *aAccess.Get();
4904                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4905                     //::lcl_PaintTopLine( this, pPage, aRect, rRect, rTopAttrs, fnRect );
4906                     ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect );
4907                 }
4908                 else
4909                 {
4910                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4911                     //::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs, fnRect );
4912                     ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4913                 }
4914             }
4915             if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) )
4916             {
4917                 // OD 21.02.2003 #b4779636#, #107692# -
4918                 // #b4779636#-hack: If another cell frame for bottom border
4919                 // paint is found, paint its bottom border.
4920                 if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this )
4921                 {
4922                     SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4923                                                 pCellFrmForBottomBorderAttrs );
4924                     const SwBorderAttrs &rBottomAttrs = *aAccess.Get();
4925                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4926                     //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rBottomAttrs, fnRect);
4927                     ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect);
4928                 }
4929                 else
4930                 {
4931                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4932                     //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rAttrs, fnRect);
4933                     ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect);
4934                 }
4935             }
4936 		}
4937 		rAttrs.SetGetCacheLine( sal_False );
4938 	}
4939 }
4940 /*************************************************************************
4941 |*
4942 |*	SwFtnContFrm::PaintBorder()
4943 |*
4944 |*	Beschreibung		Spezialimplementierung wg. der Fussnotenlinie.
4945 |* 		Derzeit braucht nur der obere Rand beruecksichtigt werden.
4946 |* 		Auf andere Linien und Schatten wird verzichtet.
4947 |*	Ersterstellung		MA 27. Feb. 93
4948 |*	Letzte Aenderung	MA 08. Sep. 93
4949 |*
4950 |*************************************************************************/
4951 
4952 void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4953 								const SwBorderAttrs & ) const
4954 {
4955 	//Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es
4956 	//keinen Rand zu painten.
4957 	SwRect aRect( Prt() );
4958 	aRect.Pos() += Frm().Pos();
4959 	if ( !aRect.IsInside( rRect ) )
4960 		PaintLine( rRect, pPage );
4961 }
4962 /*************************************************************************
4963 |*
4964 |*	SwFtnContFrm::PaintLine()
4965 |*
4966 |*	Beschreibung		Fussnotenline malen.
4967 |*	Ersterstellung		MA 02. Mar. 93
4968 |*	Letzte Aenderung	MA 28. Mar. 94
4969 |*
4970 |*************************************************************************/
4971 
4972 void SwFtnContFrm::PaintLine( const SwRect& rRect,
4973 							  const SwPageFrm *pPage ) const
4974 {
4975 	//Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc.
4976 	//Die Position ist ebenfalls am PageDesc angegeben.
4977 	//Der Pen steht direkt im PageDesc.
4978 
4979 	if ( !pPage )
4980 		pPage = FindPageFrm();
4981 	const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
4982 
4983     SWRECTFN( this )
4984     SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)();
4985     Fraction aFract( nPrtWidth, 1 );
4986 	const SwTwips nWidth = (long)(aFract *= rInf.GetWidth());
4987 
4988     SwTwips nX = (this->*fnRect->fnGetPrtLeft)();
4989 	switch ( rInf.GetAdj() )
4990 	{
4991 		case FTNADJ_CENTER:
4992             nX += nPrtWidth/2 - nWidth/2; break;
4993 		case FTNADJ_RIGHT:
4994             nX += nPrtWidth - nWidth; break;
4995 		case FTNADJ_LEFT:
4996 			/* do nothing */; break;
4997 		default:
4998 			ASSERT( !this, "Neues Adjustment fuer Fussnotenlinie?" );
4999 	}
5000     SwTwips nLineWidth = rInf.GetLineWidth();
5001     const SwRect aLineRect = bVert ?
5002         SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth,
5003                       nX), Size( nLineWidth, nWidth ) )
5004             : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ),
5005                             Size( nWidth, rInf.GetLineWidth()));
5006 	if ( aLineRect.HasArea() )
5007 		PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() );
5008 }
5009 
5010 /*************************************************************************
5011 |*
5012 |*	SwLayoutFrm::PaintColLines()
5013 |*
5014 |*	Beschreibung		Painted die Trennlinien fuer die innenliegenden
5015 |* 						Spalten.
5016 |*	Ersterstellung		MA 21. Jun. 93
5017 |*	Letzte Aenderung	MA 28. Mar. 94
5018 |*
5019 |*************************************************************************/
5020 
5021 void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol,
5022 								 const SwPageFrm *pPage ) const
5023 {
5024 	const SwFrm *pCol = Lower();
5025 	if ( !pCol || !pCol->IsColumnFrm() )
5026 		return;
5027 	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
5028     SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
5029 
5030     SwRect aLineRect = Prt();
5031     aLineRect += Frm().Pos();
5032 
5033     SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight())
5034                    / 100 - (aLineRect.*fnRect->fnGetHeight)();
5035     SwTwips nBottom = 0;
5036 
5037 	switch ( rFmtCol.GetLineAdj() )
5038 	{
5039 		case COLADJ_CENTER:
5040             nBottom = nTop / 2; nTop -= nBottom; break;
5041 		case COLADJ_TOP:
5042             nBottom = nTop; nTop = 0; break;
5043 		case COLADJ_BOTTOM:
5044             break;
5045 		default:
5046 			ASSERT( !this, "Neues Adjustment fuer Spaltenlinie?" );
5047 	}
5048 
5049     if( nTop )
5050         (aLineRect.*fnRect->fnSubTop)( nTop );
5051     if( nBottom )
5052         (aLineRect.*fnRect->fnAddBottom)( nBottom );
5053 
5054     SwTwips nPenHalf = rFmtCol.GetLineWidth();
5055     (aLineRect.*fnRect->fnSetWidth)( nPenHalf );
5056     nPenHalf /= 2;
5057 
5058     //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein.
5059 	SwRect aRect( rRect );
5060     (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW );
5061     (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW );
5062     SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight;
5063 	while ( pCol->GetNext() )
5064 	{
5065         (aLineRect.*fnRect->fnSetPosX)
5066             ( (pCol->Frm().*fnGetX)() - nPenHalf );
5067 		if ( aRect.IsOver( aLineRect ) )
5068             PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor());
5069 		pCol = pCol->GetNext();
5070 	}
5071 }
5072 
5073 void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const
5074 {
5075     if( !bHasGrid || pRetoucheFly || pRetoucheFly2 )
5076         return;
5077     GETGRID( this )
5078     if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ?
5079         pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) )
5080     {
5081         const SwLayoutFrm* pBody = FindBodyCont();
5082         if( pBody )
5083         {
5084             SwRect aGrid( pBody->Prt() );
5085             aGrid += pBody->Frm().Pos();
5086 
5087             SwRect aInter( aGrid );
5088             aInter.Intersection( rRect );
5089             if( aInter.HasArea() )
5090             {
5091                 sal_Bool bGrid = pGrid->GetRubyTextBelow();
5092                 sal_Bool bCell = GRID_LINES_CHARS == pGrid->GetGridType();
5093                 long nGrid = pGrid->GetBaseHeight();
5094 				const SwDoc* pDoc = GetFmt()->GetDoc();
5095                 long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor
5096                 long nRuby = pGrid->GetRubyHeight();
5097                 long nSum = nGrid + nRuby;
5098                 const Color *pCol = &pGrid->GetColor();
5099 
5100                 SwTwips nRight = aInter.Left() + aInter.Width();
5101                 SwTwips nBottom = aInter.Top() + aInter.Height();
5102                 if( IsVertical() )
5103                 {
5104                     SwTwips nOrig = aGrid.Left() + aGrid.Width();
5105                     SwTwips nY = nOrig + nSum *
5106                                  ( ( nOrig - aInter.Left() ) / nSum );
5107                     SwRect aTmp( Point( nY, aInter.Top() ),
5108                                 Size( 1, aInter.Height() ) );
5109                     SwTwips nX = aGrid.Top() + nGrid *
5110                                 ( ( aInter.Top() - aGrid.Top() )/ nGrid );
5111                     if( nX < aInter.Top() )
5112                         nX += nGrid;
5113                     SwTwips nGridBottom = aGrid.Top() + aGrid.Height();
5114                     sal_Bool bLeft = aGrid.Top() >= aInter.Top();
5115                     sal_Bool bRight = nGridBottom <= nBottom;
5116                     sal_Bool bBorder = bLeft || bRight;
5117                     while( nY > nRight )
5118                     {
5119                         aTmp.Pos().X() = nY;
5120                         if( bGrid )
5121                         {
5122                             nY -= nGrid;
5123                             SwTwips nPosY = Max( aInter.Left(), nY );
5124                             SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY;
5125                             if( nHeight > 0 )
5126                             {
5127                                 if( bCell )
5128                                 {
5129                                     SwRect aVert( Point( nPosY, nX ),
5130                                                 Size( nHeight, 1 ) );
5131                                     while( aVert.Top() <= nBottom )
5132                                     {
5133                                         PaintBorderLine(rRect,aVert,this,pCol);
5134                                         aVert.Pos().Y() += nGrid;
5135                                     }
5136                                 }
5137                                 else if( bBorder )
5138                                 {
5139                                     SwRect aVert( Point( nPosY, aGrid.Top() ),
5140                                                   Size( nHeight, 1 ) );
5141                                     if( bLeft )
5142                                         PaintBorderLine(rRect,aVert,this,pCol);
5143                                     if( bRight )
5144                                     {
5145                                         aVert.Pos().Y() = nGridBottom;
5146                                         PaintBorderLine(rRect,aVert,this,pCol);
5147                                     }
5148                                 }
5149                             }
5150                         }
5151                         else
5152                         {
5153                             nY -= nRuby;
5154                             if( bBorder )
5155                             {
5156                                 SwTwips nPos = Max( aInter.Left(), nY );
5157                                 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5158                                 SwRect aVert( Point( nPos, aGrid.Top() ),
5159                                               Size( nW, 1 ) );
5160                                 if( nW > 0 )
5161                                 {
5162                                     if( bLeft )
5163                                         PaintBorderLine(rRect,aVert,this,pCol);
5164                                     if( bRight )
5165                                     {
5166                                         aVert.Pos().Y() = nGridBottom;
5167                                         PaintBorderLine(rRect,aVert,this,pCol);
5168                                     }
5169                                 }
5170                             }
5171                         }
5172                         bGrid = !bGrid;
5173                     }
5174                     while( nY >= aInter.Left() )
5175                     {
5176                         aTmp.Pos().X() = nY;
5177                         PaintBorderLine( rRect, aTmp, this, pCol);
5178                         if( bGrid )
5179                         {
5180                             nY -= nGrid;
5181                             SwTwips nHeight = aTmp.Pos().X()
5182                                               - Max(aInter.Left(), nY );
5183                             if( nHeight > 0 )
5184                             {
5185                                 if( bCell )
5186                                 {
5187                                     SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5188                                                   nX ), Size( nHeight, 1 ) );
5189                                     while( aVert.Top() <= nBottom )
5190                                     {
5191                                         PaintBorderLine(rRect,aVert,this,pCol);
5192                                         aVert.Pos().Y() += nGrid;
5193                                     }
5194                                 }
5195                                 else if( bBorder )
5196                                 {
5197                                     SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5198                                             aGrid.Top() ), Size( nHeight, 1 ) );
5199                                     if( bLeft )
5200                                         PaintBorderLine(rRect,aVert,this,pCol);
5201                                     if( bRight )
5202                                     {
5203                                         aVert.Pos().Y() = nGridBottom;
5204                                         PaintBorderLine(rRect,aVert,this,pCol);
5205                                     }
5206                                 }
5207                             }
5208                         }
5209                         else
5210                         {
5211                             nY -= nRuby;
5212                             if( bBorder )
5213                             {
5214                                 SwTwips nPos = Max( aInter.Left(), nY );
5215                                 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5216                                 SwRect aVert( Point( nPos, aGrid.Top() ),
5217                                               Size( nW, 1 ) );
5218                                 if( nW > 0 )
5219                                 {
5220                                     if( bLeft )
5221                                         PaintBorderLine(rRect,aVert,this,pCol);
5222                                     if( bRight )
5223                                     {
5224                                         aVert.Pos().Y() = nGridBottom;
5225                                         PaintBorderLine(rRect,aVert,this,pCol);
5226                                     }
5227                                 }
5228                             }
5229                         }
5230                         bGrid = !bGrid;
5231                     }
5232                 }
5233                 else
5234                 {
5235                     SwTwips nOrig = aGrid.Top();
5236                     SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum );
5237                     SwRect aTmp( Point( aInter.Left(), nY ),
5238                                 Size( aInter.Width(), 1 ) );
5239                     //for textgrid refactor
5240                     SwTwips nX = aGrid.Left() + nGridWidth *
5241                         ( ( aInter.Left() - aGrid.Left() )/ nGridWidth );
5242                     if( nX < aInter.Left() )
5243                         nX += nGridWidth;
5244                     SwTwips nGridRight = aGrid.Left() + aGrid.Width();
5245                     sal_Bool bLeft = aGrid.Left() >= aInter.Left();
5246                     sal_Bool bRight = nGridRight <= nRight;
5247                     sal_Bool bBorder = bLeft || bRight;
5248                     while( nY < aInter.Top() )
5249                     {
5250                         aTmp.Pos().Y() = nY;
5251                         if( bGrid )
5252                         {
5253                             nY += nGrid;
5254                             SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() );
5255                             SwTwips nHeight = Min(nBottom, nY ) - nPosY;
5256                             if( nHeight )
5257                             {
5258                                 if( bCell )
5259                                 {
5260                                     SwRect aVert( Point( nX, nPosY ),
5261                                                 Size( 1, nHeight ) );
5262                                     while( aVert.Left() <= nRight )
5263                                     {
5264                                         PaintBorderLine(rRect,aVert,this,pCol);
5265                                         aVert.Pos().X() += nGridWidth;	//for textgrid refactor
5266                                     }
5267                                 }
5268                                 else if ( bBorder )
5269                                 {
5270                                     SwRect aVert( Point( aGrid.Left(), nPosY ),
5271                                                 Size( 1, nHeight ) );
5272                                     if( bLeft )
5273                                         PaintBorderLine(rRect,aVert,this,pCol);
5274                                     if( bRight )
5275                                     {
5276                                         aVert.Pos().X() = nGridRight;
5277                                         PaintBorderLine(rRect,aVert,this,pCol);
5278                                     }
5279                                 }
5280                             }
5281                         }
5282                         else
5283                         {
5284                             nY += nRuby;
5285                             if( bBorder )
5286                             {
5287                                 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5288                                 SwTwips nH = Min( nBottom, nY ) - nPos;
5289                                 SwRect aVert( Point( aGrid.Left(), nPos ),
5290                                             Size( 1, nH ) );
5291                                 if( nH > 0 )
5292                                 {
5293                                     if( bLeft )
5294                                         PaintBorderLine(rRect,aVert,this,pCol);
5295                                     if( bRight )
5296                                     {
5297                                         aVert.Pos().X() = nGridRight;
5298                                         PaintBorderLine(rRect,aVert,this,pCol);
5299                                     }
5300                                 }
5301                             }
5302                         }
5303                         bGrid = !bGrid;
5304                     }
5305                     while( nY <= nBottom )
5306                     {
5307                         aTmp.Pos().Y() = nY;
5308                         PaintBorderLine( rRect, aTmp, this, pCol);
5309                         if( bGrid )
5310                         {
5311                             nY += nGrid;
5312                             SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y();
5313                             if( nHeight )
5314                             {
5315                                 if( bCell )
5316                                 {
5317                                     SwRect aVert( Point( nX, aTmp.Pos().Y() ),
5318                                                 Size( 1, nHeight ) );
5319                                     while( aVert.Left() <= nRight )
5320                                     {
5321                                         PaintBorderLine( rRect, aVert, this, pCol);
5322                                         aVert.Pos().X() += nGridWidth;	//for textgrid refactor
5323                                     }
5324                                 }
5325                                 else if( bBorder )
5326                                 {
5327                                     SwRect aVert( Point( aGrid.Left(),
5328                                         aTmp.Pos().Y() ), Size( 1, nHeight ) );
5329                                     if( bLeft )
5330                                         PaintBorderLine(rRect,aVert,this,pCol);
5331                                     if( bRight )
5332                                     {
5333                                         aVert.Pos().X() = nGridRight;
5334                                         PaintBorderLine(rRect,aVert,this,pCol);
5335                                     }
5336                                 }
5337                             }
5338                         }
5339                         else
5340                         {
5341                             nY += nRuby;
5342                             if( bBorder )
5343                             {
5344                                 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5345                                 SwTwips nH = Min( nBottom, nY ) - nPos;
5346                                 SwRect aVert( Point( aGrid.Left(), nPos ),
5347                                             Size( 1, nH ) );
5348                                 if( nH > 0 )
5349                                 {
5350                                     if( bLeft )
5351                                         PaintBorderLine(rRect,aVert,this,pCol);
5352                                     if( bRight )
5353                                     {
5354                                         aVert.Pos().X() = nGridRight;
5355                                         PaintBorderLine(rRect,aVert,this,pCol);
5356                                     }
5357                                 }
5358                             }
5359                         }
5360                         bGrid = !bGrid;
5361                     }
5362                 }
5363             }
5364         }
5365     }
5366 }
5367 
5368 /** paint margin area of a page
5369 
5370     OD 20.11.2002 for #104598#:
5371     implement paint of margin area; margin area will be painted for a
5372     view shell with a window and if the document is not in online layout.
5373 
5374     @author OD
5375 
5376     @param _rOutputRect
5377     input parameter - constant instance reference of the rectangle, for
5378     which an output has to be generated.
5379 
5380     @param _pViewShell
5381     input parameter - instance of the view shell, on which the output
5382     has to be generated.
5383 */
5384 void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect,
5385                                  ViewShell* _pViewShell ) const
5386 {
5387     if (  _pViewShell->GetWin() &&
5388          !_pViewShell->GetViewOptions()->getBrowseMode() )
5389     {
5390         SwRect aPgPrtRect( Prt() );
5391         aPgPrtRect.Pos() += Frm().Pos();
5392         if ( !aPgPrtRect.IsInside( _rOutputRect ) )
5393         {
5394             SwRect aPgRect = Frm();
5395             aPgRect._Intersection( _rOutputRect );
5396             SwRegionRects aPgRegion( aPgRect );
5397             aPgRegion -= aPgPrtRect;
5398             const SwPageFrm* pPage = static_cast<const SwPageFrm*>(this);
5399             //if ( pPage->GetSortedObjs() )
5400             //    ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion );
5401             if ( aPgRegion.Count() )
5402             {
5403                 OutputDevice *pOut = _pViewShell->GetOut();
5404                 if ( pOut->GetFillColor() != aGlobalRetoucheColor )
5405                     pOut->SetFillColor( aGlobalRetoucheColor );
5406 				for ( sal_uInt16 i = 0; i < aPgRegion.Count(); ++i )
5407                 {
5408                     if ( 1 < aPgRegion.Count() )
5409                     {
5410                         ::SwAlignRect( aPgRegion[i], pGlobalShell );
5411                         if( !aPgRegion[i].HasArea() )
5412                             continue;
5413                     }
5414 					pOut->DrawRect(aPgRegion[i].SVRect());
5415                 }
5416             }
5417         }
5418     }
5419 }
5420 
5421 // ----------------------------------------------------------------------
5422 //
5423 // const SwPageFrm::mnBorderPxWidth, const SwPageFrm::mnShadowPxWidth
5424 // SwPageFrm::GetBorderRect (..), SwPageFrm::GetRightShadowRect(..),
5425 // SwPageFrm::GetBottomShadowRect(..),
5426 // SwPageFrm::PaintBorderAndShadow(..),
5427 // SwPageFrm::GetBorderAndShadowBoundRect(..)
5428 //
5429 // OD 12.02.2003 for #i9719# and #105645#
5430 // ----------------------------------------------------------------------
5431 
5432 const sal_Int8 SwPageFrm::mnBorderPxWidth = 1;
5433 const sal_Int8 SwPageFrm::mnShadowPxWidth = 2;
5434 
5435 /** determine rectangle for page border
5436 
5437     OD 12.02.2003 for #i9719# and #105645#
5438 
5439     @author OD
5440 */
5441 /*static*/ void SwPageFrm::GetBorderRect( const SwRect& _rPageRect,
5442                                           ViewShell*    _pViewShell,
5443                                           SwRect& _orBorderRect,
5444                                           bool bRightSidebar )
5445 {
5446     SwRect aAlignedPageRect( _rPageRect );
5447     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5448     Rectangle aBorderPxRect =
5449             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5450 
5451 	aBorderPxRect.Left() = aBorderPxRect.Left() - mnBorderPxWidth;
5452     aBorderPxRect.Top() = aBorderPxRect.Top() - mnBorderPxWidth;
5453     aBorderPxRect.Right() = aBorderPxRect.Right() + mnBorderPxWidth;
5454     aBorderPxRect.Bottom() = aBorderPxRect.Bottom() + mnBorderPxWidth;
5455 
5456 	AddSidebarBorders(aBorderPxRect,_pViewShell, bRightSidebar, true);
5457 
5458     _orBorderRect =
5459             SwRect( _pViewShell->GetOut()->PixelToLogic( aBorderPxRect ) );
5460 }
5461 
5462 /** determine rectangle for right page shadow
5463 
5464     OD 12.02.2003 for #i9719# and #105645#
5465 
5466     @author OD
5467 */
5468 /*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect,
5469                                                ViewShell*    _pViewShell,
5470                                                SwRect&       _orRightShadowRect,
5471                                                bool bRightSidebar )
5472 {
5473     SwRect aAlignedPageRect( _rPageRect );
5474     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5475     Rectangle aPagePxRect =
5476             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5477 
5478     Rectangle aRightShadowPxRect(
5479                     aPagePxRect.Right() + mnShadowPxWidth,
5480                     aPagePxRect.Top() + 1,
5481                     aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5482                     aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5483 
5484     if ( bRightSidebar )
5485 	    AddSidebarBorders(aRightShadowPxRect,_pViewShell, bRightSidebar, true);
5486 
5487     _orRightShadowRect =
5488             SwRect( _pViewShell->GetOut()->PixelToLogic( aRightShadowPxRect ) );
5489 }
5490 
5491 /** determine rectangle for bottom page shadow
5492 
5493     OD 12.02.2003 for #i9719# and #105645#
5494 
5495     @author OD
5496 */
5497 /*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect,
5498                                                 ViewShell*    _pViewShell,
5499                                                 SwRect&       _orBottomShadowRect,
5500                                                 bool bRightSidebar )
5501 {
5502     SwRect aAlignedPageRect( _rPageRect );
5503     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5504     Rectangle aPagePxRect =
5505             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5506 
5507     Rectangle aBottomShadowPxRect(
5508                     aPagePxRect.Left() + 1,
5509                     aPagePxRect.Bottom() + mnShadowPxWidth,
5510                     aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5511                     aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5512 
5513 	AddSidebarBorders(aBottomShadowPxRect,_pViewShell, bRightSidebar, true);
5514 
5515     _orBottomShadowRect =
5516             SwRect( _pViewShell->GetOut()->PixelToLogic( aBottomShadowPxRect ) );
5517 }
5518 
5519 /** paint page border and shadow
5520 
5521     OD 12.02.2003 for #i9719# and #105645#
5522     implement paint of page border and shadow
5523 
5524     @author OD
5525 */
5526 /*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect,
5527                                                  ViewShell*    _pViewShell,
5528                                                  bool bPaintRightShadow,
5529                                                  bool bRightSidebar )
5530 {
5531     // --> FME 2004-06-24 #i16816# tagged pdf support
5532     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() );
5533     // <--
5534 
5535     // get color for page border and shadow paint
5536     const Color& rColor = SwViewOption::GetFontColor();
5537 
5538     // save current fill and line color of output device
5539     Color aFill( _pViewShell->GetOut()->GetFillColor() );
5540     Color aLine( _pViewShell->GetOut()->GetLineColor() );
5541 
5542     // paint page border
5543     _pViewShell->GetOut()->SetFillColor(); // OD 20.02.2003 #107369# - no fill color
5544     _pViewShell->GetOut()->SetLineColor( rColor );
5545     SwRect aPaintRect;
5546     SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5547     _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5548 
5549     // paint right shadow
5550     if ( bPaintRightShadow )
5551     {
5552         _pViewShell->GetOut()->SetFillColor( rColor );
5553         SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5554         _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5555     }
5556 
5557     // paint bottom shadow
5558     SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5559     _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5560 
5561     _pViewShell->GetOut()->SetFillColor( aFill );
5562     _pViewShell->GetOut()->SetLineColor( aLine );
5563 }
5564 
5565 //mod #i6193# paint sidebar for notes
5566 //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit
5567 /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight)
5568 {
5569 	//TOOD: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons
5570     if (!_pViewShell )
5571         return;
5572 
5573     SwRect aPageRect( _rPageRect );
5574     SwAlignRect( aPageRect, _pViewShell );
5575 
5576     const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
5577     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())  // do not show anything in print preview
5578 	{
5579         sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight();
5580         const Rectangle &aVisRect = _pViewShell->VisArea().SVRect();
5581         //draw border and sidepane
5582         _pViewShell->GetOut()->SetLineColor();
5583         if (!bRight)
5584         {
5585             _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5586             _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height())))    ;
5587             if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5588                 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5589             else
5590                 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5591             _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height())))  ;
5592         }
5593         else
5594         {
5595             _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5596             SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()));
5597             _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect());
5598             if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5599                 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5600             else
5601                 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5602             SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()));
5603             _pViewShell->GetOut()->DrawRect(aSidebar.SVRect());
5604         }
5605         if (pMgr->ShowScrollbar(nPageNum))
5606         {
5607             // draw scrollbar area and arrows
5608             Point aPointBottom;
5609             Point aPointTop;
5610             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()) :
5611                                     Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height());
5612             aPointTop = !bRight ?    Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) :
5613                                 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height());
5614             Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ;
5615             Rectangle aRectBottom(aPointBottom,aSize);
5616             Rectangle aRectTop(aPointTop,aSize);
5617 
5618             if (aRectBottom.IsOver(aVisRect))
5619             {
5620 
5621                 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5622                 {
5623                     _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5624                     _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5625                 }
5626                 else
5627                 {
5628                     _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5629                     _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5630                 }
5631                 _pViewShell->GetOut()->DrawRect(aRectBottom);
5632                 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5633 
5634                 _pViewShell->GetOut()->SetLineColor();
5635                 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5636                 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5637                 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5638             }
5639             if (aRectTop.IsOver(aVisRect))
5640             {
5641                 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5642                 {
5643                     _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5644                     _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5645                 }
5646                 else
5647                 {
5648                     _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5649                     _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5650                 }
5651                 _pViewShell->GetOut()->DrawRect(aRectTop);
5652                 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5653 
5654                 _pViewShell->GetOut()->SetLineColor();
5655                 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5656                 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5657                 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5658             }
5659         }
5660     }
5661 }
5662 
5663 /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown)
5664 {
5665 	Polygon aTriangleUp(3);
5666 	Polygon aTriangleDown(3);
5667 
5668 	aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5669 	aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1);
5670 	aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5671 
5672 	aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5673 	aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1);
5674 	aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5675 
5676 	_pViewShell->GetOut()->SetFillColor(aColorUp);
5677 	_pViewShell->GetOut()->DrawPolygon(aTriangleUp);
5678 	_pViewShell->GetOut()->SetFillColor(aColorDown);
5679 	_pViewShell->GetOut()->DrawPolygon(aTriangleDown);
5680 }
5681 
5682 /** get bound rectangle of border and shadow for repaints
5683 
5684     OD 12.02.2003 for #i9719# and #105645#
5685 
5686     author OD
5687 */
5688 /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect,
5689                                                         ViewShell*    _pViewShell,
5690                                                         SwRect& _orBorderAndShadowBoundRect,
5691                                                         bool bRightSidebar )
5692 {
5693     SwRect aTmpRect;
5694     SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, _orBorderAndShadowBoundRect, bRightSidebar );
5695     SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5696     _orBorderAndShadowBoundRect.Union( aTmpRect );
5697     SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5698     _orBorderAndShadowBoundRect.Union( aTmpRect );
5699 
5700 	AddSidebarBorders(_orBorderAndShadowBoundRect, _pViewShell, bRightSidebar, false);
5701 }
5702 
5703 /*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5704 {
5705     const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5706     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5707     {
5708         if (!bRightSidebar)
5709             aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5710         else
5711             aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5712     }
5713 }
5714 
5715 /*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5716 {
5717     const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5718     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5719     {
5720         if (!bRightSidebar)
5721             aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5722         else
5723             aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx);
5724     }
5725 }
5726 
5727 /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell )
5728 {
5729     const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5730     const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
5731     return nRet;
5732 }
5733 
5734 /*************************************************************************
5735 |*
5736 |*	SwFrm::PaintBaBo()
5737 |*
5738 |*	Ersterstellung		MA 22. Oct. 93
5739 |*	Letzte Aenderung	MA 19. Jun. 96
5740 |*
5741 |*************************************************************************/
5742 
5743 void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage,
5744 					   const sal_Bool bLowerBorder ) const
5745 {
5746 	if ( !pPage )
5747 		pPage = FindPageFrm();
5748 
5749 	OutputDevice *pOut = pGlobalShell->GetOut();
5750 
5751     // --> FME 2004-06-24 #i16816# tagged pdf support
5752     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
5753     // <--
5754 
5755     // OD 2004-04-23 #116347#
5756     pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
5757     pOut->SetLineColor();
5758 
5759 	SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
5760 	const SwBorderAttrs &rAttrs = *aAccess.Get();
5761 
5762     // OD 20.11.2002 #104598# - take care of page margin area
5763     // Note: code move from <SwFrm::PaintBackground(..)> to new method
5764     // <SwPageFrm::Paintmargin(..)>.
5765     if ( IsPageFrm() )
5766     {
5767         static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell );
5768     }
5769 
5770     // OD 06.08.2002 #99657# - paint border before painting background
5771     // paint grid for page frame and paint border
5772     {
5773         SwRect aRect( rRect );
5774         if( IsPageFrm() )
5775             ((SwPageFrm*)this)->PaintGrid( pOut, aRect );
5776         PaintBorder( aRect, pPage, rAttrs );
5777     }
5778 
5779     // paint background
5780     {
5781         PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder );
5782     }
5783 
5784 	pOut->Pop();
5785 }
5786 
5787 /*************************************************************************
5788 |*
5789 |*	SwFrm::PaintBackground()
5790 |*
5791 |*	Ersterstellung		MA 04. Jan. 93
5792 |*	Letzte Aenderung	MA 06. Feb. 97
5793 |*
5794 |*************************************************************************/
5795 /// OD 05.09.2002 #102912#
5796 /// Do not paint background for fly frames without a background brush by
5797 /// calling <PaintBaBo> at the page or at the fly frame its anchored
5798 void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
5799 						 	 const SwBorderAttrs & rAttrs,
5800 							 const sal_Bool bLowerMode,
5801 							 const sal_Bool bLowerBorder ) const
5802 {
5803     // OD 20.01.2003 #i1837# - no paint of table background, if corresponding
5804     // option is *not* set.
5805     if( IsTabFrm() &&
5806         !pGlobalShell->GetViewOptions()->IsTable() )
5807     {
5808         return;
5809     }
5810 
5811 	// nothing to do for covered table cells:
5812 	if( IsCellFrm() && IsCoveredCell() )
5813 		return;
5814 
5815     ViewShell *pSh = pGlobalShell;
5816 
5817     // --> FME 2004-06-24 #i16816# tagged pdf support
5818     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
5819     // <--
5820 
5821     const SvxBrushItem* pItem;
5822     /// OD 05.09.2002 #102912#
5823     /// temporary background brush for a fly frame without a background brush
5824     SvxBrushItem* pTmpBackBrush = 0;
5825     const Color* pCol;
5826 	SwRect aOrigBackRect;
5827 	const sal_Bool bPageFrm = IsPageFrm();
5828 	sal_Bool bLowMode = sal_True;
5829 
5830     //UUUU
5831     FillAttributesPtr aFillAttributes;
5832 
5833     sal_Bool bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, bLowerMode );
5834 
5835     //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird.
5836     bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm();
5837     if ( bNoFlyBackground )
5838     {
5839         // OD 05.09.2002 #102912# - Fly frame has no background.
5840         // Try to find background brush at parents, if previous call of
5841         // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode>
5842         if ( bLowerMode )
5843         {
5844             bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, false );
5845         }
5846         // If still no background found for the fly frame, initialize the
5847         // background brush <pItem> with global retouche color and set <bBack>
5848         // to sal_True, that fly frame will paint its background using this color.
5849         if ( !bBack )
5850         {
5851             // OD 10.01.2003 #i6467# - on print output, pdf output and
5852             // in embedded mode not editing color COL_WHITE is used instead of
5853             // the global retouche color.
5854             if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
5855                  pSh->GetViewOptions()->IsPDFExport() ||
5856                  ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED &&
5857                    !pSh->GetDoc()->GetDocShell()->IsInPlaceActive()
5858                  )
5859                )
5860             {
5861                 pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND );
5862 
5863                 //UUU
5864                 aFillAttributes.reset(new FillAttributes(Color( COL_WHITE )));
5865             }
5866             else
5867             {
5868                 pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND);
5869 
5870                 //UUU
5871                 aFillAttributes.reset(new FillAttributes(aGlobalRetoucheColor));
5872             }
5873 
5874             pItem = pTmpBackBrush;
5875             bBack = true;
5876         }
5877     }
5878 
5879 	SwRect aPaintRect( Frm() );
5880 	if( IsTxtFrm() || IsSctFrm() )
5881 		aPaintRect = UnionFrm( sal_True );
5882 
5883 	if ( aPaintRect.IsOver( rRect ) )
5884 	{
5885         if ( bBack || bPageFrm || !bLowerMode )
5886         {
5887             const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode();
5888             SwRect aRect;
5889             if ( (bPageFrm && bBrowse) ||
5890                  (IsTxtFrm() && Prt().SSize() == Frm().SSize()) )
5891             {
5892                 aRect = Frm();
5893                 ::SwAlignRect( aRect, pGlobalShell );
5894             }
5895             else
5896             {
5897                 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_False );
5898                 if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() )
5899                 {
5900                     if ( GetPrev()->GetAttrSet()->GetBackground() ==
5901                          GetAttrSet()->GetBackground() )
5902                     {
5903                         aRect.Top( Frm().Top() );
5904                     }
5905                 }
5906             }
5907             aRect.Intersection( rRect );
5908 
5909             OutputDevice *pOut = pSh->GetOut();
5910 
5911             if ( aRect.HasArea() )
5912             {
5913                 SvxBrushItem* pNewItem = 0;
5914                 //SwRegionRects aRegion( aRect );
5915 
5916                 if( pCol )
5917                 {
5918                     pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND );
5919                     pItem = pNewItem;
5920 
5921                     //UUUU
5922                     aFillAttributes.reset(new FillAttributes(*pCol));
5923                 }
5924 
5925                 //if ( pPage->GetSortedObjs() )
5926                 //{
5927                 //    ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
5928                 //}
5929 
5930                 {
5931                     /// OD 06.08.2002 #99657# - determine, if background transparency
5932                     ///     have to be considered for drawing.
5933                     ///     --> Status Quo: background transparency have to be
5934                     ///        considered for fly frames
5935                     const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm();
5936                     bool bDone(false);
5937 
5938                     if(pOut && aFillAttributes.get() && aFillAttributes->isUsed())
5939                     {
5940                         bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRect, *pOut);
5941                     }
5942 
5943                     if(!bDone)
5944                     {
5945                         //for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
5946                         //{
5947                         //    if ( 1 < aRegion.Count() )
5948                         //    {
5949                         //        ::SwAlignRect( aRegion[i], pGlobalShell );
5950                         //        if( !aRegion[i].HasArea() )
5951                         //            continue;
5952                         //    }
5953                             /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if
5954                             ///     background transparency have to be considered
5955                             ///     Set missing 5th parameter to the default value GRFNUM_NO
5956                             ///         - see declaration in /core/inc/frmtool.hxx.
5957                         ::DrawGraphic(
5958                                 pItem,
5959                                 pOut,
5960                                 aOrigBackRect,
5961                                 aRect, // aRegion[i],
5962                                 GRFNUM_NO,
5963                                 bConsiderBackgroundTransparency );
5964                         //}
5965                     }
5966                 }
5967                 if( pCol )
5968                     delete pNewItem;
5969             }
5970         }
5971         else
5972             bLowMode = bLowerMode ? sal_True : sal_False;
5973 	}
5974 
5975     /// OD 05.09.2002 #102912#
5976     /// delete temporary background brush.
5977     delete pTmpBackBrush;
5978 
5979     //Jetzt noch Lower und dessen Nachbarn.
5980 	//Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist
5981 	//so hoert der Spass auf.
5982 	const SwFrm *pFrm = GetLower();
5983     if ( pFrm )
5984 	{
5985 		SwRect aFrmRect;
5986 		SwRect aRect( PaintArea() );
5987 		aRect._Intersection( rRect );
5988 		SwRect aBorderRect( aRect );
5989         SwShortCut aShortCut( *pFrm, aBorderRect );
5990 		do
5991 		{   if ( pProgress )
5992 				pProgress->Reschedule();
5993 
5994 			aFrmRect = pFrm->PaintArea();
5995 			if ( aFrmRect.IsOver( aBorderRect ) )
5996 			{
5997 				SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
5998                 const SwBorderAttrs &rTmpAttrs = *aAccess.Get();
5999                 /// OD 06.08.2002 #99657# - paint border before painting background
6000                 if ( bLowerBorder )
6001                     pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs );
6002 				if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) ||
6003 					 aFrmRect.IsOver( aRect ) )
6004                     pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode,
6005 										   bLowerBorder );
6006 			}
6007 			pFrm = pFrm->GetNext();
6008 		} while ( pFrm && pFrm->GetUpper() == this &&
6009                   !aShortCut.Stop( aFrmRect ) );
6010 	}
6011 }
6012 
6013 /*************************************************************************
6014 |*
6015 |*	SwPageFrm::RefreshSubsidiary()
6016 |*
6017 |*	Beschreibung		Erneuert alle Hilfslinien der Seite.
6018 |*	Ersterstellung		MA 04. Nov. 92
6019 |*	Letzte Aenderung	MA 10. May. 95
6020 |*
6021 |*************************************************************************/
6022 
6023 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
6024 {
6025     if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS )
6026 	{
6027 		SwRect aRect( rRect );
6028         // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of
6029         // the output rectangle.
6030         //::SwAlignRect( aRect, pGlobalShell );
6031 		if ( aRect.HasArea() )
6032 		{
6033 			//Beim Paint ueber die Root wird das Array von dort gesteuert.
6034 			//Anderfalls kuemmern wir uns selbst darum.
6035 			sal_Bool bDelSubs = sal_False;
6036 			if ( !pSubsLines )
6037 			{
6038 				pSubsLines = new SwSubsRects;
6039                 // OD 20.12.2002 #106318# - create container for special subsidiary lines
6040                 pSpecSubsLines = new SwSubsRects;
6041                 bDelSubs = sal_True;
6042 			}
6043 
6044 			RefreshLaySubsidiary( this, aRect );
6045 
6046             if ( bDelSubs )
6047 			{
6048                 // OD 20.12.2002 #106318# - paint special subsidiary lines
6049                 // and delete its container
6050                 pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL );
6051                 DELETEZ( pSpecSubsLines );
6052 
6053                 pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines );
6054 				DELETEZ( pSubsLines );
6055 			}
6056 		}
6057 	}
6058 }
6059 
6060 /*************************************************************************
6061 |*
6062 |*	SwLayoutFrm::RefreshLaySubsidiary()
6063 |*
6064 |*	Ersterstellung		MA 04. Nov. 92
6065 |*	Letzte Aenderung	MA 22. Jan. 95
6066 |*
6067 |*************************************************************************/
6068 void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage,
6069                                         const SwRect &rRect ) const
6070 {
6071 	const sal_Bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm();
6072 	const sal_Bool bSubsOpt	  = IS_SUBS;
6073     const sal_Bool bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE);
6074     const sal_Bool bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt;
6075 	const sal_Bool bSubsSect  = IsSctFrm() &&
6076 								bNoLowerColumn &&
6077 								IS_SUBS_SECTION;
6078     const sal_Bool bSubsFly   = IS_SUBS_FLYS &&
6079                                 (GetType() & FRM_FLY) &&
6080                                 bNoLowerColumn &&
6081 								(!Lower() || !Lower()->IsNoTxtFrm() ||
6082 								 !((SwNoTxtFrm*)Lower())->HasAnimation());
6083 	sal_Bool bSubsBody = sal_False;
6084 	if ( GetType() & FRM_BODY )
6085 	{
6086 		if ( IsPageBodyFrm() )
6087 			bSubsBody = bSubsOpt && bNoLowerColumn;									//nur ohne Spalten
6088         else    //Spaltenbody
6089 		{
6090 			if ( GetUpper()->GetUpper()->IsSctFrm() )
6091 				bSubsBody = IS_SUBS_SECTION;
6092 			else
6093 				bSubsBody = bSubsOpt;
6094 		}
6095 	}
6096 
6097 	if ( bSubsOther || bSubsSect  || bSubsBody || bSubsTable || bSubsFly )
6098 		PaintSubsidiaryLines( pPage, rRect );
6099 
6100     const SwFrm *pLow = Lower();
6101     if( !pLow )
6102         return;
6103     SwShortCut aShortCut( *pLow, rRect );
6104     while( pLow && !aShortCut.Stop( pLow->Frm() ) )
6105     {
6106         if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() )
6107         {
6108             if ( pLow->IsLayoutFrm() )
6109                 ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect);
6110             else if ( pLow->GetDrawObjs() )
6111             {
6112                 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs());
6113                 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
6114                 {
6115                     const SwAnchoredObject* pAnchoredObj = rObjs[i];
6116                     if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
6117                                     pAnchoredObj->GetDrawObj()->GetLayer() ) &&
6118                          pAnchoredObj->ISA(SwFlyFrm) )
6119                     {
6120                         const SwFlyFrm *pFly =
6121                                     static_cast<const SwFlyFrm*>(pAnchoredObj);
6122                         if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) )
6123                         {
6124                             if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
6125                                  !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
6126                                 pFly->RefreshLaySubsidiary( pPage, rRect );
6127                         }
6128                     }
6129                 }
6130             }
6131         }
6132         pLow = pLow->GetNext();
6133     }
6134 }
6135 
6136 /*************************************************************************
6137 |*
6138 |*	SwLayoutFrm::PaintSubsidiaryLines()
6139 |*
6140 |*	Beschreibung		Hilfslinien um die PrtAreas malen
6141 |* 		Nur die LayoutFrm's die direkt Cntnt enthalten.
6142 |*	Ersterstellung		MA 21. May. 92
6143 |*	Letzte Aenderung	MA 22. Jan. 95
6144 |*
6145 |*************************************************************************/
6146 
6147 //Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden.
6148 
6149 typedef long Size::* SizePtr;
6150 typedef long Point::* PointPtr;
6151 
6152 PointPtr pX = &Point::nA;
6153 PointPtr pY = &Point::nB;
6154 SizePtr pWidth = &Size::nA;
6155 SizePtr pHeight = &Size::nB;
6156 
6157 // OD 18.11.2002 #99672# - new parameter <_pSubsLines>
6158 void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay,
6159                                   const SwPageFrm *pPage,
6160                                   const Point &rP1,
6161                                   const Point &rP2,
6162                                   const sal_uInt8 nSubColor,
6163                                   SwLineRects* _pSubsLines )
6164 {
6165 	//In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein.
6166 	ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
6167 			"Schraege Hilfslinien sind nicht erlaubt." );
6168     const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX;
6169     const PointPtr pOthPt = pDirPt == pX ? pY : pX;
6170     const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight;
6171     const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth;
6172 	Point aP1( rP1 ),
6173 		  aP2( rP2 );
6174 
6175 	while ( aP1.*pDirPt < aP2.*pDirPt )
6176 	{	//Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt
6177 		//hinter den Fly gesetzt.
6178 		//Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt
6179 		//ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen.
6180 		//Auf diese art und weise wird eine Portion nach der anderen
6181 		//ausgegeben.
6182 
6183 		//Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus,
6184 		//die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen.
6185 		//Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche
6186 		//ich keinem dieser Flys aus.
6187 		SwOrderIter aIter( pPage );
6188 		const SwFlyFrm *pMyFly = pLay->FindFlyFrm();
6189 		if ( pMyFly )
6190 		{
6191 			aIter.Current( pMyFly->GetVirtDrawObj() );
6192             while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) )
6193 			{
6194 				if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
6195 					aIter.Current( pMyFly->GetVirtDrawObj() );
6196 			}
6197 		}
6198 		else
6199 			aIter.Bottom();
6200 
6201 		while ( aIter() )
6202 		{
6203 			const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
6204 			const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
6205 
6206 			//Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich
6207 			//_in_ dem Fly sitze weiche ich nicht aus.
6208 			if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
6209             {
6210                 aIter.Next();
6211 				continue;
6212 			}
6213 
6214             // OD 19.12.2002 #106318# - do *not* consider fly frames with
6215             // a transparent background.
6216             // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which
6217             // belongs to a invisible layer
6218             if ( pFly->IsBackgroundTransparent() ||
6219                  !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) )
6220             {
6221                 aIter.Next();
6222                 continue;
6223             }
6224 
6225 			//Sitzt das Obj auf der Linie
6226 			const Rectangle &rBound = pObj->GetCurrentBoundRect();
6227 			const Point aDrPt( rBound.TopLeft() );
6228 			const Size  aDrSz( rBound.GetSize() );
6229 			if ( rP1.*pOthPt >= aDrPt.*pOthPt &&
6230 				 rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) )
6231 			{
6232 				if ( aP1.*pDirPt >= aDrPt.*pDirPt &&
6233 			  	  	 aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) )
6234 					aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz;
6235 
6236 				if ( aP2.*pDirPt >= aDrPt.*pDirPt &&
6237 					 aP1.*pDirPt < (aDrPt.*pDirPt - 1) )
6238 					aP2.*pDirPt = aDrPt.*pDirPt - 1;
6239 			}
6240 			aIter.Next();
6241 		}
6242 
6243 		if ( aP1.*pDirPt < aP2.*pDirPt )
6244 		{
6245 			SwRect aRect( aP1, aP2 );
6246             // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of
6247             // global variable <pSubsLines>.
6248             _pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6249 		}
6250 		aP1 = aP2;
6251 		aP1.*pDirPt += 1;
6252 		aP2 = rP2;
6253 	}
6254 }
6255 
6256 void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage,
6257 										const SwRect &rRect ) const
6258 {
6259     bool bNewTableModel = false;
6260 
6261     // --> collapsing borders FME 2005-05-27 #i29550#
6262     if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
6263     {
6264         const SwTabFrm* pTabFrm = FindTabFrm();
6265         if ( pTabFrm->IsCollapsingBorders() )
6266             return;
6267 
6268         bNewTableModel = pTabFrm->GetTable()->IsNewModel();
6269         // in the new table model, we have an early return for all cell-related
6270         // frames, except from non-covered table cells
6271         if ( bNewTableModel )
6272             if ( IsTabFrm() ||
6273                  IsRowFrm() ||
6274                  ( IsCellFrm() && IsCoveredCell() ) )
6275                 return;
6276     }
6277     // <-- collapsing
6278 
6279     const bool bFlys = pPage->GetSortedObjs() ? true : false;
6280 
6281     const bool bCell = IsCellFrm() ? true : false;
6282     // use frame area for cells
6283     // OD 13.02.2003 #i3662# - for section use also frame area
6284     const bool bUseFrmArea = bCell || IsSctFrm();
6285     SwRect aOriginal( bUseFrmArea ? Frm() : Prt() );
6286     if ( !bUseFrmArea )
6287         aOriginal.Pos() += Frm().Pos();
6288 
6289     // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area
6290     // in sections to top of section frame.
6291     const bool bColBodyInSection = IsBodyFrm() &&
6292                                    !IsPageBodyFrm() &&
6293                                    GetUpper()->GetUpper()->IsSctFrm();
6294     if ( bColBodyInSection )
6295     {
6296         if ( IsVertical() )
6297             aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() );
6298         else
6299             aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() );
6300     }
6301 
6302     ::SwAlignRect( aOriginal, pGlobalShell );
6303 
6304     if ( !aOriginal.IsOver( rRect ) )
6305 		return;
6306 
6307 	SwRect aOut( aOriginal );
6308 	aOut._Intersection( rRect );
6309     // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's
6310     // printing area with the paint area of the body frame. Otherwise enlargement
6311     // will get lost.
6312     if ( !bColBodyInSection )
6313     {
6314         aOut.Intersection( PaintArea() );
6315     }
6316 
6317 	const SwTwips nRight = aOut.Right();
6318 	const SwTwips nBottom= aOut.Bottom();
6319 
6320 	const Point aRT( nRight, aOut.Top() );
6321 	const Point aRB( nRight, nBottom );
6322 	const Point aLB( aOut.Left(), nBottom );
6323 
6324     sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB :
6325                      ( IsInSct() ? SUBCOL_SECT :
6326                      ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
6327 
6328     // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks.
6329     sal_Bool bBreak = sal_False;
6330     if ( IsBodyFrm() )
6331     {
6332         const SwCntntFrm *pCnt = ContainsCntnt();
6333         if ( pCnt )
6334         {
6335             // OD 05.11.2002 #102406# - adjust setting of <bBreak>.
6336             bBreak = pCnt->IsPageBreak( sal_True ) ||
6337                      ( IsColBodyFrm() && pCnt->IsColBreak( sal_True ) );
6338         }
6339     }
6340 
6341     // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section
6342     // sub-lines in <pSpecSubsLine> array.
6343     const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() ||
6344                                   IsFtnFrm() || IsSctFrm();
6345     SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines;
6346 
6347     // NOTE: for cell frames only left and right (horizontal layout) respectively
6348     //      top and bottom (vertical layout) lines painted.
6349     // NOTE2: this does not hold for the new table model!!! We paint the top border
6350     // of each non-covered table cell.
6351     const bool bVert = IsVertical() ? true : false;
6352     if ( bFlys )
6353 	{
6354         // OD 14.11.2002 #104822# - add control for drawing left and right lines
6355         if ( !bCell || bNewTableModel || !bVert )
6356         {
6357             if ( aOriginal.Left() == aOut.Left() )
6358                 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor,
6359                                    pUsedSubsLines );
6360             // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6361             if ( aOriginal.Right() == nRight )
6362                 ::lcl_RefreshLine( this, pPage, aRT, aRB,
6363                                    (bBreak && bVert) ? SUBCOL_BREAK : nSubColor,
6364                                    pUsedSubsLines );
6365         }
6366         // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6367         if ( !bCell || bNewTableModel || bVert )
6368 		{
6369 			if ( aOriginal.Top() == aOut.Top() )
6370                 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6371 				::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT,
6372                                    (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor,
6373                                    pUsedSubsLines );
6374 			if ( aOriginal.Bottom() == nBottom )
6375                 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor,
6376                                    pUsedSubsLines );
6377 		}
6378 	}
6379 	else
6380 	{
6381         // OD 14.11.2002 #104822# - add control for drawing left and right lines
6382         if ( !bCell || bNewTableModel || !bVert )
6383         {
6384             if ( aOriginal.Left() == aOut.Left() )
6385             {
6386                 const SwRect aRect( aOut.Pos(), aLB );
6387                 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6388             }
6389             // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6390             if ( aOriginal.Right() == nRight )
6391             {
6392                 const SwRect aRect( aRT, aRB );
6393                 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6394                         (bBreak && bVert) ? SUBCOL_BREAK : nSubColor );
6395             }
6396         }
6397         // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6398         if ( !bCell || bNewTableModel || bVert )
6399         {
6400 			if ( aOriginal.Top() == aOut.Top() )
6401 			{
6402                 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6403 				const SwRect aRect( aOut.Pos(), aRT );
6404                 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6405                         (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor );
6406 			}
6407 			if ( aOriginal.Bottom() == nBottom )
6408 			{
6409 				const SwRect aRect( aLB, aRB );
6410                 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6411 			}
6412         }
6413 	}
6414 }
6415 
6416 /*************************************************************************
6417 |*
6418 |*	SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData()
6419 |*
6420 |*	Beschreibung		Erneuert alle Extradaten (Zeilennummern usw) der Seite.
6421 |* 						Grundsaetzlich sind nur diejenigen Objekte beruecksichtig,
6422 |* 						die in die seitliche Ausdehnung des Rects ragen.
6423 |*	Ersterstellung		MA 20. Jan. 98
6424 |*	Letzte Aenderung	MA 18. Feb. 98
6425 |*
6426 |*************************************************************************/
6427 
6428 void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const
6429 {
6430 	const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6431 	sal_Bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys())
6432         || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE;
6433 
6434 	SwRect aRect( rRect );
6435 	::SwAlignRect( aRect, pGlobalShell );
6436 	if ( aRect.HasArea() )
6437 	{
6438 		SwLayoutFrm::RefreshExtraData( aRect );
6439 
6440 		if ( bLineInFly && GetSortedObjs() )
6441 			for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i )
6442 			{
6443                 const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
6444                 if ( pAnchoredObj->ISA(SwFlyFrm) )
6445 				{
6446                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6447 					if ( pFly->Frm().Top() <= aRect.Bottom() &&
6448 						 pFly->Frm().Bottom() >= aRect.Top() )
6449 						pFly->RefreshExtraData( aRect );
6450 				}
6451 			}
6452 	}
6453 }
6454 
6455 void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const
6456 {
6457 
6458 	const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6459 	sal_Bool bLineInBody = rInfo.IsPaintLineNumbers(),
6460 			 bLineInFly  = bLineInBody && rInfo.IsCountInFlys(),
6461              bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE;
6462 
6463 	const SwCntntFrm *pCnt = ContainsCntnt();
6464 	while ( pCnt && IsAnLower( pCnt ) )
6465 	{
6466 		if ( pCnt->IsTxtFrm() && ( bRedLine ||
6467 			 ( !pCnt->IsInTab() &&
6468 			   ((bLineInBody && pCnt->IsInDocBody()) ||
6469 			   (bLineInFly  && pCnt->IsInFly())) ) ) &&
6470 			 pCnt->Frm().Top() <= rRect.Bottom() &&
6471 			 pCnt->Frm().Bottom() >= rRect.Top() )
6472 		{
6473 			((SwTxtFrm*)pCnt)->PaintExtraData( rRect );
6474 		}
6475 		if ( bLineInFly && pCnt->GetDrawObjs() )
6476             for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i )
6477 			{
6478                 const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i];
6479                 if ( pAnchoredObj->ISA(SwFlyFrm) )
6480                 {
6481                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6482                     if ( pFly->IsFlyInCntFrm() &&
6483 						 pFly->Frm().Top() <= rRect.Bottom() &&
6484 						 pFly->Frm().Bottom() >= rRect.Top() )
6485 						pFly->RefreshExtraData( rRect );
6486 				}
6487 		}
6488 		pCnt = pCnt->GetNextCntntFrm();
6489 	}
6490 }
6491 
6492 /** SwPageFrm::GetDrawBackgrdColor - for #102450#
6493 
6494     determine the color, that is respectively will be drawn as background
6495     for the page frame.
6496     Using existing method SwFrm::GetBackgroundBrush to determine the color
6497     that is set at the page frame respectively is parent. If none is found
6498     return the global retouche color
6499 
6500     @author OD
6501 
6502     @return Color
6503 */
6504 const Color& SwPageFrm::GetDrawBackgrdColor() const
6505 {
6506     const SvxBrushItem* pBrushItem;
6507     const Color* pDummyColor;
6508     SwRect aDummyRect;
6509 
6510     //UUUU
6511     FillAttributesPtr aFillAttributes;
6512 
6513     if ( GetBackgroundBrush( aFillAttributes, pBrushItem, pDummyColor, aDummyRect, true) )
6514     {
6515         const Graphic* pGraphic = pBrushItem->GetGraphic();
6516 
6517         if(pGraphic)
6518         {
6519             // #29105# when a graphic is set, it may be possible to calculate a single
6520             // color which looks good in all places of the graphic. Since it is
6521             // planned to have text edit on the overlay one day and the fallback
6522             // to aGlobalRetoucheColor returns something useful, just use that
6523             // for now.
6524         }
6525         else
6526         {
6527             // not a graphic, use (hopefully) initialized color
6528             return pBrushItem->GetColor();
6529         }
6530     }
6531 
6532     return aGlobalRetoucheColor;
6533 }
6534 
6535 /*************************************************************************
6536 |*
6537 |*    SwPageFrm::GetEmptyPageFont()
6538 |*
6539 |*    create/return font used to paint the "empty page" string
6540 |*
6541 |*************************************************************************/
6542 
6543 const Font& SwPageFrm::GetEmptyPageFont()
6544 {
6545     static Font* pEmptyPgFont = 0;
6546     if ( 0 == pEmptyPgFont )
6547     {
6548         pEmptyPgFont = new Font;
6549         pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt
6550         pEmptyPgFont->SetWeight( WEIGHT_BOLD );
6551         pEmptyPgFont->SetStyleName( aEmptyStr );
6552         pEmptyPgFont->SetName( String::CreateFromAscii(
6553                 RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) );
6554         pEmptyPgFont->SetFamily( FAMILY_SWISS );
6555         pEmptyPgFont->SetTransparent( sal_True );
6556         pEmptyPgFont->SetColor( COL_GRAY );
6557     }
6558 
6559     return *pEmptyPgFont;
6560 }
6561 
6562 /*************************************************************************
6563 |*
6564 |*	  SwFrm::Retouche
6565 |*
6566 |*	  Beschreibung		Retouche fuer einen Bereich.
6567 |*		Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner
6568 |* 		Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird
6569 |* 		per PaintBackground gecleared.
6570 |*	  Ersterstellung	MA 13. Apr. 93
6571 |*	  Letzte Aenderung	MA 25. Jul. 96
6572 |*
6573 |*************************************************************************/
6574 
6575 void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const
6576 {
6577 	if ( bFlyMetafile )
6578 		return;
6579 
6580 	ASSERT( GetUpper(), "Retoucheversuch ohne Upper." );
6581 	ASSERT( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" );
6582 
6583 	SwRect aRetouche( GetUpper()->PaintArea() );
6584 	aRetouche.Top( Frm().Top() + Frm().Height() );
6585 	aRetouche.Intersection( pGlobalShell->VisArea() );
6586 
6587 	if ( aRetouche.HasArea() )
6588 	{
6589         //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region
6590 		//zum ausstanzen.
6591 		SwRegionRects aRegion( aRetouche );
6592 		aRegion -= rRect;
6593 		ViewShell *pSh = getRootFrm()->GetCurrShell();
6594 
6595         // --> FME 2004-06-24 #i16816# tagged pdf support
6596         SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
6597         // <--
6598 
6599 		for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
6600 		{
6601 			SwRect &rRetouche = aRegion[i];
6602 
6603 			GetUpper()->PaintBaBo( rRetouche, pPage, sal_True );
6604 
6605 			//Hoelle und Himmel muessen auch refreshed werden.
6606 			//Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst
6607 			//zurueckgesetzt werden!
6608 			ResetRetouche();
6609             SwRect aRetouchePart( rRetouche );
6610             if ( aRetouchePart.HasArea() )
6611             {
6612                 const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
6613                 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6614                 // --> OD #i76669#
6615                 SwViewObjectContactRedirector aSwRedirector( *pSh );
6616                 // <--
6617 
6618                 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0,
6619                                         aRetouchePart, &aPageBackgrdColor,
6620                                         (pPage->IsRightToLeft() ? true : false),
6621                                         &aSwRedirector );
6622                 pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0,
6623                                         aRetouchePart, &aPageBackgrdColor,
6624                                         (pPage->IsRightToLeft() ? true : false),
6625                                         &aSwRedirector );
6626             }
6627 
6628 			SetRetouche();
6629 
6630 			//Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier
6631 			//leider die Hilfslinien erneuert werden.
6632             pPage->RefreshSubsidiary( aRetouchePart );
6633 		}
6634 	}
6635 	if ( ViewShell::IsLstEndAction() )
6636 		ResetRetouche();
6637 }
6638 
6639 /** SwFrm::GetBackgroundBrush
6640 
6641     @descr
6642     determine the background brush for the frame:
6643     the background brush is taken from it-self or from its parent (anchor/upper).
6644     Normally, the background brush is taken, which has no transparent color or
6645     which has a background graphic. But there are some special cases:
6646     (1) No background brush is taken from a page frame, if view option "IsPageBack"
6647         isn't set.
6648     (2) Background brush from a index section is taken under special conditions.
6649         In this case parameter <rpCol> is set to the index shading color.
6650     (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing
6651         of the frame transparency is considered and its color is not "no fill"/"auto fill"
6652     ---- old description in german:
6653     Beschreibung        Liefert die Backgroundbrush fuer den Bereich des
6654         des Frm. Die Brush wird entweder von ihm selbst oder von einem
6655         Upper vorgegeben, die erste Brush wird benutzt.
6656         Ist fuer keinen Frm eine Brush angegeben, so wird sal_False zurueck-
6657         geliefert.
6658     Ersterstellung      MA 23. Dec. 92
6659     Letzte Aenderung    MA 04. Feb. 97
6660 
6661     @param rpBrush
6662     output parameter - constant reference pointer the found background brush
6663 
6664     @param rpCol
6665     output parameter - constant reference pointer to the color of the index shading
6666     set under special conditions, if background brush is taken from an index section.
6667 
6668     @param rOrigRect
6669     in-/output parameter - reference to the retangle the background brush is
6670     considered for - adjusted to the frame, from which the background brush is
6671     taken.
6672 
6673     @parem bLowerMode
6674     input parameter - boolean indicating, if background brush should *not* be
6675     taken from parent.
6676 
6677     @author MA
6678     @change 20.08.2002 by OD
6679     @docdate 20.08.2002
6680 
6681     @return true, if a background brush for the frame is found
6682 */
6683 sal_Bool SwFrm::GetBackgroundBrush(
6684     FillAttributesPtr& rFillAttributes,
6685     const SvxBrushItem* & rpBrush,
6686     const Color*& rpCol,
6687     SwRect &rOrigRect,
6688     sal_Bool bLowerMode ) const
6689 {
6690 	const SwFrm *pFrm = this;
6691 	ViewShell *pSh = getRootFrm()->GetCurrShell();
6692 	const SwViewOption *pOpt = pSh->GetViewOptions();
6693 	rpBrush = 0;
6694 	rpCol = NULL;
6695 	do
6696 	{	if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() )
6697 			return sal_False;
6698 
6699         //UUUU
6700         const SwLayoutFrm* pSwLayoutFrm = dynamic_cast< const SwLayoutFrm* >(pFrm);
6701 
6702         if(pSwLayoutFrm)
6703         {
6704             const SwFrmFmt* pSwFrmFmt = dynamic_cast< const SwFrmFmt* >(pSwLayoutFrm->GetFmt());
6705 
6706             if(pSwFrmFmt  && RES_FLYFRMFMT == pSwFrmFmt->Which())
6707             {
6708                 rFillAttributes = pSwFrmFmt->getFillAttributes();
6709             }
6710         }
6711 
6712         const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
6713 
6714         if( pFrm->IsSctFrm() )
6715         {
6716             const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
6717             /// OD 20.08.2002 #99657# #GetTransChg#
6718             ///     Note: If frame <pFrm> is a section of the index and
6719             ///         it its background color is "no fill"/"auto fill" and
6720             ///         it has no background graphic and
6721             ///         we are not in the page preview and
6722             ///         we are not in read-only mode and
6723             ///         option "index shadings" is set and
6724             ///         the output is not the printer
6725             ///         then set <rpCol> to the color of the index shading
6726             if( pSection && (   TOX_HEADER_SECTION == pSection->GetType() ||
6727                                 TOX_CONTENT_SECTION == pSection->GetType() ) &&
6728                 (rBack.GetColor() == COL_TRANSPARENT) &&
6729                 ///rBack.GetColor().GetTransparency() &&
6730                 rBack.GetGraphicPos() == GPOS_NONE &&
6731                 !pOpt->IsPagePreview() &&
6732                 !pOpt->IsReadonly() &&
6733                 // --> FME 2004-06-29 #114856# Formular view
6734                 !pOpt->IsFormView() &&
6735                 // <--
6736                 SwViewOption::IsIndexShadings() &&
6737                 !pOpt->IsPDFExport() &&
6738                 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
6739             {
6740                 rpCol = &SwViewOption::GetIndexShadingsColor();
6741             }
6742         }
6743 
6744         /// OD 20.08.2002 #99657#
6745         ///     determine, if background draw of frame <pFrm> considers transparency
6746         ///     --> Status Quo: background transparency have to be
6747         ///                     considered for fly frames
6748         const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm();
6749 
6750         /// OD 20.08.2002 #99657#
6751         ///     add condition:
6752         ///     If <bConsiderBackgroundTransparency> is set - see above -,
6753         ///     return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill"
6754         if (
6755             // done when FillAttributesare set
6756             (rFillAttributes.get() && rFillAttributes->isUsed()) ||
6757 
6758             // done when SvxBrushItem is used
6759             !rBack.GetColor().GetTransparency() || rBack.GetGraphicPos() != GPOS_NONE ||
6760 
6761             // done when direct color is forced
6762             rpCol ||
6763 
6764             // done when consider BG transparency and color is not completely transparent
6765             (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT))
6766            )
6767         {
6768             rpBrush = &rBack;
6769 
6770             if ( pFrm->IsPageFrm() && pSh->GetViewOptions()->getBrowseMode() )
6771             {
6772                 rOrigRect = pFrm->Frm();
6773             }
6774             else
6775             {
6776                 if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() )
6777                 {
6778                     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
6779                     const SwBorderAttrs &rAttrs = *aAccess.Get();
6780                     ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, sal_False );
6781                 }
6782                 else
6783                 {
6784                     rOrigRect = pFrm->Prt();
6785                     rOrigRect += pFrm->Frm().Pos();
6786                 }
6787             }
6788 
6789             return sal_True;
6790         }
6791 
6792         if ( bLowerMode )
6793         {
6794             /// Do not try to get background brush from parent (anchor/upper)
6795             return sal_False;
6796         }
6797 
6798         /// get parent frame - anchor or upper - for next loop
6799         if ( pFrm->IsFlyFrm() )
6800         {
6801             /// OD 20.08.2002 - use "static_cast" instead of "old C-cast"
6802             pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm();
6803             ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
6804         }
6805         else
6806         {
6807             pFrm = pFrm->GetUpper();
6808         }
6809     } while ( pFrm );
6810 
6811     return sal_False;
6812 }
6813 
6814 /*************************************************************************
6815 |*
6816 |*	SwFrmFmt::GetGraphic()
6817 |*
6818 |*	Ersterstellung		MA 23. Jul. 96
6819 |*	Letzte Aenderung	MA 23. Jul. 96
6820 |*
6821 |*************************************************************************/
6822 
6823 void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO,
6824 					  Window *pW, sal_uInt16 nZoom )
6825 {
6826 	pSh->pOut = pO;
6827 	pSh->pWin = pW;
6828 	pSh->pOpt->SetZoom( nZoom );
6829 }
6830 
6831 Graphic SwFrmFmt::MakeGraphic( ImageMap* )
6832 {
6833 	return Graphic();
6834 }
6835 
6836 Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap )
6837 {
6838 	Graphic aRet;
6839 	//irgendeinen Fly suchen!
6840 	SwIterator<SwFrm,SwFmt> aIter( *this );
6841     SwFrm *pFirst = aIter.First();
6842 	ViewShell *pSh;
6843     if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) )
6844 	{
6845 		ViewShell *pOldGlobal = pGlobalShell;
6846 		pGlobalShell = pSh;
6847 
6848 		sal_Bool bNoteURL = pMap &&
6849 			SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, sal_True );
6850 		if( bNoteURL )
6851 		{
6852 			ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
6853 			pNoteURL = new SwNoteURL;
6854 		}
6855 		SwFlyFrm *pFly = (SwFlyFrm*)pFirst;
6856 
6857 		OutputDevice *pOld = pSh->GetOut();
6858 		VirtualDevice aDev( *pOld );
6859 		aDev.EnableOutput( sal_False );
6860 
6861 		GDIMetaFile aMet;
6862 		MapMode aMap( pOld->GetMapMode().GetMapUnit() );
6863 		aDev.SetMapMode( aMap );
6864 		aMet.SetPrefMapMode( aMap );
6865 
6866 		::SwCalcPixStatics( pSh->GetOut() );
6867 		aMet.SetPrefSize( pFly->Frm().SSize() );
6868 
6869 		aMet.Record( &aDev );
6870 		aDev.SetLineColor();
6871 		aDev.SetFillColor();
6872 		aDev.SetFont( pOld->GetFont() );
6873 
6874 		//Rechteck ggf. ausdehnen, damit die Umrandunge mit aufgezeichnet werden.
6875 		SwRect aOut( pFly->Frm() );
6876 		SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
6877 		const SwBorderAttrs &rAttrs = *aAccess.Get();
6878 		if ( rAttrs.CalcRightLine() )
6879 			aOut.SSize().Width() += 2*nPixelSzW;
6880 		if ( rAttrs.CalcBottomLine() )
6881 			aOut.SSize().Height()+= 2*nPixelSzH;
6882 
6883 		// #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
6884 		const Region aRepaintRegion(aOut.SVRect());
6885     	pSh->DLPrePaint2(aRepaintRegion);
6886 
6887         Window *pWin = pSh->GetWin();
6888 		sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom();
6889 		::SetOutDevAndWin( pSh, &aDev, 0, 100 );
6890 		bFlyMetafile = sal_True;
6891 		pFlyMetafileOut = pWin;
6892 
6893 		SwViewImp *pImp = pSh->Imp();
6894 		pFlyOnlyDraw = pFly;
6895 		pLines = new SwLineRects;
6896 
6897         // OD 09.12.2002 #103045# - determine page, fly frame is on
6898         const SwPageFrm* pFlyPage = pFly->FindPageFrm();
6899         const Color aPageBackgrdColor = pFlyPage->GetDrawBackgrdColor();
6900         const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6901         // --> OD #i76669#
6902         SwViewObjectContactRedirector aSwRedirector( *pSh );
6903         // <--
6904         pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor,
6905                           (pFlyPage->IsRightToLeft() ? true : false),
6906                           &aSwRedirector );
6907 		pLines->PaintLines( &aDev );
6908 		if ( pFly->IsFlyInCntFrm() )
6909 			pFly->Paint( aOut );
6910 		pLines->PaintLines( &aDev );
6911         /// OD 30.08.2002 #102450# - add 3rd parameter
6912         pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor,
6913                           (pFlyPage->IsRightToLeft() ? true : false),
6914                           &aSwRedirector );
6915 		pLines->PaintLines( &aDev );
6916 		DELETEZ( pLines );
6917 		pFlyOnlyDraw = 0;
6918 
6919 		pFlyMetafileOut = 0;
6920 		bFlyMetafile = sal_False;
6921 		::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
6922 
6923 		// #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted
6924    		pSh->DLPostPaint2(true);
6925 
6926         aMet.Stop();
6927 		aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() );
6928 		aRet = Graphic( aMet );
6929 
6930 		if( bNoteURL )
6931 		{
6932 			ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
6933 			pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap );
6934 			delete pNoteURL;
6935 			pNoteURL = NULL;
6936 		}
6937 		pGlobalShell = pOldGlobal;
6938 	}
6939 	return aRet;
6940 }
6941 
6942 Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* )
6943 {
6944 	Graphic aRet;
6945     SdrModel *pMod = getIDocumentDrawModelAccess()->GetDrawModel();
6946 	if ( pMod )
6947 	{
6948 		SdrObject *pObj = FindSdrObject();
6949 		SdrView *pView = new SdrView( pMod );
6950 		SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0));
6951 		pView->MarkObj( pObj, pPgView );
6952 		aRet = pView->GetMarkedObjBitmapEx();
6953 		pView->HideSdrPage();
6954 		delete pView;
6955 	}
6956 	return aRet;
6957 }
6958 
6959 
6960