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