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