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