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