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