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