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