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