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