xref: /trunk/main/sw/source/core/layout/paintfrm.cxx (revision 734ca04e)
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             const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
1655 
1656             //UUUU need to expand for correct AAed and non-AAed visualization as primitive.
1657             // This must probably be removed again when we will be able to get all Writer visualization
1658             // as primitives and Writer prepares all it's stuff in high precision coordinates (also
1659             // needs to avoid moving boundaries around to better show overlapping stuff...)
1660             if(aSvtOptionsDrawinglayer.IsAntiAliasing())
1661             {
1662                 // if AAed in principle expand by 0.5 in all directions. Since painting edges of
1663                 // AAed regions does not add to no transparence (0.5 opacity covered by 0.5 opacity
1664                 // is not full opacity but 0.75 opacity) we need some overlap here to avoid paint
1665                 // artifacts. Checked experimentally - a little bit more in Y is needed, probably
1666                 // due to still existing integer alignment and cruncing in writer.
1667                 static double fExpandX = 0.55;
1668                 static double fExpandY = 0.70;
1669                 const basegfx::B2DVector aSingleUnit(rOut.GetInverseViewTransformation() * basegfx::B2DVector(fExpandX, fExpandY));
1670 
1671                 aPaintRange.expand(aPaintRange.getMinimum() - aSingleUnit);
1672                 aPaintRange.expand(aPaintRange.getMaximum() + aSingleUnit);
1673             }
1674             else
1675             {
1676                 // if not AAed expand by one unit to bottom right due to the missing unit
1677                 // from SwRect/Rectangle integer handling
1678                 const basegfx::B2DVector aSingleUnit(rOut.GetInverseViewTransformation() * basegfx::B2DVector(1.0, 1.0));
1679 
1680                 aPaintRange.expand(aPaintRange.getMaximum() + aSingleUnit);
1681             }
1682 
1683             const basegfx::B2DRange aDefineRange(
1684                 rOriginalLayoutRect.Left(),
1685                 rOriginalLayoutRect.Top(),
1686                 rOriginalLayoutRect.Right(),
1687                 rOriginalLayoutRect.Bottom());
1688 
1689             const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rFillAttributes->getPrimitive2DSequence(
1690                 aPaintRange,
1691                 aDefineRange);
1692 
1693             if(rSequence.getLength())
1694             {
1695                 const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
1696                     basegfx::B2DHomMatrix(),
1697                     rOut.GetViewTransformation(),
1698                     aPaintRange,
1699                     0,
1700                     0.0,
1701                     uno::Sequence< beans::PropertyValue >());
1702                 drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice(
1703                     rOut,
1704                     aViewInformation2D);
1705 
1706                 if(pProcessor)
1707                 {
1708                     pProcessor->process(rSequence);
1709 
1710                     delete pProcessor;
1711 
1712                     if(bReturnWhenNew)
1713                     {
1714                         return true;
1715                     }
1716                 }
1717             }
1718         }
1719     }
1720 
1721     return false;
1722 }
1723 
1724 void MA_FASTCALL DrawGraphic(
1725     const SvxBrushItem *pBrush,
1726     OutputDevice *pOutDev,
1727     const SwRect &rOrg,
1728     const SwRect &rOut,
1729     const sal_uInt8 nGrfNum,
1730     const sal_Bool bConsiderBackgroundTransparency )
1731     /// OD 05.08.2002 #99657# - add 6th parameter to indicate that method should
1732     ///   consider background transparency, saved in the color of the brush item
1733 {
1734     ViewShell &rSh = *pGlobalShell;
1735     /// OD 17.10.2002 #103876# - change type from <sal_Bool> to <bool>
1736     bool bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum;
1737     bool bGrfNum = GRFNUM_NO != nGrfNum;
1738 	Size aGrfSize;
1739 	SvxGraphicPosition ePos = GPOS_NONE;
1740 	if( pBrush && !bReplaceGrfNum )
1741 	{
1742 		if( rSh.GetViewOptions()->IsGraphic() )
1743 		{
1744             //#125488#: load graphic directly in PDF import
1745             // --> OD 2006-08-25 #i68953# - also during print load graphic directly.
1746             if ( (rSh).GetViewOptions()->IsPDFExport() ||
1747                  rSh.GetOut()->GetOutDevType() == OUTDEV_PRINTER )
1748             // <--
1749             {
1750                 ((SvxBrushItem*)pBrush)->PurgeMedium();
1751                 ((SvxBrushItem*)pBrush)->SetDoneLink( Link() );
1752             }
1753             else
1754                 ((SvxBrushItem*)pBrush)->SetDoneLink( STATIC_LINK(
1755                                     rSh.GetDoc(), SwDoc, BackgroundDone ) );
1756             //SfxObjectShell &rObjSh = *GETOBJSHELL();
1757 			const Graphic* pGrf = pBrush->GetGraphic();
1758 			if( pGrf && GRAPHIC_NONE != pGrf->GetType() )
1759 			{
1760 				ePos = pBrush->GetGraphicPos();
1761 				if( pGrf->IsSupportedGraphic() )
1762 					// don't the use the specific output device! Bug 94802
1763                     aGrfSize = ::GetGraphicSizeTwip( *pGrf, 0 );
1764 			}
1765 		}
1766 		else
1767 			bReplaceGrfNum = bGrfNum;
1768 	}
1769 
1770 	SwRect aGrf;
1771 	aGrf.SSize( aGrfSize );
1772 	sal_Bool bDraw = sal_True;
1773 	sal_Bool bRetouche = sal_True;
1774 	switch ( ePos )
1775 	{
1776 	case GPOS_LT:
1777 		aGrf.Pos() = rOrg.Pos();
1778 		break;
1779 
1780 	case GPOS_MT:
1781 		aGrf.Pos().Y() = rOrg.Top();
1782 		aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1783 		break;
1784 
1785 	case GPOS_RT:
1786 		aGrf.Pos().Y() = rOrg.Top();
1787 		aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1788 		break;
1789 
1790 	case GPOS_LM:
1791 		aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1792 		aGrf.Pos().X() = rOrg.Left();
1793 		break;
1794 
1795 	case GPOS_MM:
1796 		aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1797 		aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1798 		break;
1799 
1800 	case GPOS_RM:
1801 		aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1802 		aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1803 		break;
1804 
1805 	case GPOS_LB:
1806 		aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1807 		aGrf.Pos().X() = rOrg.Left();
1808 		break;
1809 
1810 	case GPOS_MB:
1811 		aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1812 		aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1813 		break;
1814 
1815 	case GPOS_RB:
1816 		aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1817 		aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1818 		break;
1819 
1820 	case GPOS_AREA:
1821 		aGrf = rOrg;
1822         /// OD 05.09.2002 #102912#
1823         /// In spite the fact that the background graphic have to fill the complete
1824         /// area, it has been checked, if the graphic will completely fill out
1825         /// the region to be painted <rOut> and thus, nothing has to be retouched.
1826         /// For example, this is the case for a fly frame without a background
1827         /// brush positioned on the border of the page and inherited the
1828         /// background brush from the page.
1829         bRetouche = !rOut.IsInside( aGrf );
1830 		break;
1831 
1832 	case GPOS_TILED:
1833 		{
1834             // OD 17.10.2002 #103876# - draw background of tiled graphic
1835             // before drawing tiled graphic in loop
1836             // determine graphic object
1837             GraphicObject* pGraphicObj = const_cast< GraphicObject* >(pBrush->GetGraphicObject());
1838             // calculate aligned paint rectangle
1839             SwRect aAlignedPaintRect = rOut;
1840             ::SwAlignRect( aAlignedPaintRect, &rSh );
1841             // OD 25.10.2002 #103876# - draw background color for aligned paint rectangle
1842             lcl_DrawGraphicBackgrd( *pBrush, pOutDev, aAlignedPaintRect, *pGraphicObj, bGrfNum );
1843 
1844             // set left-top-corner of background graphic to left-top-corner of the
1845             // area, from which the background brush is determined.
1846             aGrf.Pos() = rOrg.Pos();
1847             // setup clipping at output device
1848             pOutDev->Push( PUSH_CLIPREGION );
1849             pOutDev->IntersectClipRegion( rOut.SVRect() );
1850             // OD 28.10.2002 #103876# - use new method <GraphicObject::DrawTiled(::)>
1851             {
1852                 // calculate paint offset
1853                 Point aPaintOffset( aAlignedPaintRect.Pos() - aGrf.Pos() );
1854                 // draw background graphic tiled for aligned paint rectangle
1855                 // --> OD 2005-02-15 #i42643# - apply fix #104004# for Calc
1856                 // also for Writer - see /sc/source/view/printfun.cxx
1857                 // For PDF export, every draw operation for bitmaps takes a
1858                 // noticeable amount of place (~50 characters). Thus, optimize
1859                 // between tile bitmap size and number of drawing operations here.
1860                 //
1861                 //                  A_out
1862                 // n_chars = k1 *  ---------- + k2 * A_bitmap
1863                 //                  A_bitmap
1864                 //
1865                 // minimum n_chars is obtained for (derive for  A_bitmap,
1866                 // set to 0, take positive solution):
1867                 //                   k1
1868                 // A_bitmap = Sqrt( ---- A_out )
1869                 //                   k2
1870                 //
1871                 // where k1 is the number of chars per draw operation, and
1872                 // k2 is the number of chars per bitmap pixel.
1873                 // This is approximately 50 and 7 for current PDF writer, respectively.
1874                 //
1875                 const double    k1( 50 );
1876                 const double    k2( 7 );
1877                 const Size      aSize( aAlignedPaintRect.SSize() );
1878                 const double    Abitmap( k1/k2 * static_cast<double>(aSize.Width())*aSize.Height() );
1879 
1880                 pGraphicObj->DrawTiled( pOutDev,
1881                                         aAlignedPaintRect.SVRect(),
1882                                         aGrf.SSize(),
1883                                         Size( aPaintOffset.X(), aPaintOffset.Y() ),
1884                                         NULL, GRFMGR_DRAW_STANDARD,
1885                                         ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1886                 // <--
1887             }
1888             // reset clipping at output device
1889             pOutDev->Pop();
1890             // set <bDraw> and <bRetouche> to false, indicating that background
1891             // graphic and background are already drawn.
1892             bDraw = bRetouche = sal_False;
1893 		}
1894 		break;
1895 
1896 	case GPOS_NONE:
1897 		bDraw = sal_False;
1898 		break;
1899 
1900     default: ASSERT( !pOutDev, "new Graphic position?" );
1901 	}
1902 
1903     /// OD 02.09.2002 #99657#
1904     /// init variable <bGrfBackgrdAlreadDrawn> to indicate, if background of
1905     /// graphic is already drawn or not.
1906     bool bGrfBackgrdAlreadyDrawn = false;
1907 	if ( bRetouche )
1908 	{
1909         // OD 2004-04-23 #116347#
1910         pOutDev->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
1911         pOutDev->SetLineColor();
1912 
1913         // OD 07.08.2002 #99657# #GetTransChg#
1914         //     check, if a existing background graphic (not filling the complete
1915         //     background) is transparent drawn and the background color is
1916         //     "no fill" respectively "auto fill", if background transparency
1917         //     has to be considered.
1918         //     If YES, memorise transparency of background graphic.
1919         //     check also, if background graphic bitmap is transparent.
1920         bool bTransparentGrfWithNoFillBackgrd = false;
1921         sal_Int32 nGrfTransparency = 0;
1922         bool bGrfIsTransparent = false;
1923         if ( (ePos != GPOS_NONE) &&
1924              (ePos != GPOS_TILED) && (ePos != GPOS_AREA)
1925            )
1926         {
1927             GraphicObject *pGrf = (GraphicObject*)pBrush->GetGraphicObject();
1928             if ( bConsiderBackgroundTransparency )
1929             {
1930                 GraphicAttr pGrfAttr = pGrf->GetAttr();
1931                 if ( (pGrfAttr.GetTransparency() != 0) &&
1932                      ( pBrush && (pBrush->GetColor() == COL_TRANSPARENT) )
1933                    )
1934                 {
1935                     bTransparentGrfWithNoFillBackgrd = true;
1936                     nGrfTransparency = pGrfAttr.GetTransparency();
1937                 }
1938             }
1939             if ( pGrf->IsTransparent() )
1940             {
1941                 bGrfIsTransparent = true;
1942             }
1943         }
1944 
1945         /// OD 06.08.2002 #99657# #GetTransChg# - to get color of brush,
1946         ///     check background color against COL_TRANSPARENT ("no fill"/"auto fill")
1947         ///     instead of checking, if transparency is not set.
1948         const Color aColor( pBrush &&
1949                             ( !(pBrush->GetColor() == COL_TRANSPARENT) ||
1950                               bFlyMetafile )
1951                     ? pBrush->GetColor()
1952                     : aGlobalRetoucheColor );
1953 
1954         /// OD 08.08.2002 #99657# - determine, if background region have to be
1955         ///     drawn transparent.
1956         ///     background region has to be drawn transparent, if
1957         ///         background transparency have to be considered
1958         ///     AND
1959         ///       ( background color is transparent OR
1960         ///         background graphic is transparent and background color is "no fill"
1961         ///       )
1962         sal_Bool bDrawTransparent = bConsiderBackgroundTransparency &&
1963                                 ( ( aColor.GetTransparency() != 0) ||
1964                                     bTransparentGrfWithNoFillBackgrd );
1965 
1966         // --> OD 2008-06-02 #i75614#
1967         // reset draw mode in high contrast mode in order to get fill color set
1968         const sal_uLong nOldDrawMode = pOutDev->GetDrawMode();
1969         if ( pGlobalShell->GetWin() &&
1970              Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1971         {
1972             pOutDev->SetDrawMode( 0 );
1973         }
1974         // <--
1975 
1976         /// OD 06.08.2002 #99657# - if background region have to be drawn
1977         ///     transparent, set only the RGB values of the background color as
1978         ///     the fill color for the output device.
1979         if ( bDrawTransparent )
1980         {
1981             if( pOutDev->GetFillColor() != aColor.GetRGBColor() )
1982                 pOutDev->SetFillColor( aColor.GetRGBColor() );
1983         }
1984         else
1985         {
1986             if( pOutDev->GetFillColor() != aColor )
1987                 pOutDev->SetFillColor( aColor );
1988         }
1989 
1990         // --> OD 2008-06-02 #i75614#
1991         // restore draw mode
1992         pOutDev->SetDrawMode( nOldDrawMode );
1993         // <--
1994 
1995         /// OD 02.09.2002 #99657#
1996         if ( bDrawTransparent )
1997         {
1998             /// background region have to be drawn transparent.
1999             /// Thus, create a poly-polygon from the region and draw it with
2000             /// the corresponding transparency precent.
2001             PolyPolygon aDrawPoly( rOut.SVRect() );
2002             if ( aGrf.HasArea() )
2003             {
2004                 if ( !bGrfIsTransparent )
2005                 {
2006                     /// subtract area of background graphic from draw area
2007                     /// OD 08.10.2002 #103898# - consider only that part of the
2008                     ///     graphic area that is overlapping with draw area.
2009                     SwRect aTmpGrf = aGrf;
2010                     aTmpGrf.Intersection( rOut );
2011                     if ( aTmpGrf.HasArea() )
2012                     {
2013                         Polygon aGrfPoly( aTmpGrf.SVRect() );
2014                         aDrawPoly.Insert( aGrfPoly );
2015                     }
2016                 }
2017                 else
2018                     bGrfBackgrdAlreadyDrawn = true;
2019             }
2020             /// calculate transparency percent:
2021             /// ( <transparency value[0x01..0xFF]>*100 + 0x7F ) / 0xFF
2022             /// If there is a background graphic with a background color "no fill"/"auto fill",
2023             /// the transparency value is taken from the background graphic,
2024             /// otherwise take the transparency value from the color.
2025             sal_Int8 nTransparencyPercent = static_cast<sal_Int8>(
2026               (( bTransparentGrfWithNoFillBackgrd ? nGrfTransparency : aColor.GetTransparency()
2027                )*100 + 0x7F)/0xFF);
2028             /// draw poly-polygon transparent
2029             pOutDev->DrawTransparent( aDrawPoly, nTransparencyPercent );
2030         }
2031         else
2032         {
2033             SwRegionRects aRegion( rOut, 4 );
2034             if ( !bGrfIsTransparent )
2035                 aRegion -= aGrf;
2036             else
2037                 bGrfBackgrdAlreadyDrawn = true;
2038             /// loop rectangles of background region, which has to be drawn
2039             for( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
2040             {
2041                 pOutDev->DrawRect( aRegion[i].SVRect() );
2042             }
2043         }
2044        pOutDev ->Pop();
2045 	}
2046 
2047     if( bDraw && aGrf.IsOver( rOut ) )
2048         /// OD 02.09.2002 #99657#
2049         /// add parameter <bGrfBackgrdAlreadyDrawn>
2050         lcl_DrawGraphic( *pBrush, pOutDev, rSh, aGrf, rOut, true, bGrfNum,
2051                          bGrfBackgrdAlreadyDrawn );
2052 
2053 	if( bReplaceGrfNum )
2054 	{
2055         const BitmapEx& rBmp = ViewShell::GetReplacementBitmap( false );
2056         Font aTmp( pOutDev->GetFont() );
2057         Graphic::DrawEx( pOutDev, aEmptyStr, aTmp, rBmp, rOrg.Pos(), rOrg.SSize() );
2058 	}
2059 }
2060 
2061 //------------------------------------------------------------------------
2062 
2063 /** local help method for SwRootFrm::Paint(..) - Adjust given rectangle to pixel size
2064 
2065     By OD at 27.09.2002 for #103636#
2066     In order to avoid paint errors caused by multiple alignments - e.g. method
2067     ::SwAlignRect(..) - and other changes to the rectangle to be painted,
2068     this method is called for the rectangle to be painted in order to
2069     adjust it to the pixel it is overlapping.
2070 
2071     @author OD
2072 */
2073 void lcl_AdjustRectToPixelSize( SwRect& io_aSwRect, const OutputDevice &aOut )
2074 {
2075     /// local constant object of class <Size> to determine number of Twips
2076     /// representing a pixel.
2077     const Size aTwipToPxSize( aOut.PixelToLogic( Size( 1,1 )) );
2078 
2079     /// local object of class <Rectangle> in Twip coordinates
2080     /// calculated from given rectangle aligned to pixel centers.
2081     const Rectangle aPxCenterRect = aOut.PixelToLogic(
2082             aOut.LogicToPixel( io_aSwRect.SVRect() ) );
2083 
2084     /// local constant object of class <Rectangle> representing given rectangle
2085     /// in pixel.
2086     const Rectangle aOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2087 
2088     /// calculate adjusted rectangle from pixel centered rectangle.
2089     /// Due to rounding differences <aPxCenterRect> doesn't exactly represents
2090     /// the Twip-centers. Thus, adjust borders by half of pixel width/height plus 1.
2091     /// Afterwards, adjust calculated Twip-positions of the all borders.
2092     Rectangle aSizedRect = aPxCenterRect;
2093     aSizedRect.Left() -= (aTwipToPxSize.Width()/2 + 1);
2094     aSizedRect.Right() += (aTwipToPxSize.Width()/2 + 1);
2095     aSizedRect.Top() -= (aTwipToPxSize.Height()/2 + 1);
2096     aSizedRect.Bottom() += (aTwipToPxSize.Height()/2 + 1);
2097 
2098     /// adjust left()
2099     while ( (aOut.LogicToPixel(aSizedRect)).Left() < aOrgPxRect.Left() )
2100     {
2101         ++aSizedRect.Left();
2102     }
2103     /// adjust right()
2104     while ( (aOut.LogicToPixel(aSizedRect)).Right() > aOrgPxRect.Right() )
2105     {
2106         --aSizedRect.Right();
2107     }
2108     /// adjust top()
2109     while ( (aOut.LogicToPixel(aSizedRect)).Top() < aOrgPxRect.Top() )
2110     {
2111         ++aSizedRect.Top();
2112     }
2113     /// adjust bottom()
2114     while ( (aOut.LogicToPixel(aSizedRect)).Bottom() > aOrgPxRect.Bottom() )
2115     {
2116         --aSizedRect.Bottom();
2117     }
2118 
2119     io_aSwRect = SwRect( aSizedRect );
2120 
2121 #ifdef DBG_UTIL
2122     Rectangle aTestOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2123     Rectangle aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2124     ASSERT( aTestOrgPxRect == aTestNewPxRect,
2125             "Error in lcl_AlignRectToPixelSize(..): Adjusted rectangle has incorrect position or size");
2126 #if OSL_DEBUG_LEVEL > 1
2127     Rectangle aTestNewRect( aSizedRect );
2128     /// check Left()
2129     --aSizedRect.Left();
2130     aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2131     ASSERT( aTestOrgPxRect.Left() >= (aTestNewPxRect.Left()+1),
2132             "Error in lcl_AlignRectToPixelSize(..): Left() not correct adjusted");
2133     ++aSizedRect.Left();
2134     /// check Right()
2135     ++aSizedRect.Right();
2136     aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2137     ASSERT( aTestOrgPxRect.Right() <= (aTestNewPxRect.Right()-1),
2138             "Error in lcl_AlignRectToPixelSize(..): Right() not correct adjusted");
2139     --aSizedRect.Right();
2140     /// check Top()
2141     --aSizedRect.Top();
2142     aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2143     ASSERT( aTestOrgPxRect.Top() >= (aTestNewPxRect.Top()+1),
2144             "Error in lcl_AlignRectToPixelSize(..): Top() not correct adjusted");
2145     ++aSizedRect.Top();
2146     /// check Bottom()
2147     ++aSizedRect.Bottom();
2148     aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2149     ASSERT( aTestOrgPxRect.Bottom() <= (aTestNewPxRect.Bottom()-1),
2150             "Error in lcl_AlignRectToPixelSize(..): Bottom() not correct adjusted");
2151     --aSizedRect.Bottom();
2152 #endif
2153 #endif
2154 }
2155 
2156 
2157 //
2158 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES START
2159 //
2160 
2161 struct SwLineEntry
2162 {
2163     SwTwips mnKey;
2164     SwTwips mnStartPos;
2165     SwTwips mnEndPos;
2166 
2167     svx::frame::Style maAttribute;
2168 
2169     enum OverlapType { NO_OVERLAP, OVERLAP1, OVERLAP2, OVERLAP3 };
2170 
2171 public:
2172     SwLineEntry( SwTwips nKey,
2173                  SwTwips nStartPos,
2174                  SwTwips nEndPos,
2175                  const svx::frame::Style& rAttribute );
2176 
2177     OverlapType Overlaps( const SwLineEntry& rComp ) const;
2178 };
2179 
2180 SwLineEntry::SwLineEntry( SwTwips nKey,
2181                           SwTwips nStartPos,
2182                           SwTwips nEndPos,
2183                           const svx::frame::Style& rAttribute )
2184     :   mnKey( nKey ),
2185         mnStartPos( nStartPos ),
2186         mnEndPos( nEndPos ),
2187         maAttribute( rAttribute )
2188 {
2189 }
2190 
2191 /*
2192 
2193  1. ----------    rOld
2194        ---------- rNew
2195 
2196  2. ----------    rOld
2197     ------------- rNew
2198 
2199  3.    -------    rOld
2200     ------------- rNew
2201 
2202  4. ------------- rOld
2203        ---------- rNew
2204 
2205  5. ----------    rOld
2206        ----       rNew
2207 
2208  6. ----------    rOld
2209     ----------    rNew
2210 
2211  7. ------------- rOld
2212     ----------    rNew
2213 
2214  8.    ---------- rOld
2215     ------------- rNew
2216 
2217  9.    ---------- rOld
2218     ----------    rNew
2219 */
2220 
2221 SwLineEntry::OverlapType SwLineEntry::Overlaps( const SwLineEntry& rNew )  const
2222 {
2223     SwLineEntry::OverlapType eRet = OVERLAP3;
2224 
2225     if ( mnStartPos >= rNew.mnEndPos || mnEndPos <= rNew.mnStartPos )
2226         eRet = NO_OVERLAP;
2227 
2228     // 1, 2, 3
2229     else if ( mnEndPos < rNew.mnEndPos )
2230         eRet = OVERLAP1;
2231 
2232     // 4, 5, 6, 7
2233     else if ( mnStartPos <= rNew.mnStartPos && mnEndPos >= rNew.mnEndPos )
2234         eRet = OVERLAP2;
2235 
2236     // 8, 9
2237     return eRet;
2238 }
2239 
2240 struct lt_SwLineEntry
2241 {
2242     bool operator()( const SwLineEntry& e1, const SwLineEntry& e2 ) const
2243     {
2244         return e1.mnStartPos < e2.mnStartPos;
2245     }
2246 };
2247 
2248 typedef std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet;
2249 typedef std::set< SwLineEntry, lt_SwLineEntry >::iterator SwLineEntrySetIter;
2250 typedef std::set< SwLineEntry, lt_SwLineEntry >::const_iterator SwLineEntrySetConstIter;
2251 typedef std::map< SwTwips, SwLineEntrySet > SwLineEntryMap;
2252 typedef std::map< SwTwips, SwLineEntrySet >::iterator SwLineEntryMapIter;
2253 typedef std::map< SwTwips, SwLineEntrySet >::const_iterator SwLineEntryMapConstIter;
2254 
2255 class SwTabFrmPainter
2256 {
2257     SwLineEntryMap maVertLines;
2258     SwLineEntryMap maHoriLines;
2259     const SwTabFrm& mrTabFrm;
2260 
2261     void Insert( SwLineEntry&, bool bHori );
2262     void Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem );
2263     void HandleFrame( const SwLayoutFrm& rFrm );
2264     void FindStylesForLine( const Point&,
2265                             const Point&,
2266                             svx::frame::Style*,
2267                             bool bHori ) const;
2268 
2269 public:
2270     SwTabFrmPainter( const SwTabFrm& rTabFrm );
2271 
2272     void PaintLines( OutputDevice& rDev, const SwRect& rRect ) const;
2273 };
2274 
2275 SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm )
2276     : mrTabFrm( rTabFrm )
2277 {
2278     HandleFrame( rTabFrm );
2279 }
2280 
2281 void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm )
2282 {
2283     // Add border lines of cell frames. Skip covered cells. Skip cells
2284     // in special row span row, which do not have a negative row span:
2285     if ( rLayoutFrm.IsCellFrm() && !rLayoutFrm.IsCoveredCell() )
2286     {
2287         const SwCellFrm* pThisCell = static_cast<const SwCellFrm*>(&rLayoutFrm);
2288         const SwRowFrm* pRowFrm = static_cast<const SwRowFrm*>(pThisCell->GetUpper());
2289         const long nRowSpan = pThisCell->GetTabBox()->getRowSpan();
2290         if ( !pRowFrm->IsRowSpanLine() || nRowSpan > 1 || nRowSpan < -1 )
2291         {
2292             SwBorderAttrAccess aAccess( SwFrm::GetCache(), &rLayoutFrm );
2293             const SwBorderAttrs& rAttrs = *aAccess.Get();
2294             const SvxBoxItem& rBox = rAttrs.GetBox();
2295             Insert( rLayoutFrm, rBox );
2296         }
2297     }
2298 
2299     // Recurse into lower layout frames, but do not recurse into lower tabframes.
2300     const SwFrm* pLower = rLayoutFrm.Lower();
2301     while ( pLower )
2302     {
2303         const SwLayoutFrm* pLowerLayFrm = dynamic_cast<const SwLayoutFrm*>(pLower);
2304         if ( pLowerLayFrm && !pLowerLayFrm->IsTabFrm() )
2305             HandleFrame( *pLowerLayFrm );
2306 
2307         pLower = pLower->GetNext();
2308     }
2309 }
2310 
2311 void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) const
2312 {
2313     // --> FME 2004-06-24 #i16816# tagged pdf support
2314     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev );
2315     // <--
2316 
2317     const SwFrm* pTmpFrm = &mrTabFrm;
2318     const bool bVert = pTmpFrm->IsVertical();
2319 
2320     SwLineEntryMapConstIter aIter = maHoriLines.begin();
2321     bool bHori = true;
2322 
2323     // color for subsidiary lines:
2324     const Color& rCol( SwViewOption::GetTableBoundariesColor() );
2325 
2326     // high contrast mode:
2327     // overrides the color of non-subsidiary lines.
2328     const Color* pHCColor = 0;
2329     sal_uLong nOldDrawMode = rDev.GetDrawMode();
2330     if( pGlobalShell->GetWin() &&
2331         Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
2332     {
2333         pHCColor = &SwViewOption::GetFontColor();
2334         rDev.SetDrawMode( 0 );
2335     }
2336 
2337     // set clip region:
2338     rDev.Push( PUSH_CLIPREGION );
2339     Size aSize( rRect.SSize() );
2340     // Hack! Necessary, because the layout is not pixel aligned!
2341     aSize.Width() += nPixelSzW; aSize.Height() += nPixelSzH;
2342     rDev.SetClipRegion( Rectangle( rRect.Pos(), aSize ) );
2343 
2344     // The following stuff if necessary to have the new table borders fit
2345     // into a ::SwAlignRect adjusted world.
2346     const SwTwips nTwipXCorr =  bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 );    // 1 < 2 < 3 ;-)
2347     const SwTwips nTwipYCorr = !bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 );    // 1 < 2 < 3 ;-)
2348     const SwFrm* pUpper = mrTabFrm.GetUpper();
2349     SwRect aUpper( pUpper->Prt() );
2350     aUpper.Pos() += pUpper->Frm().Pos();
2351     SwRect aUpperAligned( aUpper );
2352     ::SwAlignRect( aUpperAligned, pGlobalShell );
2353 
2354     while ( true )
2355     {
2356         if ( bHori && aIter == maHoriLines.end() )
2357         {
2358             aIter = maVertLines.begin();
2359             bHori = false;
2360         }
2361 
2362         if ( !bHori && aIter == maVertLines.end() )
2363             break;
2364 
2365         const SwLineEntrySet& rEntrySet = (*aIter).second;
2366         SwLineEntrySetConstIter aSetIter = rEntrySet.begin();
2367         while ( aSetIter != rEntrySet.end() )
2368         {
2369             const SwLineEntry& rEntry = *aSetIter;
2370             const svx::frame::Style& rEntryStyle( (*aSetIter).maAttribute );
2371 
2372             Point aStart, aEnd;
2373             if ( bHori )
2374             {
2375                 aStart.X() = rEntry.mnStartPos;
2376                 aStart.Y() = rEntry.mnKey;
2377                 aEnd.X() = rEntry.mnEndPos;
2378                 aEnd.Y() = rEntry.mnKey;
2379             }
2380             else
2381             {
2382                 aStart.X() = rEntry.mnKey;
2383                 aStart.Y() = rEntry.mnStartPos;
2384                 aEnd.X() = rEntry.mnKey;
2385                 aEnd.Y() = rEntry.mnEndPos;
2386             }
2387 
2388             SwRect aRepaintRect( aStart, aEnd );
2389 
2390             // the repaint rectangle has to be moved a bit for the centered lines:
2391             SwTwips nRepaintRectSize = !rEntryStyle.GetWidth() ? 1 : rEntryStyle.GetWidth();
2392             if ( bHori )
2393             {
2394                 aRepaintRect.Height( 2 * nRepaintRectSize );
2395                 aRepaintRect.Pos().Y() -= nRepaintRectSize;
2396             }
2397             else
2398             {
2399                 aRepaintRect.Width( 2 * nRepaintRectSize );
2400                 aRepaintRect.Pos().X() -= nRepaintRectSize;
2401             }
2402 
2403             if ( rRect.IsOver( aRepaintRect ) )
2404             {
2405                 svx::frame::Style aStyles[ 7 ];
2406                 aStyles[ 0 ] = rEntryStyle;
2407                 FindStylesForLine( aStart, aEnd, aStyles, bHori );
2408 
2409                 // subsidiary lines
2410                 const Color* pTmpColor = 0;
2411                 if ( 0 == aStyles[ 0 ].GetWidth() )
2412                 {
2413                     if ( IS_SUBS_TABLE && pGlobalShell->GetWin() )
2414                         aStyles[ 0 ].Set( rCol, 1, 0, 0 );
2415                 }
2416                 else
2417                     pTmpColor = pHCColor;
2418 
2419                 // The line sizes stored in the line style have to be adjusted as well.
2420                 // This will guarantee that lines with the same twip size will have the
2421                 // same pixel size.
2422                 for ( int i = 0; i < 7; ++i )
2423                 {
2424                     sal_uInt16 nPrim = aStyles[ i ].Prim();
2425                     sal_uInt16 nDist = aStyles[ i ].Dist();
2426                     sal_uInt16 nSecn = aStyles[ i ].Secn();
2427 
2428                     if ( nPrim > 0 )
2429                         nPrim = (sal_uInt16)( Max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) );
2430                     if ( nDist > 0 )
2431                         nDist = (sal_uInt16)( Max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) );
2432                     if ( nSecn > 0 )
2433                         nSecn = (sal_uInt16)( Max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) );
2434 
2435                     aStyles[ i ].Set( nPrim, nDist, nSecn );
2436                 }
2437 
2438                 // The (twip) positions will be adjusted to meet these requirements:
2439                 // 1. The y coordinates are located in the middle of the pixel grid
2440                 // 2. The x coordinated are located at the beginning of the pixel grid
2441                 // This is done, because the horizontal lines are painted "at beginning",
2442                 // whereas the vertical lines are painted "centered". By making the line
2443                 // sizes a multiple of one pixel size, we can assure, that all lines having
2444                 // the same twip size have the same pixel size, independent of their position
2445                 // on the screen.
2446                 Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel( aStart ) );
2447                 Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel( aEnd ) );
2448 
2449                 if( pGlobalShell->GetWin() )
2450                 {
2451                     // The table borders do not use SwAlignRect, but all the other frames do.
2452                     // Therefore we tweak the outer borders a bit to achieve that the outer
2453                     // borders match the subsidiary lines of the upper:
2454                     if ( aStart.X() == aUpper.Left() )
2455                         aPaintStart.X() = aUpperAligned.Left();
2456                     else if ( aStart.X() == aUpper._Right() )
2457                         aPaintStart.X() = aUpperAligned._Right();
2458                     if ( aStart.Y() == aUpper.Top() )
2459                         aPaintStart.Y() = aUpperAligned.Top();
2460                     else if ( aStart.Y() == aUpper._Bottom() )
2461                         aPaintStart.Y() = aUpperAligned._Bottom();
2462 
2463                     if ( aEnd.X() == aUpper.Left() )
2464                         aPaintEnd.X() = aUpperAligned.Left();
2465                     else if ( aEnd.X() == aUpper._Right() )
2466                         aPaintEnd.X() = aUpperAligned._Right();
2467                     if ( aEnd.Y() == aUpper.Top() )
2468                         aPaintEnd.Y() = aUpperAligned.Top();
2469                     else if ( aEnd.Y() == aUpper._Bottom() )
2470                         aPaintEnd.Y() = aUpperAligned._Bottom();
2471                 }
2472 
2473                 aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel
2474                 aPaintEnd.X()   -= nTwipXCorr;
2475                 aPaintStart.Y() -= nTwipYCorr;
2476                 aPaintEnd.Y()   -= nTwipYCorr;
2477 
2478                 // Here comes the painting stuff: Thank you, DR, great job!!!
2479                 if ( bHori )
2480                 {
2481                     svx::frame::DrawHorFrameBorder
2482                     (
2483                         rDev,
2484                         aPaintStart,
2485                         aPaintEnd,
2486                         aStyles[ 0 ],   // current style
2487                         aStyles[ 1 ],   // aLFromT
2488                         aStyles[ 2 ],   // aLFromL
2489                         aStyles[ 3 ],   // aLFromB
2490                         aStyles[ 4 ],   // aRFromT
2491                         aStyles[ 5 ],   // aRFromR
2492                         aStyles[ 6 ],   // aRFromB
2493                         pTmpColor
2494                     );
2495                 }
2496                 else
2497                 {
2498                     svx::frame::DrawVerFrameBorder
2499                     (
2500                         rDev,
2501                         aPaintStart,
2502                         aPaintEnd,
2503                         aStyles[ 0 ],   // current style
2504                         aStyles[ 1 ],   // aTFromL
2505                         aStyles[ 2 ],   // aTFromT
2506                         aStyles[ 3 ],   // aTFromR
2507                         aStyles[ 4 ],   // aBFromL
2508                         aStyles[ 5 ],   // aBFromB
2509                         aStyles[ 6 ],   // aBFromR
2510                         pTmpColor
2511                     );
2512                 }
2513             }
2514 
2515             ++aSetIter;
2516         }
2517 
2518         ++aIter;
2519     }
2520 
2521     // restore output device:
2522     rDev.Pop();
2523     rDev.SetDrawMode( nOldDrawMode );
2524 }
2525 
2526 // Finds the lines that join the line defined by (StartPoint, EndPoint) in either
2527 // StartPoint or Endpoint. The styles of these lines are required for DR's magic
2528 // line painting functions.
2529 void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint,
2530                                          const Point& rEndPoint,
2531                                          svx::frame::Style* pStyles,
2532                                          bool bHori ) const
2533 {
2534     // pStyles[ 1 ] = bHori ? aLFromT : TFromL
2535     // pStyles[ 2 ] = bHori ? aLFromL : TFromT,
2536     // pStyles[ 3 ] = bHori ? aLFromB : TFromR,
2537     // pStyles[ 4 ] = bHori ? aRFromT : BFromL,
2538     // pStyles[ 5 ] = bHori ? aRFromR : BFromB,
2539     // pStyles[ 6 ] = bHori ? aRFromB : BFromR,
2540 
2541     SwLineEntryMapConstIter aMapIter = maVertLines.find( rStartPoint.X() );
2542     ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" )
2543     const SwLineEntrySet& rVertSet = (*aMapIter).second;
2544     SwLineEntrySetConstIter aIter = rVertSet.begin();
2545 
2546     while ( aIter != rVertSet.end() )
2547     {
2548         const SwLineEntry& rEntry = *aIter;
2549         if ( bHori )
2550         {
2551             if ( rStartPoint.Y() == rEntry.mnStartPos )
2552                 pStyles[ 3 ] = rEntry.maAttribute;
2553             else if ( rStartPoint.Y() == rEntry.mnEndPos )
2554                 pStyles[ 1 ] = rEntry.maAttribute;
2555         }
2556         else
2557         {
2558             if ( rStartPoint.Y() == rEntry.mnEndPos )
2559                 pStyles[ 2 ] = rEntry.maAttribute;
2560             else if ( rEndPoint.Y() == rEntry.mnStartPos )
2561                 pStyles[ 5 ] = rEntry.maAttribute;
2562         }
2563         ++aIter;
2564     }
2565 
2566     aMapIter = maHoriLines.find( rStartPoint.Y() );
2567     ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" )
2568     const SwLineEntrySet& rHoriSet = (*aMapIter).second;
2569     aIter = rHoriSet.begin();
2570 
2571     while ( aIter != rHoriSet.end() )
2572     {
2573         const SwLineEntry& rEntry = *aIter;
2574         if ( bHori )
2575         {
2576             if ( rStartPoint.X() == rEntry.mnEndPos )
2577                 pStyles[ 2 ] = rEntry.maAttribute;
2578             else if ( rEndPoint.X() == rEntry.mnStartPos )
2579                 pStyles[ 5 ] = rEntry.maAttribute;
2580         }
2581         else
2582         {
2583             if ( rStartPoint.X() == rEntry.mnEndPos )
2584                 pStyles[ 1 ] = rEntry.maAttribute;
2585             else if ( rStartPoint.X() == rEntry.mnStartPos )
2586                 pStyles[ 3 ] = rEntry.maAttribute;
2587         }
2588         ++aIter;
2589     }
2590 
2591     if ( bHori )
2592     {
2593         aMapIter = maVertLines.find( rEndPoint.X() );
2594         ASSERT( aMapIter != maVertLines.end(), "FindStylesForLine: Error" )
2595         const SwLineEntrySet& rVertSet2 = (*aMapIter).second;
2596         aIter = rVertSet2.begin();
2597 
2598         while ( aIter != rVertSet2.end() )
2599         {
2600             const SwLineEntry& rEntry = *aIter;
2601             if ( rEndPoint.Y() == rEntry.mnStartPos )
2602                 pStyles[ 6 ] = rEntry.maAttribute;
2603             else if ( rEndPoint.Y() == rEntry.mnEndPos )
2604                 pStyles[ 4 ] = rEntry.maAttribute;
2605             ++aIter;
2606         }
2607     }
2608     else
2609     {
2610         aMapIter = maHoriLines.find( rEndPoint.Y() );
2611         ASSERT( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" )
2612         const SwLineEntrySet& rHoriSet2 = (*aMapIter).second;
2613         aIter = rHoriSet2.begin();
2614 
2615         while ( aIter != rHoriSet2.end() )
2616         {
2617             const SwLineEntry& rEntry = *aIter;
2618             if ( rEndPoint.X() == rEntry.mnEndPos )
2619                 pStyles[ 4 ] = rEntry.maAttribute;
2620             else if ( rEndPoint.X() == rEntry.mnStartPos )
2621                 pStyles[ 6 ] = rEntry.maAttribute;
2622             ++aIter;
2623         }
2624     }
2625 }
2626 
2627 void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem )
2628 {
2629     std::vector< const SwFrm* > aTestVec;
2630     aTestVec.push_back( &rFrm );
2631     aTestVec.push_back( &rFrm );
2632     aTestVec.push_back( &rFrm );
2633 
2634     // build 4 line entries for the 4 borders:
2635     SwRect aBorderRect = rFrm.Frm();
2636     if ( rFrm.IsTabFrm() )
2637     {
2638         aBorderRect = rFrm.Prt();
2639         aBorderRect.Pos() += rFrm.Frm().Pos();
2640     }
2641 
2642     const SwTwips nLeft   = aBorderRect._Left();
2643     const SwTwips nRight  = aBorderRect._Right();
2644     const SwTwips nTop    = aBorderRect._Top();
2645     const SwTwips nBottom = aBorderRect._Bottom();
2646 
2647     svx::frame::Style aL( rBoxItem.GetLeft() );
2648     svx::frame::Style aR( rBoxItem.GetRight() );
2649     svx::frame::Style aT( rBoxItem.GetTop() );
2650     svx::frame::Style aB( rBoxItem.GetBottom() );
2651 
2652     aR.MirrorSelf();
2653     aB.MirrorSelf();
2654 
2655     bool bVert = mrTabFrm.IsVertical();
2656     bool bR2L  = mrTabFrm.IsRightToLeft();
2657 
2658     aL.SetRefMode( svx::frame::REFMODE_CENTERED );
2659     aR.SetRefMode( svx::frame::REFMODE_CENTERED );
2660     aT.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
2661     aB.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
2662 
2663     SwLineEntry aLeft  ( nLeft,   nTop,  nBottom, bVert ? aB : ( bR2L ? aR : aL ) );
2664     SwLineEntry aRight ( nRight,  nTop,  nBottom, bVert ? aT : ( bR2L ? aL : aR ) );
2665     SwLineEntry aTop   ( nTop,    nLeft, nRight,  bVert ? aL : aT );
2666     SwLineEntry aBottom( nBottom, nLeft, nRight,  bVert ? aR : aB );
2667 
2668     Insert( aLeft, false );
2669     Insert( aRight, false );
2670     Insert( aTop, true );
2671     Insert( aBottom, true );
2672 
2673     const SwRowFrm* pThisRowFrm = dynamic_cast<const SwRowFrm*>(rFrm.GetUpper());
2674 
2675     // special case: #i9860#
2676     // first line in follow table without repeated headlines
2677     if ( pThisRowFrm &&
2678          pThisRowFrm->GetUpper() == &mrTabFrm &&
2679          mrTabFrm.IsFollow() &&
2680         !mrTabFrm.GetTable()->GetRowsToRepeat() &&
2681         (!pThisRowFrm->GetPrev() || static_cast<const SwRowFrm*>(pThisRowFrm->GetPrev())->IsRowSpanLine()) &&
2682         !rBoxItem.GetTop() &&
2683          rBoxItem.GetBottom() )
2684     {
2685         SwLineEntry aFollowTop( !bVert ? nTop : nRight, !bVert ? nLeft : nTop, !bVert ? nRight : nBottom, aB );
2686         Insert( aFollowTop, !bVert );
2687     }
2688 }
2689 
2690 void SwTabFrmPainter::Insert( SwLineEntry& rNew, bool bHori )
2691 {
2692     // get all lines from structure, that have key entry of pLE
2693     SwLineEntryMap* pLine2 = bHori ? &maHoriLines : &maVertLines;
2694     const SwTwips nKey = rNew.mnKey;
2695     SwLineEntryMapIter aMapIter = pLine2->find( nKey );
2696 
2697     SwLineEntrySet* pLineSet = aMapIter != pLine2->end() ? &((*aMapIter).second) : 0;
2698     if ( !pLineSet )
2699     {
2700         SwLineEntrySet aNewSet;
2701         (*pLine2)[ nKey ] = aNewSet;
2702         pLineSet = &(*pLine2)[ nKey ];
2703     }
2704     SwLineEntrySetIter aIter = pLineSet->begin();
2705 
2706     while ( pLineSet && aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos )
2707     {
2708         const SwLineEntry& rOld = *aIter;
2709         const SwLineEntry::OverlapType nOverlapType = rOld.Overlaps( rNew );
2710 
2711         const svx::frame::Style& rOldAttr = rOld.maAttribute;
2712         const svx::frame::Style& rNewAttr = rNew.maAttribute;
2713         const svx::frame::Style& rCmpAttr = rNewAttr > rOldAttr ? rNewAttr : rOldAttr;
2714 
2715         if ( SwLineEntry::OVERLAP1 == nOverlapType )
2716         {
2717             ASSERT( rNew.mnStartPos >= rOld.mnStartPos, "Overlap type 3? How this?" )
2718 
2719             // new left segment
2720             const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
2721 
2722             // new middle segment
2723             const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rOld.mnEndPos, rCmpAttr );
2724 
2725             // new right segment
2726             rNew.mnStartPos = rOld.mnEndPos;
2727 
2728             // update current lines set
2729             pLineSet->erase( aIter );
2730             if ( aLeft.mnStartPos   < aLeft.mnEndPos   ) pLineSet->insert( aLeft );
2731             if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2732 
2733             aIter = pLineSet->begin();
2734 
2735             continue; // start over
2736         }
2737         else if ( SwLineEntry::OVERLAP2 == nOverlapType )
2738         {
2739             // new left segment
2740             const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
2741 
2742             // new middle segment
2743             const SwLineEntry aMiddle( nKey, rNew.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         else if ( SwLineEntry::OVERLAP3 == nOverlapType )
2759         {
2760             // new left segment
2761             const SwLineEntry aLeft( nKey, rNew.mnStartPos, rOld.mnStartPos, rNewAttr );
2762 
2763             // new middle segment
2764             const SwLineEntry aMiddle( nKey, rOld.mnStartPos, rNew.mnEndPos, rCmpAttr );
2765 
2766             // new right segment
2767             const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr );
2768 
2769             // update current lines set
2770             pLineSet->erase( aIter );
2771             if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
2772             if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2773             if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
2774 
2775             rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
2776 
2777             break; // we are finished
2778         }
2779 
2780         ++aIter;
2781     }
2782 
2783     if ( rNew.mnStartPos < rNew.mnEndPos ) // insert rest
2784         pLineSet->insert( rNew );
2785 }
2786 
2787 //
2788 // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES END
2789 //
2790 
2791 // --> OD #i76669#
2792 namespace
2793 {
2794     class SwViewObjectContactRedirector : public ::sdr::contact::ViewObjectContactRedirector
2795     {
2796         private:
2797             const ViewShell& mrViewShell;
2798 
2799         public:
2800             SwViewObjectContactRedirector( const ViewShell& rSh )
2801                 : mrViewShell( rSh )
2802             {};
2803 
2804             virtual ~SwViewObjectContactRedirector()
2805             {}
2806 
2807             virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence(
2808                                     const sdr::contact::ViewObjectContact& rOriginal,
2809                                     const sdr::contact::DisplayInfo& rDisplayInfo)
2810             {
2811                 sal_Bool bPaint( sal_True );
2812 
2813                 SdrObject* pObj = rOriginal.GetViewContact().TryToGetSdrObject();
2814                 if ( pObj )
2815                 {
2816                     bPaint = SwFlyFrm::IsPaint( pObj, &mrViewShell );
2817                 }
2818 
2819                 if ( !bPaint )
2820                 {
2821                     return drawinglayer::primitive2d::Primitive2DSequence();
2822                 }
2823 
2824                 return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
2825                                                         rOriginal, rDisplayInfo );
2826             }
2827     };
2828 
2829 } // end of anonymous namespace
2830 // <--
2831 
2832 /*************************************************************************
2833 |*
2834 |*	SwRootFrm::Paint()
2835 |*
2836 |*	Beschreibung
2837 |*		Fuer jede sichtbare Seite, die von Rect ber?hrt wird einmal Painten.
2838 |*		1. Umrandungen und Hintergruende Painten.
2839 |*		2. Den Draw Layer (Ramen und Zeichenobjekte) der unter dem Dokument
2840 |* 		   liegt painten (Hoelle).
2841 |*		3. Den Dokumentinhalt (Text) Painten.
2842 |*		4. Den Drawlayer der ueber dem Dokuemnt liegt painten.
2843 |*
2844 |*	Ersterstellung		MA 01. Jun. 92
2845 |*	Letzte Aenderung	MA 10. Oct. 97
2846 |*
2847 |*************************************************************************/
2848 
2849 void
2850 SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const
2851 {
2852     ASSERT( Lower() && Lower()->IsPageFrm(), "Lower der Root keine Seite." );
2853 
2854 	PROTOCOL( this, PROT_FILE_INIT, 0, 0)
2855 
2856 	sal_Bool bResetRootPaint = sal_False;
2857 	ViewShell *pSh = pCurrShell;
2858 
2859 	if ( pSh->GetWin() )
2860 	{
2861 		if ( pSh->GetOut() == pSh->GetWin() && !pSh->GetWin()->IsVisible() )
2862 		{
2863 			return;
2864 		}
2865 		if ( SwRootFrm::bInPaint )
2866 		{
2867 			SwPaintQueue::Add( pSh, rRect );
2868 			return;
2869 		}
2870 	}
2871 	else
2872 		SwRootFrm::bInPaint = bResetRootPaint = sal_True;
2873 
2874 	SwSavePaintStatics *pStatics = 0;
2875 	if ( pGlobalShell )
2876 		pStatics = new SwSavePaintStatics();
2877 	pGlobalShell = pSh;
2878 
2879     if( !pSh->GetWin() )
2880 		pProgress = SfxProgress::GetActiveProgress( (SfxObjectShell*) pSh->GetDoc()->GetDocShell() );
2881 
2882 	::SwCalcPixStatics( pSh->GetOut() );
2883 	aGlobalRetoucheColor = pSh->Imp()->GetRetoucheColor();
2884 
2885 	//Ggf. eine Action ausloesen um klare Verhaeltnisse zu schaffen.
2886 	//Durch diesen Kunstgriff kann in allen Paints davon ausgegangen werden,
2887 	//das alle Werte gueltigt sind - keine Probleme, keine Sonderbehandlung(en).
2888     // --> OD 2008-10-07 #i92745#
2889     // Extend check on certain states of the 'current' <ViewShell> instance to
2890     // all existing <ViewShell> instances.
2891     bool bPerformLayoutAction( true );
2892     {
2893         ViewShell* pTmpViewShell = pSh;
2894         do {
2895             if ( pTmpViewShell->IsInEndAction() ||
2896                  pTmpViewShell->IsPaintInProgress() ||
2897                  ( pTmpViewShell->Imp()->IsAction() &&
2898                    pTmpViewShell->Imp()->GetLayAction().IsActionInProgress() ) )
2899             {
2900                 bPerformLayoutAction = false;
2901             }
2902 
2903             pTmpViewShell = static_cast<ViewShell*>(pTmpViewShell->GetNext());
2904         } while ( bPerformLayoutAction && pTmpViewShell != pSh );
2905     }
2906     if ( bPerformLayoutAction )
2907     // <--
2908     {
2909 		((SwRootFrm*)this)->ResetTurbo();
2910 		SwLayAction aAction( (SwRootFrm*)this, pSh->Imp() );
2911 		aAction.SetPaint( sal_False );
2912 		aAction.SetComplete( sal_False );
2913 		aAction.SetReschedule( pProgress ? sal_True : sal_False );
2914 		aAction.Action();
2915 		((SwRootFrm*)this)->ResetTurboFlag();
2916 		if ( !pSh->ActionPend() )
2917             pSh->Imp()->DelRegion();
2918 	}
2919 
2920 	SwRect aRect( rRect );
2921     aRect.Intersection( pSh->VisArea() );
2922 
2923     const sal_Bool bExtraData = ::IsExtraData( GetFmt()->GetDoc() );
2924 
2925 	pLines = new SwLineRects;	//Sammler fuer Umrandungen.
2926 
2927     // #104289#. During painting, something (OLE) can
2928     // load the linguistic, which in turn can cause a reformat
2929     // of the document. Dangerous! We better set this flag to
2930     // avoid the reformat.
2931     const sal_Bool bOldAction = IsCallbackActionEnabled();
2932     ((SwRootFrm*)this)->SetCallbackActionEnabled( sal_False );
2933 
2934 	const SwPageFrm *pPage = pSh->Imp()->GetFirstVisPage();
2935 
2936     const bool bBookMode = pGlobalShell->GetViewOptions()->IsViewLayoutBookMode();
2937     if ( bBookMode && pPage->GetPrev() && static_cast<const SwPageFrm*>(pPage->GetPrev())->IsEmptyPage() )
2938         pPage = static_cast<const SwPageFrm*>(pPage->GetPrev());
2939 
2940     const bool bLTR = IsLeftToRightViewLayout();
2941 
2942 	// #i68597#
2943 	const bool bGridPainting(pSh->GetWin() && pSh->Imp()->HasDrawView() && pSh->Imp()->GetDrawView()->IsGridVisible());
2944 
2945     // --> OD #i76669#
2946     SwViewObjectContactRedirector aSwRedirector( *pSh );
2947     // <--
2948 
2949     while ( pPage )
2950     {
2951         const bool bPaintRightShadow =  !bBookMode || (pPage == Lower()) || (!bLTR && !pPage->OnRightPage()) || (bLTR && pPage->OnRightPage());
2952         const bool bRightSidebar = pPage->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT;
2953 
2954         if ( !pPage->IsEmptyPage() )
2955         {
2956             SwRect aPaintRect;
2957             SwPageFrm::GetBorderAndShadowBoundRect( pPage->Frm(), pSh, aPaintRect, bRightSidebar );
2958 
2959             if ( aRect.IsOver( aPaintRect ) )
2960             {
2961                 if ( pSh->GetWin() )
2962                 {
2963                     pSubsLines = new SwSubsRects;
2964                     pSpecSubsLines = new SwSubsRects;
2965                 }
2966 
2967                 aPaintRect._Intersection( aRect );
2968 
2969                 // --> OD 2007-11-14 #i82616#
2970                 // Invalidate area for extra data (line numbers or change tracking
2971                 // marks), if painting on a window and the paint is trigger by an
2972                 // end action. The inefficient and simple enlargement of the
2973                 // paint area is replaced by this invalidation.
2974                 if ( bExtraData &&
2975                      pSh->GetWin() && pSh->IsInEndAction() )
2976                 {
2977                     // enlarge paint rectangle to complete page width, subtract
2978                     // current paint area and invalidate the resulting region.
2979                     SWRECTFN( pPage )
2980                     SwRect aPageRectTemp( aPaintRect );
2981                     (aPageRectTemp.*fnRect->fnSetLeftAndWidth)(
2982                          (pPage->Frm().*fnRect->fnGetLeft)(),
2983                          (pPage->Frm().*fnRect->fnGetWidth)() );
2984                     aPageRectTemp._Intersection( pSh->VisArea() );
2985                     Region aPageRectRegion( aPageRectTemp.SVRect() );
2986                     aPageRectRegion.Exclude( aPaintRect.SVRect() );
2987                     pSh->GetWin()->Invalidate( aPageRectRegion, INVALIDATE_CHILDREN );
2988                 }
2989                 // <--
2990 
2991                 // --> OD 2007-08-20 #i80793#
2992                 // enlarge paint rectangle for objects overlapping the same pixel
2993                 // in all cases and before the DrawingLayer overlay is initialized.
2994                 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
2995                 // <--
2996 
2997                 // #i68597#
2998                 // moved paint pre-process for DrawingLayer overlay here since the above
2999                 // code dependent from bExtraData may expand the PaintRect
3000                 {
3001                     // #i75172# if called from ViewShell::ImplEndAction it sould no longer
3002                     // really be used but handled by ViewShell::ImplEndAction already
3003                     const Region aDLRegion(aPaintRect.SVRect());
3004                     pSh->DLPrePaint2(aDLRegion);
3005                 }
3006 
3007                 if(OUTDEV_WINDOW == pGlobalShell->GetOut()->GetOutDevType())
3008                 {
3009                     /// OD 27.09.2002 #103636# - changed method SwLayVout::Enter(..)
3010                     /// 2nd parameter is no longer <const> and will be set to the
3011                     /// rectangle the virtual output device is calculated from <aPaintRect>,
3012                     /// if the virtual output is used.
3013                     pVout->Enter( pSh, aPaintRect, !bNoVirDev );
3014 
3015                     /// OD 27.09.2002 #103636# - adjust paint rectangle to pixel size
3016                     /// Thus, all objects overlapping on pixel level with the unadjusted
3017                     /// paint rectangle will be considered in the paint.
3018                     lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
3019                 }
3020 
3021                 // maybe this can be put in the above scope. Since we are not sure, just leave it ATM
3022                 pVout->SetOrgRect( aPaintRect );
3023 
3024                 /// OD 29.08.2002 #102450#
3025                 /// determine background color of page for <PaintLayer> method
3026                 /// calls, paint <hell> or <heaven>
3027                 const Color aPageBackgrdColor(pPage->GetDrawBackgrdColor());
3028 
3029                 pPage->PaintBaBo( aPaintRect, pPage, sal_True );
3030 
3031                 if ( pSh->Imp()->HasDrawView() )
3032                 {
3033                     pLines->LockLines( sal_True );
3034                     const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
3035                     pSh->Imp()->PaintLayer( pIDDMA->GetHellId(),
3036                                             pPrintData,
3037                                             aPaintRect,
3038                                             &aPageBackgrdColor,
3039                                             (pPage->IsRightToLeft() ? true : false),
3040                                             &aSwRedirector );
3041                     pLines->PaintLines( pSh->GetOut() );
3042                     pLines->LockLines( sal_False );
3043                 }
3044 
3045                 if( pSh->GetWin() )
3046                 {
3047                     // collect sub-lines
3048                     pPage->RefreshSubsidiary( aPaintRect );
3049                     // paint special sub-lines
3050                     pSpecSubsLines->PaintSubsidiary( pSh->GetOut(), NULL );
3051                 }
3052 
3053                 pPage->Paint( aPaintRect );
3054 
3055                 // no paint of page border and shadow, if writer is in place mode.
3056                 if( pSh->GetWin() && pSh->GetDoc()->GetDocShell() &&
3057                     !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
3058                 {
3059                     SwPageFrm::PaintBorderAndShadow( pPage->Frm(), pSh, bPaintRightShadow, bRightSidebar );
3060                     SwPageFrm::PaintNotesSidebar( pPage->Frm(), pSh, pPage->GetPhyPageNum(), bRightSidebar);
3061                 }
3062 
3063                 pLines->PaintLines( pSh->GetOut() );
3064 
3065                 if ( pSh->Imp()->HasDrawView() )
3066                 {
3067                     /// OD 29.08.2002 #102450# - add 3rd parameter
3068                     // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
3069                     pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(),
3070                                             pPrintData,
3071                                             aPaintRect,
3072                                             &aPageBackgrdColor,
3073                                             (pPage->IsRightToLeft() ? true : false),
3074                                             &aSwRedirector );
3075                 }
3076 
3077                 if ( bExtraData )
3078                     pPage->RefreshExtraData( aPaintRect );
3079 
3080                 if ( pSh->GetWin() )
3081                 {
3082                     pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines );
3083                     DELETEZ( pSubsLines );
3084                     DELETEZ( pSpecSubsLines );
3085                 }
3086                 pVout->Leave();
3087 
3088                 // #i68597#
3089                 // needed to move grid painting inside Begin/EndDrawLayer bounds and to change
3090                 // output rect for it accordingly
3091                 if(bGridPainting)
3092                 {
3093                     SdrPaintView* pPaintView = pSh->Imp()->GetDrawView();
3094                     SdrPageView* pPageView = pPaintView->GetSdrPageView();
3095                     pPageView->DrawPageViewGrid(*pSh->GetOut(), aPaintRect.SVRect(), SwViewOption::GetTextGridColor() );
3096                 }
3097 
3098                 // #i68597#
3099                 // moved paint post-process for DrawingLayer overlay here, see above
3100                 {
3101                     pSh->DLPostPaint2(true);
3102                 }
3103             }
3104         }
3105         else if ( bBookMode && pSh->GetWin() && !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
3106         {
3107             // paint empty page
3108             SwRect aPaintRect;
3109             SwRect aEmptyPageRect( pPage->Frm() );
3110 
3111             // code from vprint.cxx
3112             const SwPageFrm& rFormatPage = pPage->GetFormatPage();
3113             aEmptyPageRect.SSize() = rFormatPage.Frm().SSize();
3114 
3115             SwPageFrm::GetBorderAndShadowBoundRect( aEmptyPageRect, pSh, aPaintRect, bRightSidebar );
3116             aPaintRect._Intersection( aRect );
3117 
3118             if ( aRect.IsOver( aEmptyPageRect ) )
3119             {
3120                 // #i75172# if called from ViewShell::ImplEndAction it sould no longer
3121                 // really be used but handled by ViewShell::ImplEndAction already
3122                 {
3123                     const Region aDLRegion(aPaintRect.SVRect());
3124                     pSh->DLPrePaint2(aDLRegion);
3125                 }
3126 
3127                 if( pSh->GetOut()->GetFillColor() != aGlobalRetoucheColor )
3128                     pSh->GetOut()->SetFillColor( aGlobalRetoucheColor );
3129 
3130                 pSh->GetOut()->SetLineColor(); // OD 20.02.2003 #107369# - no line color
3131                 // OD 20.02.2003 #107369# - use aligned page rectangle
3132                 {
3133                     SwRect aTmpPageRect( aEmptyPageRect );
3134                     ::SwAlignRect( aTmpPageRect, pSh );
3135                     aEmptyPageRect = aTmpPageRect;
3136                 }
3137 
3138                 pSh->GetOut()->DrawRect( aEmptyPageRect.SVRect() );
3139 
3140                 // paint empty page text
3141                 const Font& rEmptyPageFont = SwPageFrm::GetEmptyPageFont();
3142                 const Font aOldFont( pSh->GetOut()->GetFont() );
3143 
3144                 pSh->GetOut()->SetFont( rEmptyPageFont );
3145                 pSh->GetOut()->DrawText( aEmptyPageRect.SVRect(), SW_RESSTR( STR_EMPTYPAGE ),
3146                                     TEXT_DRAW_VCENTER |
3147                                     TEXT_DRAW_CENTER |
3148                                     TEXT_DRAW_CLIP );
3149 
3150                 pSh->GetOut()->SetFont( aOldFont );
3151                 // paint shadow and border for empty page
3152                 // OD 19.02.2003 #107369# - use new method to paint page border and
3153                 // shadow
3154                 SwPageFrm::PaintBorderAndShadow( aEmptyPageRect, pSh, bPaintRightShadow, bRightSidebar );
3155                 SwPageFrm::PaintNotesSidebar( aEmptyPageRect, pSh, pPage->GetPhyPageNum(), bRightSidebar);
3156 
3157                 {
3158                     pSh->DLPostPaint2(true);
3159                 }
3160             }
3161         }
3162 
3163         ASSERT( !pPage->GetNext() || pPage->GetNext()->IsPageFrm(),
3164                 "Nachbar von Seite keine Seite." );
3165         pPage = (SwPageFrm*)pPage->GetNext();
3166     }
3167 
3168     DELETEZ( pLines );
3169 
3170 #ifdef FRANK_TEST
3171 	if ( pSh->GetWin() )
3172     {
3173         Rectangle aRect( aFrm.SVRect() );
3174         pSh->GetWin()->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
3175         pSh->GetWin()->SetFillColor();
3176         pSh->GetWin()->SetLineColor( COL_LIGHTRED );
3177         pSh->GetWin()->DrawRect( aRect );
3178         pSh->GetWin()->Pop();
3179     }
3180 #endif
3181 
3182 	if ( bResetRootPaint )
3183 		SwRootFrm::bInPaint = sal_False;
3184 	if ( pStatics )
3185 		delete pStatics;
3186 	else
3187 	{
3188 		pProgress = 0;
3189 		pGlobalShell = 0;
3190 	}
3191 
3192     ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction );
3193 }
3194 
3195 #ifdef LONG_TABLE_HACK
3196 
3197 /*************************************************************************
3198 |*
3199 |*	SwRootFrm::HackPrepareLongTblPaint()
3200 |*
3201 |*	Ersterstellung		MA 27. Sep. 96
3202 |*	Letzte Aenderung	MA 18. Nov. 97
3203 |*
3204 |*************************************************************************/
3205 
3206 void SwRootFrm::HackPrepareLongTblPaint( int nMode )
3207 {
3208 	switch ( nMode )
3209 	{
3210 		case HACK_TABLEMODE_INIT       : ASSERT( !pLines, "HackPrepare: already prepared" );
3211 										 pLines = new SwLineRects;
3212 										 ASSERT( !pGlobalShell, "old GlobalShell lost" );
3213 										 pGlobalShell = GetCurrShell();
3214 										 bTableHack = sal_True;
3215 										 break;
3216 		case HACK_TABLEMODE_LOCKLINES  : pLines->LockLines( sal_True ); break;
3217 		case HACK_TABLEMODE_PAINTLINES : pLines->PaintLines( GetShell()->GetOut() );
3218 										 break;
3219 		case HACK_TABLEMODE_UNLOCKLINES: pLines->LockLines( sal_False ); break;
3220 		case HACK_TABLEMODE_EXIT       : pLines->PaintLines( GetCurrShell()->GetOut() );
3221 										 DELETEZ( pLines );
3222 										 pGlobalShell = 0;
3223 										 bTableHack = sal_False;
3224 										 break;
3225 	}
3226 }
3227 
3228 #endif
3229 
3230 
3231 /*************************************************************************
3232 |*
3233 |*	SwLayoutFrm::Paint()
3234 |*
3235 |*	Ersterstellung		MA 19. May. 92
3236 |*	Letzte Aenderung	MA 19. Apr. 95
3237 |*
3238 |*************************************************************************/
3239 
3240 void MA_FASTCALL lcl_EmergencyFormatFtnCont( SwFtnContFrm *pCont )
3241 {
3242 	//Es kann sein, dass der Cont vernichtet wird.
3243 	SwCntntFrm *pCnt = pCont->ContainsCntnt();
3244 	while ( pCnt && pCnt->IsInFtn() )
3245 	{
3246 		pCnt->Calc();
3247 		pCnt = pCnt->GetNextCntntFrm();
3248 	}
3249 }
3250 
3251 class SwShortCut
3252 {
3253     SwRectDist fnCheck;
3254     long nLimit;
3255 public:
3256     SwShortCut( const SwFrm& rFrm, const SwRect& rRect );
3257     sal_Bool Stop( const SwRect& rRect ) const
3258         { return (rRect.*fnCheck)( nLimit ) > 0; }
3259 };
3260 
3261 SwShortCut::SwShortCut( const SwFrm& rFrm, const SwRect& rRect )
3262 {
3263     sal_Bool bVert = rFrm.IsVertical();
3264     sal_Bool bR2L = rFrm.IsRightToLeft();
3265     if( rFrm.IsNeighbourFrm() && bVert == bR2L )
3266     {
3267         if( bVert )
3268         {
3269             fnCheck = &SwRect::GetBottomDistance;
3270             nLimit = rRect.Top();
3271         }
3272         else
3273         {
3274             fnCheck = &SwRect::GetLeftDistance;
3275             nLimit = rRect.Left() + rRect.Width();
3276         }
3277     }
3278     else if( bVert == rFrm.IsNeighbourFrm() )
3279     {
3280         fnCheck = &SwRect::GetTopDistance;
3281         nLimit = rRect.Top() + rRect.Height();
3282     }
3283     else
3284     {
3285         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
3286         if ( rFrm.IsVertLR() )
3287 	    {
3288            	fnCheck = &SwRect::GetLeftDistance;
3289            	nLimit = rRect.Right();
3290         }
3291         else
3292         {
3293         	fnCheck = &SwRect::GetRightDistance;
3294         	nLimit = rRect.Left();
3295         }
3296     }
3297 }
3298 
3299 void SwLayoutFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3300 {
3301     ViewShell *pSh = getRootFrm()->GetCurrShell();
3302 
3303     // --> FME 2004-06-24 #i16816# tagged pdf support
3304     Frm_Info aFrmInfo( *this );
3305     SwTaggedPDFHelper aTaggedPDFHelper( 0, &aFrmInfo, 0, *pSh->GetOut() );
3306     // <--
3307 
3308 	const SwFrm *pFrm = Lower();
3309 	if ( !pFrm )
3310 		return;
3311 
3312     SwShortCut aShortCut( *pFrm, rRect );
3313 	sal_Bool bCnt;
3314 	if ( sal_True == (bCnt = pFrm->IsCntntFrm()) )
3315 		pFrm->Calc();
3316 
3317 	if ( pFrm->IsFtnContFrm() )
3318     {
3319         ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm );
3320 		pFrm = Lower();
3321 	}
3322 
3323 	const SwPageFrm *pPage = 0;
3324 	const sal_Bool bWin   = pGlobalShell->GetWin() ? sal_True : sal_False;
3325 
3326 	while ( IsAnLower( pFrm ) )
3327 	{
3328         SwRect aPaintRect( pFrm->PaintArea() );
3329         if( aShortCut.Stop( aPaintRect ) )
3330 			break;
3331 		if ( bCnt && pProgress )
3332 			pProgress->Reschedule();
3333 
3334 		//Wenn ein Frm es explizit will muss retouchiert werden.
3335 		//Erst die Retouche, denn selbige koennte die aligned'en Raender
3336 		//plaetten.
3337 		if ( pFrm->IsRetouche() )
3338 		{
3339 			if ( pFrm->IsRetoucheFrm() && bWin && !pFrm->GetNext() )
3340 			{	if ( !pPage )
3341 					pPage = FindPageFrm();
3342                pFrm->Retouche( pPage, rRect );
3343 			}
3344 			pFrm->ResetRetouche();
3345 		}
3346 
3347         if ( rRect.IsOver( aPaintRect ) )
3348 		{
3349 			if ( bCnt && pFrm->IsCompletePaint() &&
3350 				 !rRect.IsInside( aPaintRect ) && GetpApp()->AnyInput( INPUT_KEYBOARD ) )
3351 			{
3352 				//fix(8104): Es kann vorkommen, dass die Verarbeitung nicht
3353 				//vollstaendig war, aber trotzdem Teile des Absatzes gepaintet
3354 				//werden. In der Folge werden dann evtl. wiederum andere Teile
3355 				//des Absatzes garnicht mehr gepaintet. Einziger Ausweg scheint
3356 				//hier ein Invalidieren der Windows zu sein.
3357 				//Um es nicht alzu Heftig werden zu lassen versuche ich hier
3358 				//das Rechteck zu begrenzen indem der gewuenschte Teil gepaintet
3359 				//und nur die uebrigen Absatzanteile invalidiert werden.
3360 				if ( aPaintRect.Left()	== rRect.Left() &&
3361 					 aPaintRect.Right() == rRect.Right() )
3362 				{
3363 					aPaintRect.Bottom( rRect.Top() - 1 );
3364 					if ( aPaintRect.Height() > 0 )
3365 						pGlobalShell->InvalidateWindows(aPaintRect);
3366 					aPaintRect.Top( rRect.Bottom() + 1 );
3367 					aPaintRect.Bottom( pFrm->Frm().Bottom() );
3368 					if ( aPaintRect.Height() > 0 )
3369 						pGlobalShell->InvalidateWindows(aPaintRect);
3370 					aPaintRect.Top( pFrm->Frm().Top() );
3371 					aPaintRect.Bottom( pFrm->Frm().Bottom() );
3372 				}
3373 				else
3374 				{
3375 					pGlobalShell->InvalidateWindows( aPaintRect );
3376 					pFrm = pFrm->GetNext();
3377 					if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) )
3378 						pFrm->Calc();
3379 					continue;
3380 				}
3381 			}
3382 			pFrm->ResetCompletePaint();
3383 			aPaintRect._Intersection( rRect );
3384 
3385             pFrm->Paint( aPaintRect );
3386 
3387             if ( Lower() && Lower()->IsColumnFrm() )
3388 			{
3389 				//Ggf. die Spaltentrennlinien malen. Fuer den Seitenbody ist
3390 				//nicht der Upper sondern die Seite Zustaendig.
3391 				const SwFrmFmt *pFmt = GetUpper() && GetUpper()->IsPageFrm()
3392 											? GetUpper()->GetFmt()
3393 											: GetFmt();
3394 				const SwFmtCol &rCol = pFmt->GetCol();
3395 				if ( rCol.GetLineAdj() != COLADJ_NONE )
3396 				{
3397 					if ( !pPage )
3398 						pPage = pFrm->FindPageFrm();
3399 
3400                     PaintColLines( aPaintRect, rCol, pPage );
3401                 }
3402 			}
3403         }
3404 		if ( !bCnt && pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() )
3405 			::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm->GetNext() );
3406 
3407 		pFrm = pFrm->GetNext();
3408 		if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) )
3409 			pFrm->Calc();
3410 	}
3411 }
3412 
3413 
3414 /** FlyFrm::IsBackgroundTransparent - for feature #99657#
3415 
3416     OD 12.08.2002
3417     determines, if background of fly frame has to be drawn transparent
3418     declaration found in /core/inc/flyfrm.cxx
3419     OD 08.10.2002 #103898# - If the background of the fly frame itself is not
3420     transparent and the background is inherited from its parent/grandparent,
3421     the background brush, used for drawing, has to be investigated for transparency.
3422 
3423     @author OD
3424 
3425     @return true, if background is transparent drawn.
3426 */
3427 sal_Bool SwFlyFrm::IsBackgroundTransparent() const
3428 {
3429     sal_Bool bBackgroundTransparent = GetFmt()->IsBackgroundTransparent();
3430     if ( !bBackgroundTransparent &&
3431          static_cast<const SwFlyFrmFmt*>(GetFmt())->IsBackgroundBrushInherited() )
3432     {
3433         const SvxBrushItem* pBackgrdBrush = 0;
3434         const Color* pSectionTOXColor = 0;
3435         SwRect aDummyRect;
3436 
3437         //UUUU
3438         drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes;
3439 
3440         if ( GetBackgroundBrush( aFillAttributes, pBackgrdBrush, pSectionTOXColor, aDummyRect, false) )
3441         {
3442             if ( pSectionTOXColor &&
3443                  (pSectionTOXColor->GetTransparency() != 0) &&
3444                  (pSectionTOXColor->GetColor() != COL_TRANSPARENT) )
3445             {
3446                 bBackgroundTransparent = sal_True;
3447             }
3448             else if(aFillAttributes.get() && aFillAttributes->isUsed()) //UUUU
3449             {
3450                 bBackgroundTransparent = aFillAttributes->isTransparent();
3451             }
3452             else if ( pBackgrdBrush )
3453             {
3454                 if ( (pBackgrdBrush->GetColor().GetTransparency() != 0) &&
3455                      (pBackgrdBrush->GetColor() != COL_TRANSPARENT) )
3456                 {
3457                     bBackgroundTransparent = sal_True;
3458                 }
3459                 else
3460                 {
3461                     const GraphicObject *pTmpGrf =
3462                             static_cast<const GraphicObject*>(pBackgrdBrush->GetGraphicObject());
3463                     if ( (pTmpGrf) &&
3464                          (pTmpGrf->GetAttr().GetTransparency() != 0)
3465                        )
3466                     {
3467                         bBackgroundTransparent = sal_True;
3468                     }
3469                 }
3470             }
3471         }
3472     }
3473 
3474     return bBackgroundTransparent;
3475 };
3476 
3477 /** FlyFrm::IsShadowTransparent - for feature #99657#
3478 
3479     OD 13.08.2002
3480     determine, if shadow color of fly frame has to be drawn transparent
3481     declaration found in /core/inc/flyfrm.cxx
3482 
3483     @author OD
3484 
3485     @return true, if shadow color is transparent.
3486 */
3487 sal_Bool SwFlyFrm::IsShadowTransparent() const
3488 {
3489     return GetFmt()->IsShadowTransparent();
3490 };
3491 
3492 /*************************************************************************
3493 |*
3494 |*	SwFlyFrm::IsPaint()
3495 |*
3496 |*	Ersterstellung		MA 16. Jan. 97
3497 |*	Letzte Aenderung	MA 16. Jan. 97
3498 |*
3499 |*************************************************************************/
3500 
3501 sal_Bool SwFlyFrm::IsPaint( SdrObject *pObj, const ViewShell *pSh )
3502 {
3503 	SdrObjUserCall *pUserCall;
3504 
3505 	if ( 0 == ( pUserCall = GetUserCall(pObj) ) )
3506 		return sal_True;
3507 
3508 	//Attributabhaengig nicht fuer Drucker oder PreView painten
3509 	sal_Bool bPaint =  pFlyOnlyDraw ||
3510 					   ((SwContact*)pUserCall)->GetFmt()->GetPrint().GetValue();
3511 	if ( !bPaint )
3512 		bPaint = pSh->GetWin() && !pSh->IsPreView();
3513 
3514 	if ( bPaint )
3515 	{
3516 		//Das Paint kann evtl. von von uebergeordneten Flys verhindert werden.
3517         SwFrm *pAnch = 0;
3518         // --> OD #i117962#
3519         if ( pObj->ISA(SwFlyDrawObj) )
3520         {
3521             bPaint = false;
3522         }
3523         // <--
3524         else if ( pObj->ISA(SwVirtFlyDrawObj) )
3525 		{
3526 			SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
3527 			if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly )
3528 				return sal_True;
3529 
3530 			//Die Anzeige eines Zwischenstadiums vermeiden, Flys die nicht mit
3531 			//der Seite auf der sie verankert sind ueberlappen werden auch
3532 			//nicht gepaintet.
3533 			//HACK: Ausnahme: Drucken von Rahmen in Tabellen, diese koennen
3534 			//bei uebergrossen Tabellen (HTML) schon mal auserhalb der Seite
3535 			//stehen.
3536 			SwPageFrm *pPage = pFly->FindPageFrm();
3537 			if ( pPage )
3538 			{
3539 				if ( pPage->Frm().IsOver( pFly->Frm() ) )
3540                     pAnch = pFly->AnchorFrm();
3541 				else if ( bTableHack &&
3542                           pFly->Frm().Top() >= pFly->GetAnchorFrm()->Frm().Top() &&
3543                           pFly->Frm().Top() < pFly->GetAnchorFrm()->Frm().Bottom() &&
3544                           long(pSh->GetOut()) ==
3545                           long(pSh->getIDocumentDeviceAccess()->getPrinter( false ) ) )
3546 				{
3547                     pAnch = pFly->AnchorFrm();
3548 				}
3549 			}
3550 
3551 		}
3552 		else
3553 		{
3554             // OD 13.10.2003 #i19919# - consider 'virtual' drawing objects
3555             // OD 2004-03-29 #i26791#
3556             pAnch = ((SwDrawContact*)pUserCall)->GetAnchorFrm( pObj );
3557 			if ( pAnch )
3558 			{
3559 				if ( !pAnch->GetValidPosFlag() )
3560 					pAnch = 0;
3561                 else if ( long(pSh->GetOut()) == long(pSh->getIDocumentDeviceAccess()->getPrinter( false )))
3562 				{
3563 					//HACK: fuer das Drucken muessen wir ein paar Objekte
3564 					//weglassen, da diese sonst doppelt gedruckt werden.
3565 					//Die Objekte sollen gedruckt werden, wenn der TableHack
3566 					//gerade greift. In der Folge duerfen sie nicht gedruckt werden
3567 					//wenn sie mit der Seite dran sind, ueber der sie von der
3568 					//Position her gerade schweben.
3569                     const SwPageFrm *pPage = pAnch->FindPageFrm();
3570 					if ( !bTableHack &&
3571 						 !pPage->Frm().IsOver( pObj->GetCurrentBoundRect() ) )
3572 						pAnch = 0;
3573 				}
3574 			}
3575             else
3576             {
3577                 // OD 02.07.2003 #108784# - debug assert
3578                 if ( !pObj->ISA(SdrObjGroup) )
3579                 {
3580                     ASSERT( false, "<SwFlyFrm::IsPaint(..)> - paint of drawing object without anchor frame!?" );
3581                 }
3582             }
3583 		}
3584 		if ( pAnch )
3585 		{
3586 			if ( pAnch->IsInFly() )
3587 				bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(),
3588 											pSh );
3589 			else if ( pFlyOnlyDraw )
3590 				bPaint = sal_False;
3591 		}
3592 		else
3593 			bPaint = sal_False;
3594 	}
3595 	return bPaint;
3596 }
3597 
3598 /*************************************************************************
3599 |*  SwCellFrm::Paint( const SwRect& ) const
3600 |*************************************************************************/
3601 void SwCellFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3602 {
3603     if ( GetLayoutRowSpan() >= 1 )
3604         SwLayoutFrm::Paint( rRect );
3605 }
3606 
3607 /*************************************************************************
3608 |*
3609 |*	SwFlyFrm::Paint()
3610 |*
3611 |*	Ersterstellung		MA ??
3612 |*	Letzte Aenderung	MA 16. Jan. 97
3613 |*
3614 |*************************************************************************/
3615 
3616 //Weiter unten definiert
3617 void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay,
3618 							   const SwRect &rRect, const SwPageFrm *pPage );
3619 
3620 void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3621 {
3622 	//begin:optimize thumbnail generate and store procedure to improve odt saving performance, i120030
3623 	ViewShell *pShell = getRootFrm()->GetCurrShell();
3624 	if (pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocShell())
3625 	{
3626 		sal_Bool bInGenerateThumbnail = pShell->GetDoc()->GetDocShell()->IsInGenerateAndStoreThumbnail();
3627 		if (bInGenerateThumbnail)
3628 		{
3629 			SwRect aVisRect = pShell->VisArea();
3630 			if (!aVisRect.IsOver(Frm()))
3631 				return;
3632 		}
3633 	}
3634 	//end:i120030
3635 
3636     //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die
3637 	//Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben.
3638 	//z.B. #33066#
3639 	pLines->LockLines(sal_True);
3640 
3641     SwRect aRect( rRect );
3642 	aRect._Intersection( Frm() );
3643 
3644     OutputDevice* pOut = pGlobalShell->GetOut();
3645 	pOut->Push( PUSH_CLIPREGION );
3646 	pOut->SetClipRegion();
3647     const SwPageFrm* pPage = FindPageFrm();
3648 
3649 	const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm()
3650 												? (SwNoTxtFrm*)Lower() : 0;
3651 
3652     bool bIsChart = false; //#i102950# don't paint additional borders for charts
3653     //check whether we have a chart
3654     if(pNoTxt)
3655     {
3656         const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode());
3657         if( pNoTNd )
3658         {
3659             SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode());
3660             if( pOLENd && ChartHelper::IsChart( pOLENd->GetOLEObj().GetObject() ) )
3661                 bIsChart = true;
3662         }
3663     }
3664 
3665 	{
3666         bool bContour = GetFmt()->GetSurround().IsContour();
3667 		PolyPolygon aPoly;
3668 		if ( bContour )
3669         {
3670             // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True>
3671             // to indicate that method is called for paint in order to avoid
3672             // load of the intrinsic graphic.
3673             bContour = GetContour( aPoly, sal_True );
3674         }
3675 
3676         // --> OD 2005-06-08 #i47804# - distinguish complete background paint
3677         // and margin paint.
3678         // paint complete background for Writer text fly frames
3679         bool bPaintCompleteBack( !pNoTxt );
3680         // <--
3681         // paint complete background for transparent graphic and contour,
3682         // if own background color exists.
3683         const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false;
3684         if ( !bPaintCompleteBack &&
3685              ( bIsGraphicTransparent|| bContour ) )
3686 		{
3687             const SwFrmFmt* pSwFrmFmt = dynamic_cast< const SwFrmFmt* >(GetFmt());
3688 
3689             if(pSwFrmFmt && pSwFrmFmt->supportsFullDrawingLayerFillAttributeSet())
3690             {
3691                 //UUUU check for transparency
3692                 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(pSwFrmFmt->getSdrAllFillAttributesHelper());
3693 
3694                 // check if the new fill attributes are used
3695                 if(aFillAttributes.get() && aFillAttributes->isUsed())
3696                 {
3697                     bPaintCompleteBack = true;
3698                 }
3699             }
3700             else
3701             {
3702 			    const SvxBrushItem &rBack = GetFmt()->GetBackground();
3703                 // OD 07.08.2002 #99657# #GetTransChg#
3704                 //     to determine, if background has to be painted, by checking, if
3705                 //     background color is not COL_TRANSPARENT ("no fill"/"auto fill")
3706                 //     or a background graphic exists.
3707                 bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) ||
3708                                      rBack.GetGraphicPos() != GPOS_NONE;
3709             }
3710 		}
3711         // paint of margin needed.
3712         const bool bPaintMarginOnly( !bPaintCompleteBack &&
3713                                      Prt().SSize() != Frm().SSize() );
3714 
3715         // --> OD 2005-06-08 #i47804# - paint background of parent fly frame
3716         // for transparent graphics in layer Hell, if parent fly frame isn't
3717         // in layer Hell. It's only painted the intersection between the
3718         // parent fly frame area and the paint area <aRect>
3719         const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
3720 
3721         if ( bIsGraphicTransparent &&
3722             GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() &&
3723             GetAnchorFrm()->FindFlyFrm() )
3724         {
3725             const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm();
3726             if ( pParentFlyFrm->GetDrawObj()->GetLayer() !=
3727                                             pIDDMA->GetHellId() )
3728             {
3729                 SwFlyFrm* pOldRet = pRetoucheFly2;
3730                 pRetoucheFly2 = const_cast<SwFlyFrm*>(this);
3731 
3732                 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm );
3733                 const SwBorderAttrs &rAttrs = *aAccess.Get();
3734                 SwRect aPaintRect( aRect );
3735                 aPaintRect._Intersection( pParentFlyFrm->Frm() );
3736                 pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False );
3737 
3738                 pRetoucheFly2 = pOldRet;
3739             }
3740         }
3741 
3742         if ( bPaintCompleteBack || bPaintMarginOnly )
3743 		{
3744 			//#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder
3745 			//das orig. Rect bekommt, aber PaintBackground das begrenzte.
3746 
3747             // OD 2004-04-23 #116347#
3748             pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
3749             pOut->SetLineColor();
3750 
3751 			pPage = FindPageFrm();
3752 
3753 			SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3754 			const SwBorderAttrs &rAttrs = *aAccess.Get();
3755 
3756             // OD 06.08.2002 #99657# - paint border before painting background
3757             // paint border
3758             {
3759                 SwRect aTmp( rRect );
3760                 PaintBorder( aTmp, pPage, rAttrs );
3761             }
3762 
3763             // paint background
3764             {
3765                 SwRegionRects aRegion( aRect );
3766                 // --> OD 2007-12-13 #i80822#
3767                 // suppress painting of background in printing area for
3768                 // non-transparent graphics.
3769 //                if ( bPaintMarginOnly )
3770                 if ( bPaintMarginOnly ||
3771                      ( pNoTxt && !bIsGraphicTransparent ) )
3772                 // <--
3773                 {
3774                     //Was wir eigentlich Painten wollen ist der schmale Streifen
3775                     //zwischen PrtArea und aeusserer Umrandung.
3776                     SwRect aTmp( Prt() ); aTmp += Frm().Pos();
3777                     aRegion -= aTmp;
3778                 }
3779                 if ( bContour )
3780                 {
3781                     pOut->Push();
3782                     // --> OD 2007-12-13 #i80822#
3783                     // apply clip region under the same conditions, which are
3784                     // used in <SwNoTxtFrm::Paint(..)> to set the clip region
3785                     // for painting the graphic/OLE. Thus, the clip region is
3786                     // also applied for the PDF export.
3787 //                    if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER )
3788                 	ViewShell *pSh = getRootFrm()->GetCurrShell();
3789                     if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() )
3790                     // <--
3791                     {
3792                         pOut->SetClipRegion( aPoly );
3793                     }
3794                     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
3795                         PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
3796                     pOut->Pop();
3797                 }
3798                 else
3799                     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
3800                         PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
3801             }
3802 
3803 			pOut->Pop();
3804 		}
3805 	}
3806 
3807     // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and
3808     // the subsidiary lines of its lowers on its own, due to overlapping with
3809     // other fly frames or other objects.
3810     if( pGlobalShell->GetWin()
3811         && !bIsChart ) //#i102950# don't paint additional borders for charts
3812     {
3813         bool bSubsLineRectsCreated;
3814         if ( pSubsLines )
3815         {
3816             // Lock already existing subsidiary lines
3817             pSubsLines->LockLines( sal_True );
3818             bSubsLineRectsCreated = false;
3819         }
3820         else
3821         {
3822             // create new subsidiardy lines
3823             pSubsLines = new SwSubsRects;
3824             bSubsLineRectsCreated = true;
3825         }
3826 
3827         bool bSpecSubsLineRectsCreated;
3828         if ( pSpecSubsLines )
3829         {
3830             // Lock already existing special subsidiary lines
3831             pSpecSubsLines->LockLines( sal_True );
3832             bSpecSubsLineRectsCreated = false;
3833         }
3834         else
3835         {
3836             // create new special subsidiardy lines
3837             pSpecSubsLines = new SwSubsRects;
3838             bSpecSubsLineRectsCreated = true;
3839         }
3840         // Add subsidiary lines of fly frame and its lowers
3841         RefreshLaySubsidiary( pPage, aRect );
3842         // paint subsidiary lines of fly frame and its lowers
3843         pSpecSubsLines->PaintSubsidiary( pOut, NULL );
3844         pSubsLines->PaintSubsidiary( pOut, pLines );
3845         if ( !bSubsLineRectsCreated )
3846             // unlock subsidiary lines
3847             pSubsLines->LockLines( sal_False );
3848         else
3849             // delete created subsidiary lines container
3850             DELETEZ( pSubsLines );
3851 
3852         if ( !bSpecSubsLineRectsCreated )
3853             // unlock special subsidiary lines
3854             pSpecSubsLines->LockLines( sal_False );
3855         else
3856         {
3857             // delete created special subsidiary lines container
3858             DELETEZ( pSpecSubsLines );
3859         }
3860     }
3861 
3862     SwLayoutFrm::Paint( aRect );
3863 
3864     Validate();
3865 
3866     // OD 19.12.2002 #106318# - first paint lines added by fly frame paint
3867     // and then unlock other lines.
3868     pLines->PaintLines( pOut );
3869     pLines->LockLines( sal_False );
3870 
3871     pOut->Pop();
3872 
3873 	if ( pProgress && pNoTxt )
3874 		pProgress->Reschedule();
3875 }
3876 /*************************************************************************
3877 |*
3878 |*	  SwTabFrm::Paint()
3879 |*
3880 |*	  Ersterstellung	MA 11. May. 93
3881 |*	  Letzte Aenderung	MA 23. Mar. 95
3882 |*
3883 |*************************************************************************/
3884 
3885 void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3886 {
3887     if ( pGlobalShell->GetViewOptions()->IsTable() )
3888     {
3889         // --> collapsing borders FME 2005-05-27 #i29550#
3890         if ( IsCollapsingBorders() )
3891         {
3892             SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3893             const SwBorderAttrs &rAttrs = *aAccess.Get();
3894 
3895             // paint shadow
3896             if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
3897             {
3898                 SwRect aRect;
3899                 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
3900                 PaintShadow( rRect, aRect, rAttrs );
3901             }
3902 
3903             // paint lines
3904             SwTabFrmPainter aHelper( *this );
3905             aHelper.PaintLines( *pGlobalShell->GetOut(), rRect );
3906         }
3907         // <-- collapsing
3908 
3909 		SwLayoutFrm::Paint( rRect );
3910     }
3911     // OD 10.01.2003 #i6467# - no light grey rectangle for page preview
3912     else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() )
3913 	{
3914         // OD 10.01.2003 #i6467# - intersect output rectangle with table frame
3915         SwRect aTabRect( Prt() );
3916         aTabRect.Pos() += Frm().Pos();
3917         SwRect aTabOutRect( rRect );
3918         aTabOutRect.Intersection( aTabRect );
3919         pGlobalShell->GetViewOptions()->
3920                 DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY );
3921 	}
3922 	((SwTabFrm*)this)->ResetComplete();
3923 }
3924 
3925 /*************************************************************************
3926 |*
3927 |*	SwFrm::PaintShadow()
3928 |*
3929 |*	Beschreibung		Malt einen Schatten wenns das FrmFormat fordert.
3930 |* 		Der Schatten wird immer an den auesseren Rand des OutRect gemalt.
3931 |* 		Das OutRect wird ggf. so verkleinert, dass auf diesem das
3932 |* 		malen der Umrandung stattfinden kann.
3933 |*	Ersterstellung		MA 21. Dec. 92
3934 |*	Letzte Aenderung	MA 29. May. 97
3935 |*
3936 |*************************************************************************/
3937 /// OD 23.08.2002 #99657#
3938 ///     draw full shadow rectangle for frames with transparent drawn backgrounds.
3939 void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
3940                          const SwBorderAttrs &rAttrs ) const
3941 {
3942 	const SvxShadowItem &rShadow = rAttrs.GetShadow();
3943 	const long nWidth  = ::lcl_AlignWidth ( rShadow.GetWidth() );
3944 	const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() );
3945 
3946 	SwRects aRegion( 2, 2 );
3947 	SwRect aOut( rOutRect );
3948 
3949 	const sal_Bool bCnt	   = IsCntntFrm();
3950     const sal_Bool bTop    = !bCnt || rAttrs.GetTopLine  ( *(this) ) ? sal_True : sal_False;
3951     const sal_Bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? sal_True : sal_False;
3952 
3953     SvxShadowLocation eLoc = rShadow.GetLocation();
3954 
3955     SWRECTFN( this )
3956     if( IsVertical() )
3957     {
3958         switch( eLoc )
3959         {
3960             case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;  break;
3961             case SVX_SHADOW_TOPLEFT:     eLoc = SVX_SHADOW_TOPRIGHT;    break;
3962             case SVX_SHADOW_TOPRIGHT:    eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
3963             case SVX_SHADOW_BOTTOMLEFT:  eLoc = SVX_SHADOW_TOPLEFT;     break;
3964             default: break;
3965         }
3966     }
3967 
3968     /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to
3969     ///     be drawn or only two shadow rectangles beside the frame.
3970     ///     draw full shadow rectangle, if frame background is drawn transparent.
3971     ///     Status Quo:
3972     ///         SwLayoutFrm can have transparent drawn backgrounds. Thus,
3973     ///         "asked" their frame format.
3974     sal_Bool bDrawFullShadowRectangle =
3975             ( IsLayoutFrm() &&
3976               (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent()
3977             );
3978     switch ( eLoc )
3979 	{
3980 		case SVX_SHADOW_BOTTOMRIGHT:
3981 			{
3982                 if ( bDrawFullShadowRectangle )
3983                 {
3984                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
3985                     aOut.Top( aOut.Top() + nHeight );
3986                     aOut.Left( aOut.Left() + nWidth );
3987                     aRegion.Insert( aOut, aRegion.Count() );
3988                 }
3989                 else
3990                 {
3991                     aOut.Top ( aOut.Bottom() - nHeight );
3992                     aOut.Left( aOut.Left()   + nWidth );
3993                     if ( bBottom )
3994                         aRegion.Insert( aOut, aRegion.Count() );
3995                     aOut.Left( aOut.Right()   - nWidth );
3996                     aOut.Top ( rOutRect.Top() + nHeight );
3997                     if ( bBottom )
3998                         aOut.Bottom( aOut.Bottom() - nHeight );
3999                     if ( bCnt && (!bTop || !bBottom) )
4000                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
4001                     aRegion.Insert( aOut, aRegion.Count() );
4002                 }
4003 
4004 				rOutRect.Right ( rOutRect.Right() - nWidth );
4005 				rOutRect.Bottom( rOutRect.Bottom()- nHeight );
4006 			}
4007 			break;
4008 		case SVX_SHADOW_TOPLEFT:
4009 			{
4010                 if ( bDrawFullShadowRectangle )
4011                 {
4012                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
4013                     aOut.Bottom( aOut.Bottom() - nHeight );
4014                     aOut.Right( aOut.Right() - nWidth );
4015                     aRegion.Insert( aOut, aRegion.Count() );
4016                 }
4017                 else
4018                 {
4019                     aOut.Bottom( aOut.Top()   + nHeight );
4020                     aOut.Right ( aOut.Right() - nWidth );
4021                     if ( bTop )
4022                         aRegion.Insert( aOut, aRegion.Count() );
4023                     aOut.Right ( aOut.Left() + nWidth );
4024                     aOut.Bottom( rOutRect.Bottom() - nHeight );
4025                     if ( bTop )
4026                         aOut.Top( aOut.Top() + nHeight );
4027                     if ( bCnt && (!bBottom || !bTop) )
4028                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
4029                     aRegion.Insert( aOut, aRegion.Count() );
4030                 }
4031 
4032 				rOutRect.Left( rOutRect.Left() + nWidth );
4033 				rOutRect.Top(  rOutRect.Top() + nHeight );
4034 			}
4035 			break;
4036 		case SVX_SHADOW_TOPRIGHT:
4037 			{
4038                 if ( bDrawFullShadowRectangle )
4039                 {
4040                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
4041                     aOut.Bottom( aOut.Bottom() - nHeight);
4042                     aOut.Left( aOut.Left() + nWidth );
4043                     aRegion.Insert( aOut, aRegion.Count() );
4044                 }
4045                 else
4046                 {
4047                     aOut.Bottom( aOut.Top() + nHeight );
4048                     aOut.Left (  aOut.Left()+ nWidth );
4049                     if ( bTop )
4050                         aRegion.Insert( aOut, aRegion.Count() );
4051                     aOut.Left  ( aOut.Right() - nWidth );
4052                     aOut.Bottom( rOutRect.Bottom() - nHeight );
4053                     if ( bTop )
4054                         aOut.Top( aOut.Top() + nHeight );
4055                     if ( bCnt && (!bBottom || bTop) )
4056                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
4057                     aRegion.Insert( aOut, aRegion.Count() );
4058                 }
4059 
4060                 rOutRect.Right( rOutRect.Right() - nWidth );
4061 				rOutRect.Top( rOutRect.Top() + nHeight );
4062 			}
4063 			break;
4064 		case SVX_SHADOW_BOTTOMLEFT:
4065 			{
4066                 if ( bDrawFullShadowRectangle )
4067                 {
4068                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
4069                     aOut.Top( aOut.Top() + nHeight );
4070                     aOut.Right( aOut.Right() - nWidth );
4071                     aRegion.Insert( aOut, aRegion.Count() );
4072                 }
4073                 else
4074                 {
4075                     aOut.Top  ( aOut.Bottom()- nHeight );
4076                     aOut.Right( aOut.Right() - nWidth );
4077                     if ( bBottom )
4078                         aRegion.Insert( aOut, aRegion.Count() );
4079                     aOut.Right( aOut.Left() + nWidth );
4080                     aOut.Top( rOutRect.Top() + nHeight );
4081                     if ( bBottom )
4082                         aOut.Bottom( aOut.Bottom() - nHeight );
4083                     if ( bCnt && (!bTop || !bBottom) )
4084                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
4085                     aRegion.Insert( aOut, aRegion.Count() );
4086                 }
4087 
4088 				rOutRect.Left( rOutRect.Left() + nWidth );
4089 				rOutRect.Bottom( rOutRect.Bottom() - nHeight );
4090 			}
4091 			break;
4092         default:
4093             ASSERT( !this, "new ShadowLocation() ?" )
4094             break;
4095     }
4096 
4097 	OutputDevice *pOut = pGlobalShell->GetOut();
4098 
4099     sal_uLong nOldDrawMode = pOut->GetDrawMode();
4100     Color aShadowColor( rShadow.GetColor() );
4101     if( aRegion.Count() && pGlobalShell->GetWin() &&
4102         Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4103     {
4104         // Is heigh contrast mode, the output device has already set the
4105         // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function
4106         // to ignore the setting of a new color. Therefore we have to reset
4107         // the drawing mode
4108         pOut->SetDrawMode( 0 );
4109         aShadowColor = SwViewOption::GetFontColor();
4110     }
4111 
4112     if ( pOut->GetFillColor() != aShadowColor )
4113         pOut->SetFillColor( aShadowColor );
4114 
4115     pOut->SetDrawMode( nOldDrawMode );
4116 
4117 	for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
4118 	{
4119 		SwRect &rOut = aRegion[i];
4120 		aOut = rOut;
4121         // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle
4122         // no alignment necessary, because (1) <rRect> is already aligned
4123         // and because (2) paint of border and background will occur later.
4124         // Thus, (1) assures that no conflicts with neighbour object will occur
4125         // and (2) assures that border and background is not affected by the
4126         // shadow paint.
4127         /*
4128         ::SwAlignRect( aOut, pGlobalShell );
4129         */
4130 		if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
4131 		{
4132 			aOut._Intersection( rRect );
4133 			pOut->DrawRect( aOut.SVRect() );
4134 		}
4135 	}
4136 }
4137 
4138 /*************************************************************************
4139 |*
4140 |*	SwFrm::PaintBorderLine()
4141 |*
4142 |*	Ersterstellung		MA 22. Dec. 92
4143 |*	Letzte Aenderung	MA 22. Jan. 95
4144 |*
4145 |*************************************************************************/
4146 
4147 void SwFrm::PaintBorderLine( const SwRect& rRect,
4148 							 const SwRect& rOutRect,
4149 							 const SwPageFrm* /*pPage*/,
4150 							 const Color *pColor ) const
4151 {
4152 	if ( !rOutRect.IsOver( rRect ) )
4153 		return;
4154 
4155 	SwRect aOut( rOutRect );
4156 	aOut._Intersection( rRect );
4157 
4158 	const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0;
4159     sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB :
4160                    ( IsInSct() ? SUBCOL_SECT :
4161                    ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
4162     if( pColor && pGlobalShell->GetWin() &&
4163         Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4164     {
4165         pColor = &SwViewOption::GetFontColor();
4166     }
4167 
4168 	//if ( pPage->GetSortedObjs() )
4169 	//{
4170 	//	SwRegionRects aRegion( aOut, 4, 1 );
4171 	//	::lcl_SubtractFlys( this, pPage, aOut, aRegion );
4172 	//	for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
4173     //        pLines->AddLineRect( aRegion[i], pColor, pTab, nSubCol );
4174 	//}
4175 	//else
4176         pLines->AddLineRect( aOut, pColor, pTab, nSubCol );
4177 }
4178 
4179 /*************************************************************************
4180 |*
4181 |*	SwFrm::PaintBorderLines()
4182 |*
4183 |*	Beschreibung		Nur alle Linien einfach oder alle Linien doppelt!!!!
4184 |*	Ersterstellung		MA 22. Dec. 92
4185 |*	Letzte Aenderung	MA 22. Mar. 95
4186 |*
4187 |*************************************************************************/
4188 
4189 // OD 29.04.2003 #107169# - method called for left and right border rectangles.
4190 // For a printer output device perform adjustment for non-overlapping top and
4191 // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate
4192 // printer output device.
4193 // NOTE: For printer output device left/right border rectangle <_iorRect>
4194 //       has to be already non-overlapping the outer top/bottom border rectangle.
4195 void MA_FASTCALL lcl_SubTopBottom( SwRect&              _iorRect,
4196                                    const SvxBoxItem&    _rBox,
4197                                    const SwBorderAttrs& _rAttrs,
4198                                    const SwFrm&         _rFrm,
4199                                    const SwRectFn&      _rRectFn,
4200                                    const sal_Bool       _bPrtOutputDev )
4201 {
4202     const sal_Bool bCnt = _rFrm.IsCntntFrm();
4203     if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() &&
4204          ( !bCnt || _rAttrs.GetTopLine( _rFrm ) )
4205        )
4206 	{
4207         // subtract distance between outer and inner line.
4208         SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() );
4209         // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4210         // adjust x-/y-position, if inner top line is a hair line (width = 1)
4211         sal_Bool bIsInnerTopLineHairline = sal_False;
4212         if ( !_bPrtOutputDev )
4213         {
4214             // additionally subtract width of top outer line
4215             // --> left/right inner/outer line doesn't overlap top outer line.
4216             nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() );
4217         }
4218         else
4219         {
4220             // OD 29.04.2003 #107169# - additionally subtract width of top inner line
4221             // --> left/right inner/outer line doesn't overlap top inner line.
4222             nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() );
4223             bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1;
4224         }
4225         (_iorRect.*_rRectFn->fnSubTop)( -nDist );
4226         // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line
4227         // is a hair line
4228         if ( bIsInnerTopLineHairline )
4229         {
4230             if ( _rFrm.IsVertical() )
4231             {
4232                 // right of border rectangle has to be checked and adjusted
4233                 Point aCompPt( _iorRect.Right(), 0 );
4234                 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4235                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4236                                           aRefPt, aCompPt,
4237                                           sal_True, -1 );
4238                 _iorRect.Right( aCompPt.X() );
4239             }
4240             else
4241             {
4242                 // top of border rectangle has to be checked and adjusted
4243                 Point aCompPt( 0, _iorRect.Top() );
4244                 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4245                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4246                                           aRefPt, aCompPt,
4247                                           sal_False, +1 );
4248                 _iorRect.Top( aCompPt.Y() );
4249             }
4250         }
4251 	}
4252 
4253     if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() &&
4254          ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) )
4255        )
4256 	{
4257         // subtract distance between outer and inner line.
4258         SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() );
4259         // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4260         // adjust x-/y-position, if inner bottom line is a hair line (width = 1)
4261         sal_Bool bIsInnerBottomLineHairline = sal_False;
4262         if ( !_bPrtOutputDev )
4263         {
4264             // additionally subtract width of bottom outer line
4265             // --> left/right inner/outer line doesn't overlap bottom outer line.
4266             nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() );
4267         }
4268         else
4269         {
4270             // OD 29.04.2003 #107169# - additionally subtract width of bottom inner line
4271             // --> left/right inner/outer line doesn't overlap bottom inner line.
4272             nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() );
4273             bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1;
4274         }
4275         (_iorRect.*_rRectFn->fnAddBottom)( -nDist );
4276         // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner
4277         // bottom line is a hair line.
4278         if ( bIsInnerBottomLineHairline )
4279         {
4280             if ( _rFrm.IsVertical() )
4281             {
4282                 // left of border rectangle has to be checked and adjusted
4283                 Point aCompPt( _iorRect.Left(), 0 );
4284                 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4285                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4286                                           aRefPt, aCompPt,
4287                                           sal_True, +1 );
4288                 _iorRect.Left( aCompPt.X() );
4289             }
4290             else
4291             {
4292                 // bottom of border rectangle has to be checked and adjusted
4293                 Point aCompPt( 0, _iorRect.Bottom() );
4294                 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4295                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4296                                           aRefPt, aCompPt,
4297                                           sal_False, -1 );
4298                 _iorRect.Bottom( aCompPt.Y() );
4299             }
4300         }
4301 	}
4302 }
4303 
4304 // method called for top and bottom border rectangles.
4305 void MA_FASTCALL lcl_SubLeftRight( SwRect&           rRect,
4306                                    const SvxBoxItem& rBox,
4307                                    const SwRectFn&   rRectFn )
4308 {
4309 	if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() )
4310 	{
4311         const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() )
4312                            + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() );
4313         (rRect.*rRectFn->fnSubLeft)( -nDist );
4314 	}
4315 
4316 	if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() )
4317 	{
4318         const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() )
4319                            + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() );
4320         (rRect.*rRectFn->fnAddRight)( -nDist );
4321 	}
4322 }
4323 
4324 // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine>
4325 // into new method <lcl_PaintLeftRightLine(..)>
4326 void lcl_PaintLeftRightLine( const sal_Bool         _bLeft,
4327                              const SwFrm&           _rFrm,
4328                              const SwPageFrm&       _rPage,
4329                              const SwRect&          _rOutRect,
4330                              const SwRect&          _rRect,
4331                              const SwBorderAttrs&   _rAttrs,
4332                              const SwRectFn&        _rRectFn )
4333 {
4334     const SvxBoxItem& rBox = _rAttrs.GetBox();
4335     const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft();
4336     const SvxBorderLine* pLeftRightBorder = 0;
4337     if ( _bLeft )
4338     {
4339         pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft();
4340     }
4341     else
4342     {
4343         pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight();
4344     }
4345     // OD 06.05.2003 #107169# - init boolean indicating printer output device.
4346     const sal_Bool bPrtOutputDev =
4347             ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() );
4348 
4349     if ( !pLeftRightBorder )
4350     {
4351         return;
4352     }
4353 
4354     SwRect aRect( _rOutRect );
4355     if ( _bLeft )
4356     {
4357         (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4358                                        (aRect.*_rRectFn->fnGetWidth)() );
4359     }
4360     else
4361     {
4362         (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4363                                       (aRect.*_rRectFn->fnGetWidth)() );
4364     }
4365 
4366     const sal_Bool bCnt = _rFrm.IsCntntFrm();
4367 
4368     if ( bCnt )
4369     {
4370         ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn );
4371     }
4372 
4373     // OD 06.05.2003 #107169# - adjustments for printer output device
4374     if ( bPrtOutputDev )
4375     {
4376         // subtract width of outer top line.
4377         if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) )
4378         {
4379             long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() );
4380             (aRect.*_rRectFn->fnSubTop)( -nDist );
4381             // OD 19.05.2003 #109667# - If outer top line is hair line, calculated
4382             // top has to be adjusted.
4383             if ( nDist == 1 )
4384             {
4385                 if ( _rFrm.IsVertical() )
4386                 {
4387                     // right of border rectangle has to be checked and adjusted
4388                     Point aCompPt( aRect.Right(), 0 );
4389                     Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4390                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4391                                               aRefPt, aCompPt,
4392                                               sal_True, -1 );
4393                     aRect.Right( aCompPt.X() );
4394                 }
4395                 else
4396                 {
4397                     // top of border rectangle has to be checked and adjusted
4398                     Point aCompPt( 0, aRect.Top() );
4399                     Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4400                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4401                                               aRefPt, aCompPt,
4402                                               sal_False, +1 );
4403                     aRect.Top( aCompPt.Y() );
4404                 }
4405             }
4406         }
4407         // subtract width of outer bottom line.
4408         if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) )
4409         {
4410             long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth());
4411             (aRect.*_rRectFn->fnAddBottom)( -nDist );
4412             // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated
4413             // top has to be adjusted.
4414             if ( nDist == 1 )
4415             {
4416                 if ( _rFrm.IsVertical() )
4417                 {
4418                     // left of border rectangle has to be checked and adjusted
4419                     Point aCompPt( aRect.Left(), 0 );
4420                     Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4421                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4422                                               aRefPt, aCompPt,
4423                                               sal_True, +1 );
4424                     aRect.Left( aCompPt.X() );
4425                 }
4426                 else
4427                 {
4428                     // bottom of border rectangle has to be checked and adjusted
4429                     Point aCompPt( 0, aRect.Bottom() );
4430                     Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4431                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4432                                               aRefPt, aCompPt,
4433                                               sal_False, -1 );
4434                     aRect.Bottom( aCompPt.Y() );
4435                 }
4436             }
4437         }
4438     }
4439 
4440     if ( !pLeftRightBorder->GetInWidth() )
4441     {
4442         // OD 06.05.2003 #107169# - add 6th parameter
4443         ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4444     }
4445 
4446     // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4447     {
4448         SwRect aPaintRect( aRect );
4449         ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4450         // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4451         // to the prior left postion with width of one twip.
4452         if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4453         {
4454             if ( _bLeft )
4455             {
4456                 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4457                 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4458                 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4459             }
4460             else
4461             {
4462                 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4463                 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4464                 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4465             }
4466         }
4467         _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4468     }
4469 
4470     if ( pLeftRightBorder->GetInWidth() )
4471     {
4472         const long nDist = ::lcl_MinWidthDist( pLeftRightBorder->GetDistance() );
4473         long nWidth = ::lcl_AlignWidth( pLeftRightBorder->GetInWidth() );
4474         if ( _bLeft )
4475         {
4476             (aRect.*_rRectFn->fnAddRight)( nDist + nWidth );
4477             (aRect.*_rRectFn->fnSubLeft)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4478         }
4479         else
4480         {
4481             (aRect.*_rRectFn->fnSubLeft)( nDist + nWidth );
4482             (aRect.*_rRectFn->fnAddRight)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4483         }
4484         // OD 06.05.2003 #107169# - add 6th parameter
4485         ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4486         // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4487         {
4488             SwRect aPaintRect( aRect );
4489             ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4490             // if <SwAlignRect> reveals rectangle with no width, adjust
4491             // rectangle to the prior left postion with width of one twip.
4492             if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4493             {
4494                 if ( _bLeft )
4495                 {
4496                     (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4497                     (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4498                     (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4499                 }
4500                 else
4501                 {
4502                     (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4503                     (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4504                     (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4505                 }
4506             }
4507             _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4508         }
4509     }
4510 }
4511 
4512 // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine>
4513 // into <lcl_PaintTopLine>
4514 void lcl_PaintTopBottomLine( const sal_Bool         _bTop,
4515                              const SwFrm&           _rFrm,
4516                              const SwPageFrm&       _rPage,
4517                              const SwRect&          _rOutRect,
4518                              const SwRect&          _rRect,
4519                              const SwBorderAttrs&   _rAttrs,
4520                              const SwRectFn&        _rRectFn )
4521 {
4522     const SvxBoxItem& rBox = _rAttrs.GetBox();
4523     const SvxBorderLine* pTopBottomBorder = 0;
4524     if ( _bTop )
4525     {
4526         pTopBottomBorder = rBox.GetTop();
4527     }
4528     else
4529     {
4530         pTopBottomBorder = rBox.GetBottom();
4531     }
4532 
4533     if ( !pTopBottomBorder )
4534     {
4535 		return;
4536     }
4537 
4538     SwRect aRect( _rOutRect );
4539     if ( _bTop )
4540     {
4541         (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4542                                         (aRect.*_rRectFn->fnGetHeight)() );
4543     }
4544     else
4545     {
4546         (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4547                                      (aRect.*_rRectFn->fnGetHeight)() );
4548     }
4549 
4550     // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4551     {
4552         SwRect aPaintRect( aRect );
4553         ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4554         // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4555         // to the prior top postion with width of one twip.
4556         if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4557         {
4558             if ( _bTop )
4559             {
4560                 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4561                 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4562                 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4563             }
4564             else
4565             {
4566                 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4567                 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4568                 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4569             }
4570         }
4571         _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4572     }
4573 
4574     if ( pTopBottomBorder->GetInWidth() )
4575 	{
4576         const long nDist = ::lcl_MinHeightDist( pTopBottomBorder->GetDistance() );
4577         const long nHeight = ::lcl_AlignHeight( pTopBottomBorder->GetInWidth() );
4578         if ( _bTop )
4579         {
4580             (aRect.*_rRectFn->fnAddBottom)( nDist + nHeight );
4581             (aRect.*_rRectFn->fnSubTop)( nHeight - (aRect.*_rRectFn->fnGetHeight)() );
4582         }
4583         else
4584         {
4585             (aRect.*_rRectFn->fnSubTop)( nDist + nHeight );
4586             (aRect.*_rRectFn->fnAddBottom)( nHeight -(aRect.*_rRectFn->fnGetHeight)() );
4587         }
4588         ::lcl_SubLeftRight( aRect, rBox, _rRectFn );
4589         // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4590         {
4591             SwRect aPaintRect( aRect );
4592             ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4593             // if <SwAlignRect> reveals rectangle with no width, adjust
4594             // rectangle to the prior top postion with width of one twip.
4595             if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4596             {
4597                 if ( _bTop )
4598                 {
4599                     (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4600                     (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4601                     (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4602                 }
4603                 else
4604                 {
4605                     (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4606                     (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4607                     (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4608                 }
4609             }
4610             _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4611         }
4612 	}
4613 }
4614 
4615 
4616 /*************************************************************************
4617 |*
4618 |*  const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4619 |*
4620 |* No comment. #i15844#
4621 |*
4622 |*************************************************************************/
4623 
4624 const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4625 {
4626     ASSERT( rFrm.IsCellFrm(),
4627             "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" )
4628 
4629     const SwFrm* pTmpFrm = &rFrm;
4630     do
4631     {
4632         if ( pTmpFrm->GetNext() )
4633             return pTmpFrm->GetNext();
4634 
4635         pTmpFrm = pTmpFrm->GetUpper()->GetUpper();
4636     }
4637     while ( pTmpFrm->IsCellFrm() );
4638 
4639     return 0;
4640 }
4641 
4642 
4643 /*************************************************************************
4644 |*
4645 |*	SwFrm::PaintBorder()
4646 |*
4647 |*	Beschreibung		Malt Schatten und Umrandung
4648 |*	Ersterstellung		MA 23.01.92
4649 |*	Letzte Aenderung	MA 29. Jul. 96
4650 |*
4651 |*************************************************************************/
4652 
4653 /** local method to determine cell frame, from which the border attributes
4654     for paint of top/bottom border has to be used.
4655 
4656     OD 21.02.2003 #b4779636#, #107692#
4657 
4658     @author OD
4659 
4660 
4661     @param _pCellFrm
4662     input parameter - constant pointer to cell frame for which the cell frame
4663     for the border attributes has to be determined.
4664 
4665     @param _rCellBorderAttrs
4666     input parameter - constant reference to the border attributes of cell frame
4667     <_pCellFrm>.
4668 
4669     @param _bTop
4670     input parameter - boolean, that controls, if cell frame for top border or
4671     for bottom border has to be determined.
4672 
4673     @return constant pointer to cell frame, for which the border attributes has
4674     to be used
4675 */
4676 const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm*         _pCellFrm,
4677                                            const SwBorderAttrs& _rCellBorderAttrs,
4678                                            const bool           _bTop )
4679 {
4680     ASSERT( _pCellFrm, "No cell frame available, dying soon" )
4681 
4682     // determine, if cell frame is at bottom/top border of a table frame and
4683     // the table frame has/is a follow.
4684     const SwFrm* pTmpFrm = _pCellFrm;
4685     bool bCellAtBorder = true;
4686     bool bCellAtLeftBorder = !_pCellFrm->GetPrev();
4687     bool bCellAtRightBorder = !_pCellFrm->GetNext();
4688     while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() )
4689     {
4690         pTmpFrm = pTmpFrm->GetUpper();
4691         if ( pTmpFrm->IsRowFrm() &&
4692              (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext())
4693            )
4694         {
4695             bCellAtBorder = false;
4696         }
4697         if ( pTmpFrm->IsCellFrm() )
4698         {
4699             if ( pTmpFrm->GetPrev() )
4700             {
4701                 bCellAtLeftBorder = false;
4702             }
4703             if ( pTmpFrm->GetNext() )
4704             {
4705                 bCellAtRightBorder = false;
4706             }
4707         }
4708     }
4709     ASSERT( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" );
4710 
4711     const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm);
4712     const SwTabFrm* pParentTabFrm =
4713             static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper());
4714 
4715     const bool bCellNeedsAttribute = bCellAtBorder &&
4716                                      ( _bTop ?
4717                                       // bCellInFirstRowWithMaster
4718                                        ( !pParentRowFrm->GetPrev() &&
4719                                          pParentTabFrm->IsFollow() &&
4720                                          0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) :
4721                                       // bCellInLastRowWithFollow
4722                                        ( !pParentRowFrm->GetNext() &&
4723                                          pParentTabFrm->GetFollow() )
4724                                      );
4725 
4726     const SwFrm* pRet = _pCellFrm;
4727     if ( bCellNeedsAttribute )
4728     {
4729         // determine, if cell frame has no borders inside the table.
4730         const SwFrm* pNextCell = 0;
4731         bool bNoBordersInside = false;
4732 
4733         if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) )
4734         {
4735             SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell );
4736             const SwBorderAttrs &rBorderAttrs = *aAccess.Get();
4737             const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox();
4738             bCellAtRightBorder = !lcl_HasNextCell( *pNextCell );
4739             bNoBordersInside =
4740                 ( !rBorderBox.GetTop()    || !pParentRowFrm->GetPrev() ) &&
4741                   !rBorderBox.GetLeft() &&
4742                 ( !rBorderBox.GetRight()  || bCellAtRightBorder ) &&
4743                 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4744         }
4745         else
4746         {
4747             const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox();
4748             bNoBordersInside =
4749                 ( !rBorderBox.GetTop()    || !pParentRowFrm->GetPrev() ) &&
4750                 ( !rBorderBox.GetLeft()   || bCellAtLeftBorder ) &&
4751                 ( !rBorderBox.GetRight()  || bCellAtRightBorder ) &&
4752                 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4753         }
4754 
4755         if ( bNoBordersInside )
4756         {
4757             if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() )
4758             {
4759                 // #b4779636#-hack:
4760                 // Cell frame has no top border and no border inside the table, but
4761                 // it is at the top border of a table frame, which is a follow.
4762                 // Thus, use border attributes of cell frame in first row of complete table.
4763                 // First, determine first table frame of complete table.
4764                 SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true );
4765                 // determine first row of complete table.
4766                 const SwFrm* pFirstRow = pMasterTabFrm->GetLower();
4767                 // return first cell in first row
4768                 SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower());
4769                 while ( !pLowerCell->IsCellFrm() ||
4770                         ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4771                       )
4772                 {
4773                     pLowerCell = pLowerCell->GetLower();
4774                 }
4775                 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4776                 pRet = pLowerCell;
4777             }
4778             else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() )
4779             {
4780                 // #b4779636#-hack:
4781                 // Cell frame has no bottom border and no border inside the table,
4782                 // but it is at the bottom border of a table frame, which has a follow.
4783                 // Thus, use border attributes of cell frame in last row of complete table.
4784                 // First, determine last table frame of complete table.
4785                 SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow());
4786                 while ( pLastTabFrm->GetFollow() )
4787                 {
4788                     pLastTabFrm = pLastTabFrm->GetFollow();
4789                 }
4790                 // determine last row of complete table.
4791                 SwFrm* pLastRow = pLastTabFrm->GetLastLower();
4792                 // return first bottom border cell in last row
4793                 SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower());
4794                 while ( !pLowerCell->IsCellFrm() ||
4795                         ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4796                       )
4797                 {
4798                     if ( pLowerCell->IsRowFrm() )
4799                     {
4800                         while ( pLowerCell->GetNext() )
4801                         {
4802                             pLowerCell = pLowerCell->GetNext();
4803                         }
4804                     }
4805                     pLowerCell = pLowerCell->GetLower();
4806                 }
4807                 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4808                 pRet = pLowerCell;
4809             }
4810         }
4811     }
4812 
4813     return pRet;
4814 }
4815 
4816 void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4817 						 const SwBorderAttrs &rAttrs ) const
4818 {
4819     //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun
4820     if ( (GetType() & 0x90C5) || (Prt().SSize() == Frm().SSize()) )
4821         return;
4822 
4823 	if ( (GetType() & 0x2000) && 	//Cell
4824 		 !pGlobalShell->GetViewOptions()->IsTable() )
4825 		return;
4826 
4827     // --> collapsing borders FME 2005-05-27 #i29550#
4828     if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
4829     {
4830         const SwTabFrm* pTabFrm = FindTabFrm();
4831         if ( pTabFrm->IsCollapsingBorders() )
4832             return;
4833 
4834         if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) )
4835             return;
4836     }
4837     // <--
4838 
4839     const bool bLine = rAttrs.IsLine() ? true : false;
4840     const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE;
4841 
4842     // OD 24.02.2003 #b4779636#, #107692# - flag to control,
4843     // if #b4779636#-hack has to be used.
4844     const bool bb4779636HackActive = true;
4845     // OD 21.02.2003 #b4779636#, #107692#
4846     const SwFrm* pCellFrmForBottomBorderAttrs = 0;
4847     const SwFrm* pCellFrmForTopBorderAttrs = 0;
4848     bool         bFoundCellForTopOrBorderAttrs = false;
4849     if ( bb4779636HackActive && IsCellFrm() )
4850     {
4851         pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false );
4852         if ( pCellFrmForBottomBorderAttrs != this )
4853             bFoundCellForTopOrBorderAttrs = true;
4854         pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true );
4855         if ( pCellFrmForTopBorderAttrs != this )
4856             bFoundCellForTopOrBorderAttrs = true;
4857     }
4858 
4859     // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4860     // for #b4779636#-hack
4861     if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs )
4862 	{
4863 		//Wenn das Rechteck vollstandig innerhalb der PrtArea liegt,
4864 		//so braucht kein Rand gepainted werden.
4865 		//Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden,
4866 		//anderfalls wuerden u.U. Teile nicht verarbeitet.
4867 		SwRect aRect( Prt() );
4868 		aRect += Frm().Pos();
4869 		::SwAlignRect( aRect, pGlobalShell );
4870         // OD 27.09.2002 #103636# - new local boolean variable in order to
4871         // suspend border paint under special cases - see below.
4872         // NOTE: This is a fix for the implementation of feature #99657#.
4873         bool bDrawOnlyShadowForTransparentFrame = false;
4874         if ( aRect.IsInside( rRect ) )
4875         {
4876             // OD 27.09.2002 #103636# - paint shadow, if background is transparent.
4877             // Because of introduced transparent background for fly frame #99657#,
4878             // the shadow have to be drawn if the background is transparent,
4879             // in spite the fact that the paint rectangle <rRect> lies fully
4880             // in the printing area.
4881             // NOTE to chosen solution:
4882             //     On transparent background, continue processing, but suspend
4883             //     drawing of border by setting <bDrawOnlyShadowForTransparentFrame>
4884             //     to true.
4885             if ( IsLayoutFrm() &&
4886                  static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() )
4887             {
4888                  bDrawOnlyShadowForTransparentFrame = true;
4889             }
4890             else
4891             {
4892                 return;
4893             }
4894         }
4895 
4896 		if ( !pPage )
4897 			pPage = FindPageFrm();
4898 
4899 		::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
4900 		rAttrs.SetGetCacheLine( sal_True );
4901 		if ( bShadow )
4902             PaintShadow( rRect, aRect, rAttrs );
4903         // OD 27.09.2002 #103636# - suspend drawing of border
4904         // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
4905         // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4906         // for #b4779636#-hack.
4907         if ( ( bLine || bFoundCellForTopOrBorderAttrs ) &&
4908              !bDrawOnlyShadowForTransparentFrame )
4909 		{
4910             const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this;
4911             SWRECTFN( pDirRefFrm )
4912             // OD 19.05.2003 #109667# - use new method <lcl_PaintLeftRightLine(..)>
4913             //::lcl_PaintLeftLine  ( this, pPage, aRect, rRect, rAttrs, fnRect );
4914             //::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs, fnRect );
4915             ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4916             ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4917             if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) )
4918             {
4919                 // OD 21.02.2003 #b4779636#, #107692# -
4920                 // #b4779636#-hack: If another cell frame for top border
4921                 // paint is found, paint its top border.
4922                 if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this )
4923                 {
4924                     SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4925                                                 pCellFrmForTopBorderAttrs );
4926                     const SwBorderAttrs &rTopAttrs = *aAccess.Get();
4927                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4928                     //::lcl_PaintTopLine( this, pPage, aRect, rRect, rTopAttrs, fnRect );
4929                     ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect );
4930                 }
4931                 else
4932                 {
4933                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4934                     //::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs, fnRect );
4935                     ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4936                 }
4937             }
4938             if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) )
4939             {
4940                 // OD 21.02.2003 #b4779636#, #107692# -
4941                 // #b4779636#-hack: If another cell frame for bottom border
4942                 // paint is found, paint its bottom border.
4943                 if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this )
4944                 {
4945                     SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4946                                                 pCellFrmForBottomBorderAttrs );
4947                     const SwBorderAttrs &rBottomAttrs = *aAccess.Get();
4948                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4949                     //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rBottomAttrs, fnRect);
4950                     ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect);
4951                 }
4952                 else
4953                 {
4954                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4955                     //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rAttrs, fnRect);
4956                     ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect);
4957                 }
4958             }
4959 		}
4960 		rAttrs.SetGetCacheLine( sal_False );
4961 	}
4962 }
4963 /*************************************************************************
4964 |*
4965 |*	SwFtnContFrm::PaintBorder()
4966 |*
4967 |*	Beschreibung		Spezialimplementierung wg. der Fussnotenlinie.
4968 |* 		Derzeit braucht nur der obere Rand beruecksichtigt werden.
4969 |* 		Auf andere Linien und Schatten wird verzichtet.
4970 |*	Ersterstellung		MA 27. Feb. 93
4971 |*	Letzte Aenderung	MA 08. Sep. 93
4972 |*
4973 |*************************************************************************/
4974 
4975 void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4976 								const SwBorderAttrs & ) const
4977 {
4978 	//Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es
4979 	//keinen Rand zu painten.
4980 	SwRect aRect( Prt() );
4981 	aRect.Pos() += Frm().Pos();
4982 	if ( !aRect.IsInside( rRect ) )
4983 		PaintLine( rRect, pPage );
4984 }
4985 /*************************************************************************
4986 |*
4987 |*	SwFtnContFrm::PaintLine()
4988 |*
4989 |*	Beschreibung		Fussnotenline malen.
4990 |*	Ersterstellung		MA 02. Mar. 93
4991 |*	Letzte Aenderung	MA 28. Mar. 94
4992 |*
4993 |*************************************************************************/
4994 
4995 void SwFtnContFrm::PaintLine( const SwRect& rRect,
4996 							  const SwPageFrm *pPage ) const
4997 {
4998 	//Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc.
4999 	//Die Position ist ebenfalls am PageDesc angegeben.
5000 	//Der Pen steht direkt im PageDesc.
5001 
5002 	if ( !pPage )
5003 		pPage = FindPageFrm();
5004 	const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
5005 
5006     SWRECTFN( this )
5007     SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)();
5008     Fraction aFract( nPrtWidth, 1 );
5009 	const SwTwips nWidth = (long)(aFract *= rInf.GetWidth());
5010 
5011     SwTwips nX = (this->*fnRect->fnGetPrtLeft)();
5012 	switch ( rInf.GetAdj() )
5013 	{
5014 		case FTNADJ_CENTER:
5015             nX += nPrtWidth/2 - nWidth/2; break;
5016 		case FTNADJ_RIGHT:
5017             nX += nPrtWidth - nWidth; break;
5018 		case FTNADJ_LEFT:
5019 			/* do nothing */; break;
5020 		default:
5021 			ASSERT( !this, "Neues Adjustment fuer Fussnotenlinie?" );
5022 	}
5023     SwTwips nLineWidth = rInf.GetLineWidth();
5024     const SwRect aLineRect = bVert ?
5025         SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth,
5026                       nX), Size( nLineWidth, nWidth ) )
5027             : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ),
5028                             Size( nWidth, rInf.GetLineWidth()));
5029 	if ( aLineRect.HasArea() )
5030 		PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() );
5031 }
5032 
5033 /*************************************************************************
5034 |*
5035 |*	SwLayoutFrm::PaintColLines()
5036 |*
5037 |*	Beschreibung		Painted die Trennlinien fuer die innenliegenden
5038 |* 						Spalten.
5039 |*	Ersterstellung		MA 21. Jun. 93
5040 |*	Letzte Aenderung	MA 28. Mar. 94
5041 |*
5042 |*************************************************************************/
5043 
5044 void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol,
5045 								 const SwPageFrm *pPage ) const
5046 {
5047 	const SwFrm *pCol = Lower();
5048 	if ( !pCol || !pCol->IsColumnFrm() )
5049 		return;
5050 	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
5051     SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
5052 
5053     SwRect aLineRect = Prt();
5054     aLineRect += Frm().Pos();
5055 
5056     SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight())
5057                    / 100 - (aLineRect.*fnRect->fnGetHeight)();
5058     SwTwips nBottom = 0;
5059 
5060 	switch ( rFmtCol.GetLineAdj() )
5061 	{
5062 		case COLADJ_CENTER:
5063             nBottom = nTop / 2; nTop -= nBottom; break;
5064 		case COLADJ_TOP:
5065             nBottom = nTop; nTop = 0; break;
5066 		case COLADJ_BOTTOM:
5067             break;
5068 		default:
5069 			ASSERT( !this, "Neues Adjustment fuer Spaltenlinie?" );
5070 	}
5071 
5072     if( nTop )
5073         (aLineRect.*fnRect->fnSubTop)( nTop );
5074     if( nBottom )
5075         (aLineRect.*fnRect->fnAddBottom)( nBottom );
5076 
5077     SwTwips nPenHalf = rFmtCol.GetLineWidth();
5078     (aLineRect.*fnRect->fnSetWidth)( nPenHalf );
5079     nPenHalf /= 2;
5080 
5081     //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein.
5082 	SwRect aRect( rRect );
5083     (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW );
5084     (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW );
5085     SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight;
5086 	while ( pCol->GetNext() )
5087 	{
5088         (aLineRect.*fnRect->fnSetPosX)
5089             ( (pCol->Frm().*fnGetX)() - nPenHalf );
5090 		if ( aRect.IsOver( aLineRect ) )
5091             PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor());
5092 		pCol = pCol->GetNext();
5093 	}
5094 }
5095 
5096 void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const
5097 {
5098     if( !bHasGrid || pRetoucheFly || pRetoucheFly2 )
5099         return;
5100     GETGRID( this )
5101     if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ?
5102         pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) )
5103     {
5104         const SwLayoutFrm* pBody = FindBodyCont();
5105         if( pBody )
5106         {
5107             SwRect aGrid( pBody->Prt() );
5108             aGrid += pBody->Frm().Pos();
5109 
5110             SwRect aInter( aGrid );
5111             aInter.Intersection( rRect );
5112             if( aInter.HasArea() )
5113             {
5114                 sal_Bool bGrid = pGrid->GetRubyTextBelow();
5115                 sal_Bool bCell = GRID_LINES_CHARS == pGrid->GetGridType();
5116                 long nGrid = pGrid->GetBaseHeight();
5117 				const SwDoc* pDoc = GetFmt()->GetDoc();
5118                 long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor
5119                 long nRuby = pGrid->GetRubyHeight();
5120                 long nSum = nGrid + nRuby;
5121                 const Color *pCol = &pGrid->GetColor();
5122 
5123                 SwTwips nRight = aInter.Left() + aInter.Width();
5124                 SwTwips nBottom = aInter.Top() + aInter.Height();
5125                 if( IsVertical() )
5126                 {
5127                     SwTwips nOrig = aGrid.Left() + aGrid.Width();
5128                     SwTwips nY = nOrig + nSum *
5129                                  ( ( nOrig - aInter.Left() ) / nSum );
5130                     SwRect aTmp( Point( nY, aInter.Top() ),
5131                                 Size( 1, aInter.Height() ) );
5132                     SwTwips nX = aGrid.Top() + nGrid *
5133                                 ( ( aInter.Top() - aGrid.Top() )/ nGrid );
5134                     if( nX < aInter.Top() )
5135                         nX += nGrid;
5136                     SwTwips nGridBottom = aGrid.Top() + aGrid.Height();
5137                     sal_Bool bLeft = aGrid.Top() >= aInter.Top();
5138                     sal_Bool bRight = nGridBottom <= nBottom;
5139                     sal_Bool bBorder = bLeft || bRight;
5140                     while( nY > nRight )
5141                     {
5142                         aTmp.Pos().X() = nY;
5143                         if( bGrid )
5144                         {
5145                             nY -= nGrid;
5146                             SwTwips nPosY = Max( aInter.Left(), nY );
5147                             SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY;
5148                             if( nHeight > 0 )
5149                             {
5150                                 if( bCell )
5151                                 {
5152                                     SwRect aVert( Point( nPosY, nX ),
5153                                                 Size( nHeight, 1 ) );
5154                                     while( aVert.Top() <= nBottom )
5155                                     {
5156                                         PaintBorderLine(rRect,aVert,this,pCol);
5157                                         aVert.Pos().Y() += nGrid;
5158                                     }
5159                                 }
5160                                 else if( bBorder )
5161                                 {
5162                                     SwRect aVert( Point( nPosY, aGrid.Top() ),
5163                                                   Size( nHeight, 1 ) );
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                         else
5175                         {
5176                             nY -= nRuby;
5177                             if( bBorder )
5178                             {
5179                                 SwTwips nPos = Max( aInter.Left(), nY );
5180                                 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5181                                 SwRect aVert( Point( nPos, aGrid.Top() ),
5182                                               Size( nW, 1 ) );
5183                                 if( nW > 0 )
5184                                 {
5185                                     if( bLeft )
5186                                         PaintBorderLine(rRect,aVert,this,pCol);
5187                                     if( bRight )
5188                                     {
5189                                         aVert.Pos().Y() = nGridBottom;
5190                                         PaintBorderLine(rRect,aVert,this,pCol);
5191                                     }
5192                                 }
5193                             }
5194                         }
5195                         bGrid = !bGrid;
5196                     }
5197                     while( nY >= aInter.Left() )
5198                     {
5199                         aTmp.Pos().X() = nY;
5200                         PaintBorderLine( rRect, aTmp, this, pCol);
5201                         if( bGrid )
5202                         {
5203                             nY -= nGrid;
5204                             SwTwips nHeight = aTmp.Pos().X()
5205                                               - Max(aInter.Left(), nY );
5206                             if( nHeight > 0 )
5207                             {
5208                                 if( bCell )
5209                                 {
5210                                     SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5211                                                   nX ), Size( nHeight, 1 ) );
5212                                     while( aVert.Top() <= nBottom )
5213                                     {
5214                                         PaintBorderLine(rRect,aVert,this,pCol);
5215                                         aVert.Pos().Y() += nGrid;
5216                                     }
5217                                 }
5218                                 else if( bBorder )
5219                                 {
5220                                     SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5221                                             aGrid.Top() ), Size( nHeight, 1 ) );
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                         else
5233                         {
5234                             nY -= nRuby;
5235                             if( bBorder )
5236                             {
5237                                 SwTwips nPos = Max( aInter.Left(), nY );
5238                                 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5239                                 SwRect aVert( Point( nPos, aGrid.Top() ),
5240                                               Size( nW, 1 ) );
5241                                 if( nW > 0 )
5242                                 {
5243                                     if( bLeft )
5244                                         PaintBorderLine(rRect,aVert,this,pCol);
5245                                     if( bRight )
5246                                     {
5247                                         aVert.Pos().Y() = nGridBottom;
5248                                         PaintBorderLine(rRect,aVert,this,pCol);
5249                                     }
5250                                 }
5251                             }
5252                         }
5253                         bGrid = !bGrid;
5254                     }
5255                 }
5256                 else
5257                 {
5258                     SwTwips nOrig = aGrid.Top();
5259                     SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum );
5260                     SwRect aTmp( Point( aInter.Left(), nY ),
5261                                 Size( aInter.Width(), 1 ) );
5262                     //for textgrid refactor
5263                     SwTwips nX = aGrid.Left() + nGridWidth *
5264                         ( ( aInter.Left() - aGrid.Left() )/ nGridWidth );
5265                     if( nX < aInter.Left() )
5266                         nX += nGridWidth;
5267                     SwTwips nGridRight = aGrid.Left() + aGrid.Width();
5268                     sal_Bool bLeft = aGrid.Left() >= aInter.Left();
5269                     sal_Bool bRight = nGridRight <= nRight;
5270                     sal_Bool bBorder = bLeft || bRight;
5271                     while( nY < aInter.Top() )
5272                     {
5273                         aTmp.Pos().Y() = nY;
5274                         if( bGrid )
5275                         {
5276                             nY += nGrid;
5277                             SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() );
5278                             SwTwips nHeight = Min(nBottom, nY ) - nPosY;
5279                             if( nHeight )
5280                             {
5281                                 if( bCell )
5282                                 {
5283                                     SwRect aVert( Point( nX, nPosY ),
5284                                                 Size( 1, nHeight ) );
5285                                     while( aVert.Left() <= nRight )
5286                                     {
5287                                         PaintBorderLine(rRect,aVert,this,pCol);
5288                                         aVert.Pos().X() += nGridWidth;	//for textgrid refactor
5289                                     }
5290                                 }
5291                                 else if ( bBorder )
5292                                 {
5293                                     SwRect aVert( Point( aGrid.Left(), nPosY ),
5294                                                 Size( 1, nHeight ) );
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                         else
5306                         {
5307                             nY += nRuby;
5308                             if( bBorder )
5309                             {
5310                                 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5311                                 SwTwips nH = Min( nBottom, nY ) - nPos;
5312                                 SwRect aVert( Point( aGrid.Left(), nPos ),
5313                                             Size( 1, nH ) );
5314                                 if( nH > 0 )
5315                                 {
5316                                     if( bLeft )
5317                                         PaintBorderLine(rRect,aVert,this,pCol);
5318                                     if( bRight )
5319                                     {
5320                                         aVert.Pos().X() = nGridRight;
5321                                         PaintBorderLine(rRect,aVert,this,pCol);
5322                                     }
5323                                 }
5324                             }
5325                         }
5326                         bGrid = !bGrid;
5327                     }
5328                     while( nY <= nBottom )
5329                     {
5330                         aTmp.Pos().Y() = nY;
5331                         PaintBorderLine( rRect, aTmp, this, pCol);
5332                         if( bGrid )
5333                         {
5334                             nY += nGrid;
5335                             SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y();
5336                             if( nHeight )
5337                             {
5338                                 if( bCell )
5339                                 {
5340                                     SwRect aVert( Point( nX, aTmp.Pos().Y() ),
5341                                                 Size( 1, nHeight ) );
5342                                     while( aVert.Left() <= nRight )
5343                                     {
5344                                         PaintBorderLine( rRect, aVert, this, pCol);
5345                                         aVert.Pos().X() += nGridWidth;	//for textgrid refactor
5346                                     }
5347                                 }
5348                                 else if( bBorder )
5349                                 {
5350                                     SwRect aVert( Point( aGrid.Left(),
5351                                         aTmp.Pos().Y() ), Size( 1, nHeight ) );
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                         else
5363                         {
5364                             nY += nRuby;
5365                             if( bBorder )
5366                             {
5367                                 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5368                                 SwTwips nH = Min( nBottom, nY ) - nPos;
5369                                 SwRect aVert( Point( aGrid.Left(), nPos ),
5370                                             Size( 1, nH ) );
5371                                 if( nH > 0 )
5372                                 {
5373                                     if( bLeft )
5374                                         PaintBorderLine(rRect,aVert,this,pCol);
5375                                     if( bRight )
5376                                     {
5377                                         aVert.Pos().X() = nGridRight;
5378                                         PaintBorderLine(rRect,aVert,this,pCol);
5379                                     }
5380                                 }
5381                             }
5382                         }
5383                         bGrid = !bGrid;
5384                     }
5385                 }
5386             }
5387         }
5388     }
5389 }
5390 
5391 /** paint margin area of a page
5392 
5393     OD 20.11.2002 for #104598#:
5394     implement paint of margin area; margin area will be painted for a
5395     view shell with a window and if the document is not in online layout.
5396 
5397     @author OD
5398 
5399     @param _rOutputRect
5400     input parameter - constant instance reference of the rectangle, for
5401     which an output has to be generated.
5402 
5403     @param _pViewShell
5404     input parameter - instance of the view shell, on which the output
5405     has to be generated.
5406 */
5407 void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect,
5408                                  ViewShell* _pViewShell ) const
5409 {
5410     if (  _pViewShell->GetWin() && !_pViewShell->GetViewOptions()->getBrowseMode() )
5411     {
5412         //UUUU Simplified paint with DrawingLayer FillStyle
5413         SwRect aPgRect = Frm();
5414         aPgRect._Intersection( _rOutputRect );
5415 
5416         if(!aPgRect.IsEmpty())
5417         {
5418             OutputDevice *pOut = _pViewShell->GetOut();
5419 
5420             if(pOut->GetFillColor() != aGlobalRetoucheColor)
5421             {
5422                 pOut->SetFillColor(aGlobalRetoucheColor);
5423             }
5424 
5425             pOut->DrawRect(aPgRect.SVRect());
5426         }
5427     }
5428 }
5429 
5430 // OD 12.02.2003 for #i9719# and #105645#
5431 // ----------------------------------------------------------------------
5432 
5433 const sal_Int8 SwPageFrm::mnBorderPxWidth = 1;
5434 const sal_Int8 SwPageFrm::mnShadowPxWidth = 2;
5435 
5436 /** determine rectangle for page border
5437 
5438     OD 12.02.2003 for #i9719# and #105645#
5439 
5440     @author OD
5441 */
5442 /*static*/ void SwPageFrm::GetBorderRect( const SwRect& _rPageRect,
5443                                           ViewShell*    _pViewShell,
5444                                           SwRect& _orBorderRect,
5445                                           bool bRightSidebar )
5446 {
5447     SwRect aAlignedPageRect( _rPageRect );
5448     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5449     Rectangle aBorderPxRect =
5450             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5451 
5452 	aBorderPxRect.Left() = aBorderPxRect.Left() - mnBorderPxWidth;
5453     aBorderPxRect.Top() = aBorderPxRect.Top() - mnBorderPxWidth;
5454     aBorderPxRect.Right() = aBorderPxRect.Right() + mnBorderPxWidth;
5455     aBorderPxRect.Bottom() = aBorderPxRect.Bottom() + mnBorderPxWidth;
5456 
5457 	AddSidebarBorders(aBorderPxRect,_pViewShell, bRightSidebar, true);
5458 
5459     _orBorderRect =
5460             SwRect( _pViewShell->GetOut()->PixelToLogic( aBorderPxRect ) );
5461 }
5462 
5463 /** determine rectangle for right page shadow
5464 
5465     OD 12.02.2003 for #i9719# and #105645#
5466 
5467     @author OD
5468 */
5469 /*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect,
5470                                                ViewShell*    _pViewShell,
5471                                                SwRect&       _orRightShadowRect,
5472                                                bool bRightSidebar )
5473 {
5474     SwRect aAlignedPageRect( _rPageRect );
5475     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5476     Rectangle aPagePxRect =
5477             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5478 
5479     Rectangle aRightShadowPxRect(
5480                     aPagePxRect.Right() + mnShadowPxWidth,
5481                     aPagePxRect.Top() + 1,
5482                     aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5483                     aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5484 
5485     if ( bRightSidebar )
5486 	    AddSidebarBorders(aRightShadowPxRect,_pViewShell, bRightSidebar, true);
5487 
5488     _orRightShadowRect =
5489             SwRect( _pViewShell->GetOut()->PixelToLogic( aRightShadowPxRect ) );
5490 }
5491 
5492 /** determine rectangle for bottom page shadow
5493 
5494     OD 12.02.2003 for #i9719# and #105645#
5495 
5496     @author OD
5497 */
5498 /*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect,
5499                                                 ViewShell*    _pViewShell,
5500                                                 SwRect&       _orBottomShadowRect,
5501                                                 bool bRightSidebar )
5502 {
5503     SwRect aAlignedPageRect( _rPageRect );
5504     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5505     Rectangle aPagePxRect =
5506             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5507 
5508     Rectangle aBottomShadowPxRect(
5509                     aPagePxRect.Left() + 1,
5510                     aPagePxRect.Bottom() + mnShadowPxWidth,
5511                     aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5512                     aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5513 
5514 	AddSidebarBorders(aBottomShadowPxRect,_pViewShell, bRightSidebar, true);
5515 
5516     _orBottomShadowRect =
5517             SwRect( _pViewShell->GetOut()->PixelToLogic( aBottomShadowPxRect ) );
5518 }
5519 
5520 /** paint page border and shadow
5521 
5522     OD 12.02.2003 for #i9719# and #105645#
5523     implement paint of page border and shadow
5524 
5525     @author OD
5526 */
5527 /*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect,
5528                                                  ViewShell*    _pViewShell,
5529                                                  bool bPaintRightShadow,
5530                                                  bool bRightSidebar )
5531 {
5532     // --> FME 2004-06-24 #i16816# tagged pdf support
5533     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() );
5534     // <--
5535 
5536     // get color for page border and shadow paint
5537     const Color& rColor = SwViewOption::GetFontColor();
5538 
5539     // save current fill and line color of output device
5540     Color aFill( _pViewShell->GetOut()->GetFillColor() );
5541     Color aLine( _pViewShell->GetOut()->GetLineColor() );
5542 
5543     // paint page border
5544     _pViewShell->GetOut()->SetFillColor(); // OD 20.02.2003 #107369# - no fill color
5545     _pViewShell->GetOut()->SetLineColor( rColor );
5546     SwRect aPaintRect;
5547     SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5548     _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5549 
5550     // paint right shadow
5551     if ( bPaintRightShadow )
5552     {
5553         _pViewShell->GetOut()->SetFillColor( rColor );
5554         SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5555         _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5556     }
5557 
5558     // paint bottom shadow
5559     SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5560     _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5561 
5562     _pViewShell->GetOut()->SetFillColor( aFill );
5563     _pViewShell->GetOut()->SetLineColor( aLine );
5564 }
5565 
5566 //mod #i6193# paint sidebar for notes
5567 //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit
5568 /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight)
5569 {
5570 	//TOOD: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons
5571     if (!_pViewShell )
5572         return;
5573 
5574     SwRect aPageRect( _rPageRect );
5575     SwAlignRect( aPageRect, _pViewShell );
5576 
5577     const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
5578     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())  // do not show anything in print preview
5579 	{
5580         sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight();
5581         const Rectangle &aVisRect = _pViewShell->VisArea().SVRect();
5582         //draw border and sidepane
5583         _pViewShell->GetOut()->SetLineColor();
5584         if (!bRight)
5585         {
5586             _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5587             _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height())))    ;
5588             if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5589                 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5590             else
5591                 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5592             _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height())))  ;
5593         }
5594         else
5595         {
5596             _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5597             SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()));
5598             _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect());
5599             if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5600                 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5601             else
5602                 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5603             SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()));
5604             _pViewShell->GetOut()->DrawRect(aSidebar.SVRect());
5605         }
5606         if (pMgr->ShowScrollbar(nPageNum))
5607         {
5608             // draw scrollbar area and arrows
5609             Point aPointBottom;
5610             Point aPointTop;
5611             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()) :
5612                                     Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height());
5613             aPointTop = !bRight ?    Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) :
5614                                 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height());
5615             Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ;
5616             Rectangle aRectBottom(aPointBottom,aSize);
5617             Rectangle aRectTop(aPointTop,aSize);
5618 
5619             if (aRectBottom.IsOver(aVisRect))
5620             {
5621 
5622                 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5623                 {
5624                     _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5625                     _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5626                 }
5627                 else
5628                 {
5629                     _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5630                     _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5631                 }
5632                 _pViewShell->GetOut()->DrawRect(aRectBottom);
5633                 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5634 
5635                 _pViewShell->GetOut()->SetLineColor();
5636                 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5637                 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5638                 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5639             }
5640             if (aRectTop.IsOver(aVisRect))
5641             {
5642                 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5643                 {
5644                     _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5645                     _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5646                 }
5647                 else
5648                 {
5649                     _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5650                     _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5651                 }
5652                 _pViewShell->GetOut()->DrawRect(aRectTop);
5653                 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5654 
5655                 _pViewShell->GetOut()->SetLineColor();
5656                 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5657                 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5658                 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5659             }
5660         }
5661     }
5662 }
5663 
5664 /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown)
5665 {
5666 	Polygon aTriangleUp(3);
5667 	Polygon aTriangleDown(3);
5668 
5669 	aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5670 	aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1);
5671 	aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5672 
5673 	aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5674 	aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1);
5675 	aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5676 
5677 	_pViewShell->GetOut()->SetFillColor(aColorUp);
5678 	_pViewShell->GetOut()->DrawPolygon(aTriangleUp);
5679 	_pViewShell->GetOut()->SetFillColor(aColorDown);
5680 	_pViewShell->GetOut()->DrawPolygon(aTriangleDown);
5681 }
5682 
5683 /** get bound rectangle of border and shadow for repaints
5684 
5685     OD 12.02.2003 for #i9719# and #105645#
5686 
5687     author OD
5688 */
5689 /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect,
5690                                                         ViewShell*    _pViewShell,
5691                                                         SwRect& _orBorderAndShadowBoundRect,
5692                                                         bool bRightSidebar )
5693 {
5694     SwRect aTmpRect;
5695     SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, _orBorderAndShadowBoundRect, bRightSidebar );
5696     SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5697     _orBorderAndShadowBoundRect.Union( aTmpRect );
5698     SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5699     _orBorderAndShadowBoundRect.Union( aTmpRect );
5700 
5701 	AddSidebarBorders(_orBorderAndShadowBoundRect, _pViewShell, bRightSidebar, false);
5702 }
5703 
5704 /*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5705 {
5706     const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5707     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5708     {
5709         if (!bRightSidebar)
5710             aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5711         else
5712             aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5713     }
5714 }
5715 
5716 /*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5717 {
5718     const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5719     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5720     {
5721         if (!bRightSidebar)
5722             aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5723         else
5724             aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx);
5725     }
5726 }
5727 
5728 /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell )
5729 {
5730     const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5731     const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
5732     return nRet;
5733 }
5734 
5735 /*************************************************************************
5736 |*
5737 |*	SwFrm::PaintBaBo()
5738 |*
5739 |*	Ersterstellung		MA 22. Oct. 93
5740 |*	Letzte Aenderung	MA 19. Jun. 96
5741 |*
5742 |*************************************************************************/
5743 
5744 void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage,
5745 					   const sal_Bool bLowerBorder ) const
5746 {
5747 	if ( !pPage )
5748 		pPage = FindPageFrm();
5749 
5750 	OutputDevice *pOut = pGlobalShell->GetOut();
5751 
5752     // --> FME 2004-06-24 #i16816# tagged pdf support
5753     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
5754     // <--
5755 
5756     // OD 2004-04-23 #116347#
5757     pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
5758     pOut->SetLineColor();
5759 
5760 	SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
5761 	const SwBorderAttrs &rAttrs = *aAccess.Get();
5762 
5763     // OD 20.11.2002 #104598# - take care of page margin area
5764     // Note: code move from <SwFrm::PaintBackground(..)> to new method
5765     // <SwPageFrm::Paintmargin(..)>.
5766     if ( IsPageFrm() )
5767     {
5768         static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell );
5769     }
5770 
5771     // OD 06.08.2002 #99657# - paint border before painting background
5772     // paint grid for page frame and paint border
5773     {
5774         SwRect aRect( rRect );
5775         if( IsPageFrm() )
5776             ((SwPageFrm*)this)->PaintGrid( pOut, aRect );
5777         PaintBorder( aRect, pPage, rAttrs );
5778     }
5779 
5780     // paint background
5781     {
5782         PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder );
5783     }
5784 
5785 	pOut->Pop();
5786 }
5787 
5788 /*************************************************************************
5789 |*
5790 |*	SwFrm::PaintBackground()
5791 |*
5792 |*	Ersterstellung		MA 04. Jan. 93
5793 |*	Letzte Aenderung	MA 06. Feb. 97
5794 |*
5795 |*************************************************************************/
5796 /// OD 05.09.2002 #102912#
5797 /// Do not paint background for fly frames without a background brush by
5798 /// calling <PaintBaBo> at the page or at the fly frame its anchored
5799 void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
5800 						 	 const SwBorderAttrs & rAttrs,
5801 							 const sal_Bool bLowerMode,
5802 							 const sal_Bool bLowerBorder ) const
5803 {
5804     // OD 20.01.2003 #i1837# - no paint of table background, if corresponding
5805     // option is *not* set.
5806     if( IsTabFrm() &&
5807         !pGlobalShell->GetViewOptions()->IsTable() )
5808     {
5809         return;
5810     }
5811 
5812 	// nothing to do for covered table cells:
5813 	if( IsCellFrm() && IsCoveredCell() )
5814 		return;
5815 
5816     ViewShell *pSh = pGlobalShell;
5817 
5818     // --> FME 2004-06-24 #i16816# tagged pdf support
5819     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
5820     // <--
5821 
5822     const SvxBrushItem* pItem;
5823     /// OD 05.09.2002 #102912#
5824     /// temporary background brush for a fly frame without a background brush
5825     SvxBrushItem* pTmpBackBrush = 0;
5826     const Color* pCol;
5827 	SwRect aOrigBackRect;
5828 	const sal_Bool bPageFrm = IsPageFrm();
5829 	sal_Bool bLowMode = sal_True;
5830 
5831     //UUUU
5832     drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes;
5833 
5834     sal_Bool bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, bLowerMode );
5835 
5836     //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird.
5837     bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm();
5838     if ( bNoFlyBackground )
5839     {
5840         // OD 05.09.2002 #102912# - Fly frame has no background.
5841         // Try to find background brush at parents, if previous call of
5842         // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode>
5843         if ( bLowerMode )
5844         {
5845             bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, false );
5846         }
5847         // If still no background found for the fly frame, initialize the
5848         // background brush <pItem> with global retouche color and set <bBack>
5849         // to sal_True, that fly frame will paint its background using this color.
5850         if ( !bBack )
5851         {
5852             // OD 10.01.2003 #i6467# - on print output, pdf output and
5853             // in embedded mode not editing color COL_WHITE is used instead of
5854             // the global retouche color.
5855             if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
5856                  pSh->GetViewOptions()->IsPDFExport() ||
5857                  ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED &&
5858                    !pSh->GetDoc()->GetDocShell()->IsInPlaceActive()
5859                  )
5860                )
5861             {
5862                 pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND );
5863 
5864                 //UUU
5865                 aFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(Color( COL_WHITE )));
5866             }
5867             else
5868             {
5869                 pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND);
5870 
5871                 //UUU
5872                 aFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(aGlobalRetoucheColor));
5873             }
5874 
5875             pItem = pTmpBackBrush;
5876             bBack = true;
5877         }
5878     }
5879 
5880 	SwRect aPaintRect( Frm() );
5881 	if( IsTxtFrm() || IsSctFrm() )
5882 		aPaintRect = UnionFrm( sal_True );
5883 
5884 	if ( aPaintRect.IsOver( rRect ) )
5885 	{
5886         if ( bBack || bPageFrm || !bLowerMode )
5887         {
5888             const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode();
5889             SwRect aRect;
5890             if ( (bPageFrm && bBrowse) ||
5891                  (IsTxtFrm() && Prt().SSize() == Frm().SSize()) )
5892             {
5893                 aRect = Frm();
5894                 ::SwAlignRect( aRect, pGlobalShell );
5895             }
5896             else
5897             {
5898                 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_False );
5899                 if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() )
5900                 {
5901                     if ( GetPrev()->GetAttrSet()->GetBackground() ==
5902                          GetAttrSet()->GetBackground() )
5903                     {
5904                         aRect.Top( Frm().Top() );
5905                     }
5906                 }
5907             }
5908             aRect.Intersection( rRect );
5909 
5910             OutputDevice *pOut = pSh->GetOut();
5911 
5912             if ( aRect.HasArea() )
5913             {
5914                 SvxBrushItem* pNewItem = 0;
5915                 //SwRegionRects aRegion( aRect );
5916 
5917                 if( pCol )
5918                 {
5919                     pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND );
5920                     pItem = pNewItem;
5921 
5922                     //UUUU
5923                     aFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(*pCol));
5924                 }
5925 
5926                 //if ( pPage->GetSortedObjs() )
5927                 //{
5928                 //    ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
5929                 //}
5930 
5931                 {
5932                     /// OD 06.08.2002 #99657# - determine, if background transparency
5933                     ///     have to be considered for drawing.
5934                     ///     --> Status Quo: background transparency have to be
5935                     ///        considered for fly frames
5936                     const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm();
5937                     bool bDone(false);
5938 
5939                     // #i125189# We are also done when the new DrawingLayer FillAttributes are used
5940                     // or the FillStyle is set (different from XFILL_NONE)
5941                     if(pOut && aFillAttributes.get())
5942                     {
5943                         if(aFillAttributes->isUsed())
5944                         {
5945                             // check if really something is painted
5946                             bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRect, *pOut);
5947                         }
5948 
5949                         if(!bDone)
5950                         {
5951                             // if not, still a FillStyle could be set but the transparency is at 100%,
5952                             // thus need to check the model data itself for FillStyle (do not rely on
5953                             // SdrAllFillAttributesHelper since it already contains optimized information,
5954                             // e.g. transparency leads to no fill)
5955                             const XFillStyle eFillStyle(static_cast< const XFillStyleItem& >(GetAttrSet()->Get(XATTR_FILLSTYLE)).GetValue());
5956 
5957                             if(XFILL_NONE != eFillStyle)
5958                             {
5959                                 bDone = true;
5960                             }
5961                         }
5962                     }
5963 
5964                     if(!bDone)
5965                     {
5966                         //for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
5967                         //{
5968                         //    if ( 1 < aRegion.Count() )
5969                         //    {
5970                         //        ::SwAlignRect( aRegion[i], pGlobalShell );
5971                         //        if( !aRegion[i].HasArea() )
5972                         //            continue;
5973                         //    }
5974                             /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if
5975                             ///     background transparency have to be considered
5976                             ///     Set missing 5th parameter to the default value GRFNUM_NO
5977                             ///         - see declaration in /core/inc/frmtool.hxx.
5978                         ::DrawGraphic(
5979                                 pItem,
5980                                 pOut,
5981                                 aOrigBackRect,
5982                                 aRect, // aRegion[i],
5983                                 GRFNUM_NO,
5984                                 bConsiderBackgroundTransparency );
5985                         //}
5986                     }
5987                 }
5988                 if( pCol )
5989                     delete pNewItem;
5990             }
5991         }
5992         else
5993             bLowMode = bLowerMode ? sal_True : sal_False;
5994 	}
5995 
5996     /// OD 05.09.2002 #102912#
5997     /// delete temporary background brush.
5998     delete pTmpBackBrush;
5999 
6000     //Jetzt noch Lower und dessen Nachbarn.
6001 	//Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist
6002 	//so hoert der Spass auf.
6003 	const SwFrm *pFrm = GetLower();
6004     if ( pFrm )
6005 	{
6006 		SwRect aFrmRect;
6007 		SwRect aRect( PaintArea() );
6008 		aRect._Intersection( rRect );
6009 		SwRect aBorderRect( aRect );
6010         SwShortCut aShortCut( *pFrm, aBorderRect );
6011 		do
6012 		{   if ( pProgress )
6013 				pProgress->Reschedule();
6014 
6015 			aFrmRect = pFrm->PaintArea();
6016 			if ( aFrmRect.IsOver( aBorderRect ) )
6017 			{
6018 				SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
6019                 const SwBorderAttrs &rTmpAttrs = *aAccess.Get();
6020                 /// OD 06.08.2002 #99657# - paint border before painting background
6021                 if ( bLowerBorder )
6022                     pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs );
6023 				if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) ||
6024 					 aFrmRect.IsOver( aRect ) )
6025                     pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode,
6026 										   bLowerBorder );
6027 			}
6028 			pFrm = pFrm->GetNext();
6029 		} while ( pFrm && pFrm->GetUpper() == this &&
6030                   !aShortCut.Stop( aFrmRect ) );
6031 	}
6032 }
6033 
6034 /*************************************************************************
6035 |*
6036 |*	SwPageFrm::RefreshSubsidiary()
6037 |*
6038 |*	Beschreibung		Erneuert alle Hilfslinien der Seite.
6039 |*	Ersterstellung		MA 04. Nov. 92
6040 |*	Letzte Aenderung	MA 10. May. 95
6041 |*
6042 |*************************************************************************/
6043 
6044 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
6045 {
6046     if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS )
6047 	{
6048 		SwRect aRect( rRect );
6049         // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of
6050         // the output rectangle.
6051         //::SwAlignRect( aRect, pGlobalShell );
6052 		if ( aRect.HasArea() )
6053 		{
6054 			//Beim Paint ueber die Root wird das Array von dort gesteuert.
6055 			//Anderfalls kuemmern wir uns selbst darum.
6056 			sal_Bool bDelSubs = sal_False;
6057 			if ( !pSubsLines )
6058 			{
6059 				pSubsLines = new SwSubsRects;
6060                 // OD 20.12.2002 #106318# - create container for special subsidiary lines
6061                 pSpecSubsLines = new SwSubsRects;
6062                 bDelSubs = sal_True;
6063 			}
6064 
6065 			RefreshLaySubsidiary( this, aRect );
6066 
6067             if ( bDelSubs )
6068 			{
6069                 // OD 20.12.2002 #106318# - paint special subsidiary lines
6070                 // and delete its container
6071                 pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL );
6072                 DELETEZ( pSpecSubsLines );
6073 
6074                 pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines );
6075 				DELETEZ( pSubsLines );
6076 			}
6077 		}
6078 	}
6079 }
6080 
6081 /*************************************************************************
6082 |*
6083 |*	SwLayoutFrm::RefreshLaySubsidiary()
6084 |*
6085 |*	Ersterstellung		MA 04. Nov. 92
6086 |*	Letzte Aenderung	MA 22. Jan. 95
6087 |*
6088 |*************************************************************************/
6089 void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage,
6090                                         const SwRect &rRect ) const
6091 {
6092 	const sal_Bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm();
6093 	const sal_Bool bSubsOpt	  = IS_SUBS;
6094     const sal_Bool bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE);
6095     const sal_Bool bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt;
6096 	const sal_Bool bSubsSect  = IsSctFrm() &&
6097 								bNoLowerColumn &&
6098 								IS_SUBS_SECTION;
6099     const sal_Bool bSubsFly   = IS_SUBS_FLYS &&
6100                                 (GetType() & FRM_FLY) &&
6101                                 bNoLowerColumn &&
6102 								(!Lower() || !Lower()->IsNoTxtFrm() ||
6103 								 !((SwNoTxtFrm*)Lower())->HasAnimation());
6104 	sal_Bool bSubsBody = sal_False;
6105 	if ( GetType() & FRM_BODY )
6106 	{
6107 		if ( IsPageBodyFrm() )
6108 			bSubsBody = bSubsOpt && bNoLowerColumn;									//nur ohne Spalten
6109         else    //Spaltenbody
6110 		{
6111 			if ( GetUpper()->GetUpper()->IsSctFrm() )
6112 				bSubsBody = IS_SUBS_SECTION;
6113 			else
6114 				bSubsBody = bSubsOpt;
6115 		}
6116 	}
6117 
6118 	if ( bSubsOther || bSubsSect  || bSubsBody || bSubsTable || bSubsFly )
6119 		PaintSubsidiaryLines( pPage, rRect );
6120 
6121     const SwFrm *pLow = Lower();
6122     if( !pLow )
6123         return;
6124     SwShortCut aShortCut( *pLow, rRect );
6125     while( pLow && !aShortCut.Stop( pLow->Frm() ) )
6126     {
6127         if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() )
6128         {
6129             if ( pLow->IsLayoutFrm() )
6130                 ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect);
6131             else if ( pLow->GetDrawObjs() )
6132             {
6133                 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs());
6134                 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
6135                 {
6136                     const SwAnchoredObject* pAnchoredObj = rObjs[i];
6137                     if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
6138                                     pAnchoredObj->GetDrawObj()->GetLayer() ) &&
6139                          pAnchoredObj->ISA(SwFlyFrm) )
6140                     {
6141                         const SwFlyFrm *pFly =
6142                                     static_cast<const SwFlyFrm*>(pAnchoredObj);
6143                         if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) )
6144                         {
6145                             if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
6146                                  !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
6147                                 pFly->RefreshLaySubsidiary( pPage, rRect );
6148                         }
6149                     }
6150                 }
6151             }
6152         }
6153         pLow = pLow->GetNext();
6154     }
6155 }
6156 
6157 /*************************************************************************
6158 |*
6159 |*	SwLayoutFrm::PaintSubsidiaryLines()
6160 |*
6161 |*	Beschreibung		Hilfslinien um die PrtAreas malen
6162 |* 		Nur die LayoutFrm's die direkt Cntnt enthalten.
6163 |*	Ersterstellung		MA 21. May. 92
6164 |*	Letzte Aenderung	MA 22. Jan. 95
6165 |*
6166 |*************************************************************************/
6167 
6168 //Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden.
6169 
6170 typedef long Size::* SizePtr;
6171 typedef long Point::* PointPtr;
6172 
6173 PointPtr pX = &Point::nA;
6174 PointPtr pY = &Point::nB;
6175 SizePtr pWidth = &Size::nA;
6176 SizePtr pHeight = &Size::nB;
6177 
6178 // OD 18.11.2002 #99672# - new parameter <_pSubsLines>
6179 void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay,
6180                                   const SwPageFrm *pPage,
6181                                   const Point &rP1,
6182                                   const Point &rP2,
6183                                   const sal_uInt8 nSubColor,
6184                                   SwLineRects* _pSubsLines )
6185 {
6186 	//In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein.
6187 	ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
6188 			"Schraege Hilfslinien sind nicht erlaubt." );
6189     const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX;
6190     const PointPtr pOthPt = pDirPt == pX ? pY : pX;
6191     const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight;
6192     const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth;
6193 	Point aP1( rP1 ),
6194 		  aP2( rP2 );
6195 
6196 	while ( aP1.*pDirPt < aP2.*pDirPt )
6197 	{	//Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt
6198 		//hinter den Fly gesetzt.
6199 		//Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt
6200 		//ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen.
6201 		//Auf diese art und weise wird eine Portion nach der anderen
6202 		//ausgegeben.
6203 
6204 		//Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus,
6205 		//die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen.
6206 		//Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche
6207 		//ich keinem dieser Flys aus.
6208 		SwOrderIter aIter( pPage );
6209 		const SwFlyFrm *pMyFly = pLay->FindFlyFrm();
6210 		if ( pMyFly )
6211 		{
6212 			aIter.Current( pMyFly->GetVirtDrawObj() );
6213             while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) )
6214 			{
6215 				if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
6216 					aIter.Current( pMyFly->GetVirtDrawObj() );
6217 			}
6218 		}
6219 		else
6220 			aIter.Bottom();
6221 
6222 		while ( aIter() )
6223 		{
6224 			const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
6225 			const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
6226 
6227 			//Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich
6228 			//_in_ dem Fly sitze weiche ich nicht aus.
6229 			if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
6230             {
6231                 aIter.Next();
6232 				continue;
6233 			}
6234 
6235             // OD 19.12.2002 #106318# - do *not* consider fly frames with
6236             // a transparent background.
6237             // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which
6238             // belongs to a invisible layer
6239             if ( pFly->IsBackgroundTransparent() ||
6240                  !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) )
6241             {
6242                 aIter.Next();
6243                 continue;
6244             }
6245 
6246 			//Sitzt das Obj auf der Linie
6247 			const Rectangle &rBound = pObj->GetCurrentBoundRect();
6248 			const Point aDrPt( rBound.TopLeft() );
6249 			const Size  aDrSz( rBound.GetSize() );
6250 			if ( rP1.*pOthPt >= aDrPt.*pOthPt &&
6251 				 rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) )
6252 			{
6253 				if ( aP1.*pDirPt >= aDrPt.*pDirPt &&
6254 			  	  	 aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) )
6255 					aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz;
6256 
6257 				if ( aP2.*pDirPt >= aDrPt.*pDirPt &&
6258 					 aP1.*pDirPt < (aDrPt.*pDirPt - 1) )
6259 					aP2.*pDirPt = aDrPt.*pDirPt - 1;
6260 			}
6261 			aIter.Next();
6262 		}
6263 
6264 		if ( aP1.*pDirPt < aP2.*pDirPt )
6265 		{
6266 			SwRect aRect( aP1, aP2 );
6267             // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of
6268             // global variable <pSubsLines>.
6269             _pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6270 		}
6271 		aP1 = aP2;
6272 		aP1.*pDirPt += 1;
6273 		aP2 = rP2;
6274 	}
6275 }
6276 
6277 void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage,
6278 										const SwRect &rRect ) const
6279 {
6280     bool bNewTableModel = false;
6281 
6282     // --> collapsing borders FME 2005-05-27 #i29550#
6283     if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
6284     {
6285         const SwTabFrm* pTabFrm = FindTabFrm();
6286         if ( pTabFrm->IsCollapsingBorders() )
6287             return;
6288 
6289         bNewTableModel = pTabFrm->GetTable()->IsNewModel();
6290         // in the new table model, we have an early return for all cell-related
6291         // frames, except from non-covered table cells
6292         if ( bNewTableModel )
6293             if ( IsTabFrm() ||
6294                  IsRowFrm() ||
6295                  ( IsCellFrm() && IsCoveredCell() ) )
6296                 return;
6297     }
6298     // <-- collapsing
6299 
6300     const bool bFlys = pPage->GetSortedObjs() ? true : false;
6301 
6302     const bool bCell = IsCellFrm() ? true : false;
6303     // use frame area for cells
6304     // OD 13.02.2003 #i3662# - for section use also frame area
6305     const bool bUseFrmArea = bCell || IsSctFrm();
6306     SwRect aOriginal( bUseFrmArea ? Frm() : Prt() );
6307     if ( !bUseFrmArea )
6308         aOriginal.Pos() += Frm().Pos();
6309 
6310     // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area
6311     // in sections to top of section frame.
6312     const bool bColBodyInSection = IsBodyFrm() &&
6313                                    !IsPageBodyFrm() &&
6314                                    GetUpper()->GetUpper()->IsSctFrm();
6315     if ( bColBodyInSection )
6316     {
6317         if ( IsVertical() )
6318             aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() );
6319         else
6320             aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() );
6321     }
6322 
6323     ::SwAlignRect( aOriginal, pGlobalShell );
6324 
6325     if ( !aOriginal.IsOver( rRect ) )
6326 		return;
6327 
6328 	SwRect aOut( aOriginal );
6329 	aOut._Intersection( rRect );
6330     // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's
6331     // printing area with the paint area of the body frame. Otherwise enlargement
6332     // will get lost.
6333     if ( !bColBodyInSection )
6334     {
6335         aOut.Intersection( PaintArea() );
6336     }
6337 
6338 	const SwTwips nRight = aOut.Right();
6339 	const SwTwips nBottom= aOut.Bottom();
6340 
6341 	const Point aRT( nRight, aOut.Top() );
6342 	const Point aRB( nRight, nBottom );
6343 	const Point aLB( aOut.Left(), nBottom );
6344 
6345     sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB :
6346                      ( IsInSct() ? SUBCOL_SECT :
6347                      ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
6348 
6349     // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks.
6350     sal_Bool bBreak = sal_False;
6351     if ( IsBodyFrm() )
6352     {
6353         const SwCntntFrm *pCnt = ContainsCntnt();
6354         if ( pCnt )
6355         {
6356             // OD 05.11.2002 #102406# - adjust setting of <bBreak>.
6357             bBreak = pCnt->IsPageBreak( sal_True ) ||
6358                      ( IsColBodyFrm() && pCnt->IsColBreak( sal_True ) );
6359         }
6360     }
6361 
6362     // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section
6363     // sub-lines in <pSpecSubsLine> array.
6364     const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() ||
6365                                   IsFtnFrm() || IsSctFrm();
6366     SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines;
6367 
6368     // NOTE: for cell frames only left and right (horizontal layout) respectively
6369     //      top and bottom (vertical layout) lines painted.
6370     // NOTE2: this does not hold for the new table model!!! We paint the top border
6371     // of each non-covered table cell.
6372     const bool bVert = IsVertical() ? true : false;
6373     if ( bFlys )
6374 	{
6375         // OD 14.11.2002 #104822# - add control for drawing left and right lines
6376         if ( !bCell || bNewTableModel || !bVert )
6377         {
6378             if ( aOriginal.Left() == aOut.Left() )
6379                 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor,
6380                                    pUsedSubsLines );
6381             // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6382             if ( aOriginal.Right() == nRight )
6383                 ::lcl_RefreshLine( this, pPage, aRT, aRB,
6384                                    (bBreak && bVert) ? SUBCOL_BREAK : nSubColor,
6385                                    pUsedSubsLines );
6386         }
6387         // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6388         if ( !bCell || bNewTableModel || bVert )
6389 		{
6390 			if ( aOriginal.Top() == aOut.Top() )
6391                 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6392 				::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT,
6393                                    (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor,
6394                                    pUsedSubsLines );
6395 			if ( aOriginal.Bottom() == nBottom )
6396                 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor,
6397                                    pUsedSubsLines );
6398 		}
6399 	}
6400 	else
6401 	{
6402         // OD 14.11.2002 #104822# - add control for drawing left and right lines
6403         if ( !bCell || bNewTableModel || !bVert )
6404         {
6405             if ( aOriginal.Left() == aOut.Left() )
6406             {
6407                 const SwRect aRect( aOut.Pos(), aLB );
6408                 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6409             }
6410             // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6411             if ( aOriginal.Right() == nRight )
6412             {
6413                 const SwRect aRect( aRT, aRB );
6414                 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6415                         (bBreak && bVert) ? SUBCOL_BREAK : nSubColor );
6416             }
6417         }
6418         // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6419         if ( !bCell || bNewTableModel || bVert )
6420         {
6421 			if ( aOriginal.Top() == aOut.Top() )
6422 			{
6423                 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6424 				const SwRect aRect( aOut.Pos(), aRT );
6425                 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6426                         (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor );
6427 			}
6428 			if ( aOriginal.Bottom() == nBottom )
6429 			{
6430 				const SwRect aRect( aLB, aRB );
6431                 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6432 			}
6433         }
6434 	}
6435 }
6436 
6437 /*************************************************************************
6438 |*
6439 |*	SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData()
6440 |*
6441 |*	Beschreibung		Erneuert alle Extradaten (Zeilennummern usw) der Seite.
6442 |* 						Grundsaetzlich sind nur diejenigen Objekte beruecksichtig,
6443 |* 						die in die seitliche Ausdehnung des Rects ragen.
6444 |*	Ersterstellung		MA 20. Jan. 98
6445 |*	Letzte Aenderung	MA 18. Feb. 98
6446 |*
6447 |*************************************************************************/
6448 
6449 void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const
6450 {
6451 	const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6452 	sal_Bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys())
6453         || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE;
6454 
6455 	SwRect aRect( rRect );
6456 	::SwAlignRect( aRect, pGlobalShell );
6457 	if ( aRect.HasArea() )
6458 	{
6459 		SwLayoutFrm::RefreshExtraData( aRect );
6460 
6461 		if ( bLineInFly && GetSortedObjs() )
6462 			for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i )
6463 			{
6464                 const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
6465                 if ( pAnchoredObj->ISA(SwFlyFrm) )
6466 				{
6467                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6468 					if ( pFly->Frm().Top() <= aRect.Bottom() &&
6469 						 pFly->Frm().Bottom() >= aRect.Top() )
6470 						pFly->RefreshExtraData( aRect );
6471 				}
6472 			}
6473 	}
6474 }
6475 
6476 void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const
6477 {
6478 
6479 	const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6480 	sal_Bool bLineInBody = rInfo.IsPaintLineNumbers(),
6481 			 bLineInFly  = bLineInBody && rInfo.IsCountInFlys(),
6482              bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE;
6483 
6484 	const SwCntntFrm *pCnt = ContainsCntnt();
6485 	while ( pCnt && IsAnLower( pCnt ) )
6486 	{
6487 		if ( pCnt->IsTxtFrm() && ( bRedLine ||
6488 			 ( !pCnt->IsInTab() &&
6489 			   ((bLineInBody && pCnt->IsInDocBody()) ||
6490 			   (bLineInFly  && pCnt->IsInFly())) ) ) &&
6491 			 pCnt->Frm().Top() <= rRect.Bottom() &&
6492 			 pCnt->Frm().Bottom() >= rRect.Top() )
6493 		{
6494 			((SwTxtFrm*)pCnt)->PaintExtraData( rRect );
6495 		}
6496 		if ( bLineInFly && pCnt->GetDrawObjs() )
6497             for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i )
6498 			{
6499                 const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i];
6500                 if ( pAnchoredObj->ISA(SwFlyFrm) )
6501                 {
6502                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6503                     if ( pFly->IsFlyInCntFrm() &&
6504 						 pFly->Frm().Top() <= rRect.Bottom() &&
6505 						 pFly->Frm().Bottom() >= rRect.Top() )
6506 						pFly->RefreshExtraData( rRect );
6507 				}
6508 		}
6509 		pCnt = pCnt->GetNextCntntFrm();
6510 	}
6511 }
6512 
6513 /** SwPageFrm::GetDrawBackgrdColor - for #102450#
6514 
6515     determine the color, that is respectively will be drawn as background
6516     for the page frame.
6517     Using existing method SwFrm::GetBackgroundBrush to determine the color
6518     that is set at the page frame respectively is parent. If none is found
6519     return the global retouche color
6520 
6521     @author OD
6522 
6523     @return Color
6524 */
6525 const Color SwPageFrm::GetDrawBackgrdColor() const
6526 {
6527     const SvxBrushItem* pBrushItem;
6528     const Color* pDummyColor;
6529     SwRect aDummyRect;
6530 
6531     //UUUU
6532     drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes;
6533 
6534     if ( GetBackgroundBrush( aFillAttributes, pBrushItem, pDummyColor, aDummyRect, true) )
6535     {
6536         if(aFillAttributes.get() && aFillAttributes->isUsed()) //UUUU
6537         {
6538             // let SdrAllFillAttributesHelper do the average color calculation
6539             return Color(aFillAttributes->getAverageColor(aGlobalRetoucheColor.getBColor()));
6540         }
6541         else if(pBrushItem)
6542         {
6543             const Graphic* pGraphic = pBrushItem->GetGraphic();
6544 
6545             if(pGraphic)
6546             {
6547                 // #29105# when a graphic is set, it may be possible to calculate a single
6548                 // color which looks good in all places of the graphic. Since it is
6549                 // planned to have text edit on the overlay one day and the fallback
6550                 // to aGlobalRetoucheColor returns something useful, just use that
6551                 // for now.
6552             }
6553             else
6554             {
6555                 // not a graphic, use (hopefully) initialized color
6556                 return pBrushItem->GetColor();
6557             }
6558         }
6559     }
6560 
6561     return aGlobalRetoucheColor;
6562 }
6563 
6564 /*************************************************************************
6565 |*
6566 |*    SwPageFrm::GetEmptyPageFont()
6567 |*
6568 |*    create/return font used to paint the "empty page" string
6569 |*
6570 |*************************************************************************/
6571 
6572 const Font& SwPageFrm::GetEmptyPageFont()
6573 {
6574     static Font* pEmptyPgFont = 0;
6575     if ( 0 == pEmptyPgFont )
6576     {
6577         pEmptyPgFont = new Font;
6578         pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt
6579         pEmptyPgFont->SetWeight( WEIGHT_BOLD );
6580         pEmptyPgFont->SetStyleName( aEmptyStr );
6581         pEmptyPgFont->SetName( String::CreateFromAscii(
6582                 RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) );
6583         pEmptyPgFont->SetFamily( FAMILY_SWISS );
6584         pEmptyPgFont->SetTransparent( sal_True );
6585         pEmptyPgFont->SetColor( COL_GRAY );
6586     }
6587 
6588     return *pEmptyPgFont;
6589 }
6590 
6591 /*************************************************************************
6592 |*
6593 |*	  SwFrm::Retouche
6594 |*
6595 |*	  Beschreibung		Retouche fuer einen Bereich.
6596 |*		Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner
6597 |* 		Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird
6598 |* 		per PaintBackground gecleared.
6599 |*	  Ersterstellung	MA 13. Apr. 93
6600 |*	  Letzte Aenderung	MA 25. Jul. 96
6601 |*
6602 |*************************************************************************/
6603 
6604 void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const
6605 {
6606 	if ( bFlyMetafile )
6607 		return;
6608 
6609 	ASSERT( GetUpper(), "Retoucheversuch ohne Upper." );
6610 	ASSERT( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" );
6611 
6612 	SwRect aRetouche( GetUpper()->PaintArea() );
6613 	aRetouche.Top( Frm().Top() + Frm().Height() );
6614 	aRetouche.Intersection( pGlobalShell->VisArea() );
6615 
6616 	if ( aRetouche.HasArea() )
6617 	{
6618         //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region
6619 		//zum ausstanzen.
6620 		SwRegionRects aRegion( aRetouche );
6621 		aRegion -= rRect;
6622 		ViewShell *pSh = getRootFrm()->GetCurrShell();
6623 
6624         // --> FME 2004-06-24 #i16816# tagged pdf support
6625         SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
6626         // <--
6627 
6628 		for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
6629 		{
6630 			SwRect &rRetouche = aRegion[i];
6631 
6632 			GetUpper()->PaintBaBo( rRetouche, pPage, sal_True );
6633 
6634 			//Hoelle und Himmel muessen auch refreshed werden.
6635 			//Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst
6636 			//zurueckgesetzt werden!
6637 			ResetRetouche();
6638             SwRect aRetouchePart( rRetouche );
6639             if ( aRetouchePart.HasArea() )
6640             {
6641                 const Color aPageBackgrdColor(pPage->GetDrawBackgrdColor());
6642                 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6643                 // --> OD #i76669#
6644                 SwViewObjectContactRedirector aSwRedirector( *pSh );
6645                 // <--
6646 
6647                 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0,
6648                                         aRetouchePart, &aPageBackgrdColor,
6649                                         (pPage->IsRightToLeft() ? true : false),
6650                                         &aSwRedirector );
6651                 pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0,
6652                                         aRetouchePart, &aPageBackgrdColor,
6653                                         (pPage->IsRightToLeft() ? true : false),
6654                                         &aSwRedirector );
6655             }
6656 
6657 			SetRetouche();
6658 
6659 			//Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier
6660 			//leider die Hilfslinien erneuert werden.
6661             pPage->RefreshSubsidiary( aRetouchePart );
6662 		}
6663 	}
6664 	if ( ViewShell::IsLstEndAction() )
6665 		ResetRetouche();
6666 }
6667 
6668 /** SwFrm::GetBackgroundBrush
6669 
6670     @descr
6671     determine the background brush for the frame:
6672     the background brush is taken from it-self or from its parent (anchor/upper).
6673     Normally, the background brush is taken, which has no transparent color or
6674     which has a background graphic. But there are some special cases:
6675     (1) No background brush is taken from a page frame, if view option "IsPageBack"
6676         isn't set.
6677     (2) Background brush from a index section is taken under special conditions.
6678         In this case parameter <rpCol> is set to the index shading color.
6679     (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing
6680         of the frame transparency is considered and its color is not "no fill"/"auto fill"
6681     ---- old description in german:
6682     Beschreibung        Liefert die Backgroundbrush fuer den Bereich des
6683         des Frm. Die Brush wird entweder von ihm selbst oder von einem
6684         Upper vorgegeben, die erste Brush wird benutzt.
6685         Ist fuer keinen Frm eine Brush angegeben, so wird sal_False zurueck-
6686         geliefert.
6687     Ersterstellung      MA 23. Dec. 92
6688     Letzte Aenderung    MA 04. Feb. 97
6689 
6690     @param rpBrush
6691     output parameter - constant reference pointer the found background brush
6692 
6693     @param rpCol
6694     output parameter - constant reference pointer to the color of the index shading
6695     set under special conditions, if background brush is taken from an index section.
6696 
6697     @param rOrigRect
6698     in-/output parameter - reference to the retangle the background brush is
6699     considered for - adjusted to the frame, from which the background brush is
6700     taken.
6701 
6702     @parem bLowerMode
6703     input parameter - boolean indicating, if background brush should *not* be
6704     taken from parent.
6705 
6706     @author MA
6707     @change 20.08.2002 by OD
6708     @docdate 20.08.2002
6709 
6710     @return true, if a background brush for the frame is found
6711 */
6712 sal_Bool SwFrm::GetBackgroundBrush(
6713     drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
6714     const SvxBrushItem* & rpBrush,
6715     const Color*& rpCol,
6716     SwRect &rOrigRect,
6717     sal_Bool bLowerMode ) const
6718 {
6719 	const SwFrm *pFrm = this;
6720 	ViewShell *pSh = getRootFrm()->GetCurrShell();
6721 	const SwViewOption *pOpt = pSh->GetViewOptions();
6722 	rpBrush = 0;
6723 	rpCol = NULL;
6724 	do
6725 	{	if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() )
6726 			return sal_False;
6727 
6728         //UUUU
6729         rFillAttributes = pFrm->getSdrAllFillAttributesHelper();
6730         const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
6731 
6732         if( pFrm->IsSctFrm() )
6733         {
6734             const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
6735             /// OD 20.08.2002 #99657# #GetTransChg#
6736             ///     Note: If frame <pFrm> is a section of the index and
6737             ///         it its background color is "no fill"/"auto fill" and
6738             ///         it has no background graphic and
6739             ///         we are not in the page preview and
6740             ///         we are not in read-only mode and
6741             ///         option "index shadings" is set and
6742             ///         the output is not the printer
6743             ///         then set <rpCol> to the color of the index shading
6744             if( pSection && (   TOX_HEADER_SECTION == pSection->GetType() ||
6745                                 TOX_CONTENT_SECTION == pSection->GetType() ) &&
6746                 (rBack.GetColor() == COL_TRANSPARENT) &&
6747                 ///rBack.GetColor().GetTransparency() &&
6748                 rBack.GetGraphicPos() == GPOS_NONE &&
6749                 !pOpt->IsPagePreview() &&
6750                 !pOpt->IsReadonly() &&
6751                 // --> FME 2004-06-29 #114856# Formular view
6752                 !pOpt->IsFormView() &&
6753                 // <--
6754                 SwViewOption::IsIndexShadings() &&
6755                 !pOpt->IsPDFExport() &&
6756                 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
6757             {
6758                 rpCol = &SwViewOption::GetIndexShadingsColor();
6759             }
6760         }
6761 
6762         /// OD 20.08.2002 #99657#
6763         ///     determine, if background draw of frame <pFrm> considers transparency
6764         ///     --> Status Quo: background transparency have to be
6765         ///                     considered for fly frames
6766         const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm();
6767 
6768         // #i125189# Do not base the decision for using the parent's fill style for this
6769         // frame when the new DrawingLayer FillAttributes are used on the SdrAllFillAttributesHelper
6770         // information. There the data is already optimized to no fill in the case that the
6771         // transparence is at 100% while no fill is the criteria for derivation
6772         bool bNewDrawingLayerFillStyleIsUsedAndNotNoFill(false);
6773 
6774         if(rFillAttributes.get())
6775         {
6776             // the new DrawingLayer FillStyle is used
6777             if(rFillAttributes->isUsed())
6778             {
6779                 // it's not XFILL_NONE
6780                 bNewDrawingLayerFillStyleIsUsedAndNotNoFill = true;
6781             }
6782             else
6783             {
6784                 // maybe optimized already when 100% transparency is used somewhere, need to test
6785                 // XFillStyleItem directly from the model data
6786                 const XFillStyle eFillStyle(static_cast< const XFillStyleItem& >(pFrm->GetAttrSet()->Get(XATTR_FILLSTYLE)).GetValue());
6787 
6788                 if(XFILL_NONE != eFillStyle)
6789                 {
6790                     bNewDrawingLayerFillStyleIsUsedAndNotNoFill = true;
6791                 }
6792             }
6793         }
6794 
6795         /// OD 20.08.2002 #99657#
6796         ///     add condition:
6797         ///     If <bConsiderBackgroundTransparency> is set - see above -,
6798         ///     return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill"
6799         if (
6800             // #i125189# Done when the new DrawingLayer FillAttributes are used and
6801             // not XFILL_NONE (see above)
6802             bNewDrawingLayerFillStyleIsUsedAndNotNoFill ||
6803 
6804             // done when SvxBrushItem is used
6805             !rBack.GetColor().GetTransparency() || rBack.GetGraphicPos() != GPOS_NONE ||
6806 
6807             // done when direct color is forced
6808             rpCol ||
6809 
6810             // done when consider BG transparency and color is not completely transparent
6811             (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT))
6812            )
6813         {
6814             rpBrush = &rBack;
6815 
6816             if ( pFrm->IsPageFrm() && pSh->GetViewOptions()->getBrowseMode() )
6817             {
6818                 rOrigRect = pFrm->Frm();
6819             }
6820             else
6821             {
6822                 if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() )
6823                 {
6824                     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
6825                     const SwBorderAttrs &rAttrs = *aAccess.Get();
6826                     ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, sal_False );
6827                 }
6828                 else
6829                 {
6830                     rOrigRect = pFrm->Prt();
6831                     rOrigRect += pFrm->Frm().Pos();
6832                 }
6833             }
6834 
6835             return sal_True;
6836         }
6837 
6838         if ( bLowerMode )
6839         {
6840             /// Do not try to get background brush from parent (anchor/upper)
6841             return sal_False;
6842         }
6843 
6844         /// get parent frame - anchor or upper - for next loop
6845         if ( pFrm->IsFlyFrm() )
6846         {
6847             /// OD 20.08.2002 - use "static_cast" instead of "old C-cast"
6848             pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm();
6849             ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
6850         }
6851         else
6852         {
6853             pFrm = pFrm->GetUpper();
6854         }
6855     } while ( pFrm );
6856 
6857     return sal_False;
6858 }
6859 
6860 /*************************************************************************
6861 |*
6862 |*	SwFrmFmt::GetGraphic()
6863 |*
6864 |*	Ersterstellung		MA 23. Jul. 96
6865 |*	Letzte Aenderung	MA 23. Jul. 96
6866 |*
6867 |*************************************************************************/
6868 
6869 void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO,
6870 					  Window *pW, sal_uInt16 nZoom )
6871 {
6872 	pSh->pOut = pO;
6873 	pSh->pWin = pW;
6874 	pSh->pOpt->SetZoom( nZoom );
6875 }
6876 
6877 Graphic SwFrmFmt::MakeGraphic( ImageMap* )
6878 {
6879 	return Graphic();
6880 }
6881 
6882 Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap )
6883 {
6884 	Graphic aRet;
6885 	//irgendeinen Fly suchen!
6886 	SwIterator<SwFrm,SwFmt> aIter( *this );
6887     SwFrm *pFirst = aIter.First();
6888 	ViewShell *pSh;
6889     if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) )
6890 	{
6891 		ViewShell *pOldGlobal = pGlobalShell;
6892 		pGlobalShell = pSh;
6893 
6894 		sal_Bool bNoteURL = pMap &&
6895 			SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, sal_True );
6896 		if( bNoteURL )
6897 		{
6898 			ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
6899 			pNoteURL = new SwNoteURL;
6900 		}
6901 		SwFlyFrm *pFly = (SwFlyFrm*)pFirst;
6902 
6903 		OutputDevice *pOld = pSh->GetOut();
6904 		VirtualDevice aDev( *pOld );
6905 		aDev.EnableOutput( sal_False );
6906 
6907 		GDIMetaFile aMet;
6908 		MapMode aMap( pOld->GetMapMode().GetMapUnit() );
6909 		aDev.SetMapMode( aMap );
6910 		aMet.SetPrefMapMode( aMap );
6911 
6912 		::SwCalcPixStatics( pSh->GetOut() );
6913 		aMet.SetPrefSize( pFly->Frm().SSize() );
6914 
6915 		aMet.Record( &aDev );
6916 		aDev.SetLineColor();
6917 		aDev.SetFillColor();
6918 		aDev.SetFont( pOld->GetFont() );
6919 
6920 		//Rechteck ggf. ausdehnen, damit die Umrandunge mit aufgezeichnet werden.
6921 		SwRect aOut( pFly->Frm() );
6922 		SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
6923 		const SwBorderAttrs &rAttrs = *aAccess.Get();
6924 		if ( rAttrs.CalcRightLine() )
6925 			aOut.SSize().Width() += 2*nPixelSzW;
6926 		if ( rAttrs.CalcBottomLine() )
6927 			aOut.SSize().Height()+= 2*nPixelSzH;
6928 
6929 		// #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
6930 		const Region aRepaintRegion(aOut.SVRect());
6931     	pSh->DLPrePaint2(aRepaintRegion);
6932 
6933         Window *pWin = pSh->GetWin();
6934 		sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom();
6935 		::SetOutDevAndWin( pSh, &aDev, 0, 100 );
6936 		bFlyMetafile = sal_True;
6937 		pFlyMetafileOut = pWin;
6938 
6939 		SwViewImp *pImp = pSh->Imp();
6940 		pFlyOnlyDraw = pFly;
6941 		pLines = new SwLineRects;
6942 
6943         // OD 09.12.2002 #103045# - determine page, fly frame is on
6944         const SwPageFrm* pFlyPage = pFly->FindPageFrm();
6945         const Color aPageBackgrdColor(pFlyPage->GetDrawBackgrdColor());
6946         const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6947         // --> OD #i76669#
6948         SwViewObjectContactRedirector aSwRedirector( *pSh );
6949         // <--
6950         pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor,
6951                           (pFlyPage->IsRightToLeft() ? true : false),
6952                           &aSwRedirector );
6953 		pLines->PaintLines( &aDev );
6954 		if ( pFly->IsFlyInCntFrm() )
6955 			pFly->Paint( aOut );
6956 		pLines->PaintLines( &aDev );
6957         /// OD 30.08.2002 #102450# - add 3rd parameter
6958         pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor,
6959                           (pFlyPage->IsRightToLeft() ? true : false),
6960                           &aSwRedirector );
6961 		pLines->PaintLines( &aDev );
6962 		DELETEZ( pLines );
6963 		pFlyOnlyDraw = 0;
6964 
6965 		pFlyMetafileOut = 0;
6966 		bFlyMetafile = sal_False;
6967 		::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
6968 
6969 		// #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted
6970    		pSh->DLPostPaint2(true);
6971 
6972         aMet.Stop();
6973 		aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() );
6974 		aRet = Graphic( aMet );
6975 
6976 		if( bNoteURL )
6977 		{
6978 			ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
6979 			pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap );
6980 			delete pNoteURL;
6981 			pNoteURL = NULL;
6982 		}
6983 		pGlobalShell = pOldGlobal;
6984 	}
6985 	return aRet;
6986 }
6987 
6988 Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* )
6989 {
6990 	Graphic aRet;
6991     SwDrawModel* pMod = getIDocumentDrawModelAccess()->GetDrawModel();
6992 	if ( pMod )
6993 	{
6994 		SdrObject *pObj = FindSdrObject();
6995 		SdrView *pView = new SdrView( pMod );
6996 		SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0));
6997 		pView->MarkObj( pObj, pPgView );
6998 		aRet = pView->GetMarkedObjBitmapEx();
6999 		pView->HideSdrPage();
7000 		delete pView;
7001 	}
7002 	return aRet;
7003 }
7004 
7005 //eof
7006