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