xref: /AOO41X/main/sw/source/core/layout/paintfrm.cxx (revision 22ea211e5d72c49b08cce5bd5c7b47abff7c407c)
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 
GetColor() const151     const Color         *GetColor() const { return pColor;}
GetTab() const152     const SwTabFrm      *GetTab()   const { return pTab;  }
SetPainted()153     void  SetPainted()                    { bPainted = sal_True; }
Lock(sal_Bool bLock)154     void  Lock( sal_Bool bLock )              { if ( bLock )
155                                                 ++nLock;
156                                             else if ( nLock )
157                                                 --nLock;
158                                           }
IsPainted() const159     sal_Bool  IsPainted()               const { return bPainted; }
IsLocked() const160     sal_Bool  IsLocked()                const { return nLock != 0;  }
GetSubColor() const161     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;  // unnuetze Durchlaeufe im PaintLines verhindern.
171 public:
SwLineRects()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
Free() const180     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 gepaintet 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 waehrend 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.
SwCalcPixStatics(OutputDevice * pOut)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 
SwSavePaintStatics()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 
~SwSavePaintStatics()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 
SwLineRect(const SwRect & rRect,const Color * pCol,const SwTabFrm * pT,const sal_uInt8 nSCol)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 
MakeUnion(const SwRect & rRect)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 
AddLineRect(const SwRect & rRect,const Color * pCol,const SwTabFrm * pTab,const sal_uInt8 nSCol)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 
ConnectEdges(OutputDevice * pOut)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 
Ins(const SwRect & rRect,const sal_uInt8 nSCol)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 
RemoveSuperfluousSubsidiaryLines(const SwLineRects & rRects)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 
LockLines(sal_Bool bLock)752 void SwLineRects::LockLines( sal_Bool bLock )
753 {
754     for ( sal_uInt16 i = 0; i < Count(); ++i )
755         operator[](i).Lock( bLock );
756 }
757 
PaintLines(OutputDevice * pOut)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 
PaintSubsidiary(OutputDevice * pOut,const SwLineRects * pRects)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.
SwAlignRect(SwRect & rRect,ViewShell * pSh)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 */
lcl_CompPxPosAndAdjustPos(const OutputDevice & _rOut,const Point & _rRefPt,Point & _rCompPt,const sal_Bool _bChkXPos,const sal_Int8 _nPxAdjustment)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 */
SwAlignGrfRect(SwRect * pGrfRect,const OutputDevice & rOut)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 
lcl_AlignWidth(const long nWidth)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 
lcl_AlignHeight(const long nHeight)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 
lcl_MinHeightDist(const long nDist)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 
lcl_MinWidthDist(const long nDist)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.
lcl_CalcBorderRect(SwRect & rRect,const SwFrm * pFrm,const SwBorderAttrs & rAttrs,const sal_Bool bShadow)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 
lcl_ExtendLeftAndRight(SwRect & _rRect,const SwFrm & _rFrm,const SwBorderAttrs & _rAttrs,const SwRectFn & _rRectFn)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 
lcl_SubtractFlys(const SwFrm * pFrm,const SwPageFrm * pPage,const SwRect & rRect,SwRegionRects & rRegion)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 */
lcl_implDrawGraphicBackgrd(const SvxBrushItem & _rBackgrdBrush,OutputDevice * _pOut,const SwRect & _rAlignedPaintRect,const GraphicObject & _rGraphicObj)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 
lcl_DrawGraphicBackgrd(const SvxBrushItem & _rBackgrdBrush,OutputDevice * _pOut,const SwRect & _rAlignedPaintRect,const GraphicObject & _rGraphicObj,bool _bNumberingGraphic,bool _bBackgrdAlreadyDrawn=false)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>.
lcl_DrawGraphic(const SvxBrushItem & rBrush,OutputDevice * pOut,ViewShell & rSh,const SwRect & rGrf,const SwRect & rOut,bool bClip,bool bGrfNum,bool bBackgrdAlreadyDrawn=false)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 
DrawGraphic(const SvxBrushItem * pBrush,OutputDevice * pOutDev,const SwRect & rOrg,const SwRect & rOut,const sal_uInt8 nGrfNum,const sal_Bool bConsiderBackgroundTransparency)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 */
lcl_AdjustRectToPixelSize(SwRect & io_aSwRect,const OutputDevice & aOut)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 
SwLineEntry(SwTwips nKey,SwTwips nStartPos,SwTwips nEndPos,const svx::frame::Style & rAttribute)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 
Overlaps(const SwLineEntry & rNew) const2132 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 {
operator ()lt_SwLineEntry2153     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 
SwTabFrmPainter(const SwTabFrm & rTabFrm)2186 SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm )
2187     : mrTabFrm( rTabFrm )
2188 {
2189     HandleFrame( rTabFrm );
2190 }
2191 
HandleFrame(const SwLayoutFrm & rLayoutFrm)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 
PaintLines(OutputDevice & rDev,const SwRect & rRect) const2222 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         SwLineEntrySetConstIter 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.
FindStylesForLine(const Point & rStartPoint,const Point & rEndPoint,svx::frame::Style * pStyles,bool bHori) const2440 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 
Insert(const SwFrm & rFrm,const SvxBoxItem & rBoxItem)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 
Insert(SwLineEntry & rNew,bool bHori)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:
SwViewObjectContactRedirector(const ViewShell & rSh)2711             SwViewObjectContactRedirector( const ViewShell& rSh )
2712                 : mrViewShell( rSh )
2713             {};
2714 
~SwViewObjectContactRedirector()2715             virtual ~SwViewObjectContactRedirector()
2716             {}
2717 
createRedirectedPrimitive2DSequence(const sdr::contact::ViewObjectContact & rOriginal,const sdr::contact::DisplayInfo & rDisplayInfo)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
Paint(SwRect const & rRect,SwPrintData const * const pPrintData) const2761 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 
HackPrepareLongTblPaint(int nMode)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 
lcl_EmergencyFormatFtnCont(SwFtnContFrm * pCont)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 );
Stop(const SwRect & rRect) const3168     sal_Bool Stop( const SwRect& rRect ) const
3169         { return (rRect.*fnCheck)( nLimit ) > 0; }
3170 };
3171 
SwShortCut(const SwFrm & rFrm,const SwRect & rRect)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 
Paint(SwRect const & rRect,SwPrintData const * const) const3210 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 */
IsBackgroundTransparent() const3338 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 */
IsShadowTransparent() const3390 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 
IsPaint(SdrObject * pObj,const ViewShell * pSh)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 |*************************************************************************/
Paint(SwRect const & rRect,SwPrintData const * const) const3504 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 
Paint(SwRect const & rRect,SwPrintData const * const) const3523 void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3524 {
3525     //begin:optimize thumbnail generate and store procedure to improve odt saving performance, i120030
3526     ViewShell *pShell = getRootFrm()->GetCurrShell();
3527     if (pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocShell())
3528     {
3529         sal_Bool bInGenerateThumbnail = pShell->GetDoc()->GetDocShell()->IsInGenerateAndStoreThumbnail();
3530         if (bInGenerateThumbnail)
3531         {
3532             SwRect aVisRect = pShell->VisArea();
3533             if (!aVisRect.IsOver(Frm()))
3534                 return;
3535         }
3536     }
3537     //end:i120030
3538 
3539     //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die
3540     //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben.
3541     //z.B. #33066#
3542     pLines->LockLines(sal_True);
3543 
3544     SwRect aRect( rRect );
3545     aRect._Intersection( Frm() );
3546 
3547     OutputDevice* pOut = pGlobalShell->GetOut();
3548     pOut->Push( PUSH_CLIPREGION );
3549     pOut->SetClipRegion();
3550     const SwPageFrm* pPage = FindPageFrm();
3551 
3552     const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm()
3553                                                 ? (SwNoTxtFrm*)Lower() : 0;
3554 
3555     bool bIsChart = false; //#i102950# don't paint additional borders for charts
3556     //check whether we have a chart
3557     if(pNoTxt)
3558     {
3559         const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode());
3560         if( pNoTNd )
3561         {
3562             SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode());
3563             if( pOLENd && ChartHelper::IsChart( pOLENd->GetOLEObj().GetObject() ) )
3564                 bIsChart = true;
3565         }
3566     }
3567 
3568     {
3569         bool bContour = GetFmt()->GetSurround().IsContour();
3570         PolyPolygon aPoly;
3571         if ( bContour )
3572         {
3573             // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True>
3574             // to indicate that method is called for paint in order to avoid
3575             // load of the intrinsic graphic.
3576             bContour = GetContour( aPoly, sal_True );
3577         }
3578 
3579         // --> OD 2005-06-08 #i47804# - distinguish complete background paint
3580         // and margin paint.
3581         // paint complete background for Writer text fly frames
3582         bool bPaintCompleteBack( !pNoTxt );
3583         // <--
3584         // paint complete background for transparent graphic and contour,
3585         // if own background color exists.
3586         const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false;
3587         if ( !bPaintCompleteBack &&
3588              ( bIsGraphicTransparent|| bContour ) )
3589         {
3590             const SvxBrushItem &rBack = GetFmt()->GetBackground();
3591             // OD 07.08.2002 #99657# #GetTransChg#
3592             //     to determine, if background has to be painted, by checking, if
3593             //     background color is not COL_TRANSPARENT ("no fill"/"auto fill")
3594             //     or a background graphic exists.
3595             bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) ||
3596                                  rBack.GetGraphicPos() != GPOS_NONE;
3597         }
3598         // paint of margin needed.
3599         const bool bPaintMarginOnly( !bPaintCompleteBack &&
3600                                      Prt().SSize() != Frm().SSize() );
3601 
3602         // --> OD 2005-06-08 #i47804# - paint background of parent fly frame
3603         // for transparent graphics in layer Hell, if parent fly frame isn't
3604         // in layer Hell. It's only painted the intersection between the
3605         // parent fly frame area and the paint area <aRect>
3606         const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
3607 
3608         if ( bIsGraphicTransparent &&
3609             GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() &&
3610             GetAnchorFrm()->FindFlyFrm() )
3611         {
3612             const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm();
3613             if ( pParentFlyFrm->GetDrawObj()->GetLayer() !=
3614                                             pIDDMA->GetHellId() )
3615             {
3616                 SwFlyFrm* pOldRet = pRetoucheFly2;
3617                 pRetoucheFly2 = const_cast<SwFlyFrm*>(this);
3618 
3619                 SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm );
3620                 const SwBorderAttrs &rAttrs = *aAccess.Get();
3621                 SwRect aPaintRect( aRect );
3622                 aPaintRect._Intersection( pParentFlyFrm->Frm() );
3623                 pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False );
3624 
3625                 pRetoucheFly2 = pOldRet;
3626             }
3627         }
3628 
3629         if ( bPaintCompleteBack || bPaintMarginOnly )
3630         {
3631             //#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder
3632             //das orig. Rect bekommt, aber PaintBackground das begrenzte.
3633 
3634             // OD 2004-04-23 #116347#
3635             pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
3636             pOut->SetLineColor();
3637 
3638             pPage = FindPageFrm();
3639 
3640             SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3641             const SwBorderAttrs &rAttrs = *aAccess.Get();
3642 
3643             // OD 06.08.2002 #99657# - paint border before painting background
3644             // paint border
3645             {
3646                 SwRect aTmp( rRect );
3647                 PaintBorder( aTmp, pPage, rAttrs );
3648             }
3649 
3650             // paint background
3651             {
3652                 SwRegionRects aRegion( aRect );
3653                 // --> OD 2007-12-13 #i80822#
3654                 // suppress painting of background in printing area for
3655                 // non-transparent graphics.
3656 //                if ( bPaintMarginOnly )
3657                 if ( bPaintMarginOnly ||
3658                      ( pNoTxt && !bIsGraphicTransparent ) )
3659                 // <--
3660                 {
3661                     //Was wir eigentlich Painten wollen ist der schmale Streifen
3662                     //zwischen PrtArea und aeusserer Umrandung.
3663                     SwRect aTmp( Prt() ); aTmp += Frm().Pos();
3664                     aRegion -= aTmp;
3665                 }
3666                 if ( bContour )
3667                 {
3668                     pOut->Push();
3669                     // --> OD 2007-12-13 #i80822#
3670                     // apply clip region under the same conditions, which are
3671                     // used in <SwNoTxtFrm::Paint(..)> to set the clip region
3672                     // for painting the graphic/OLE. Thus, the clip region is
3673                     // also applied for the PDF export.
3674 //                    if ( !pOut->GetConnectMetaFile() || pOut->GetOutDevType() == OUTDEV_PRINTER )
3675                     ViewShell *pSh = getRootFrm()->GetCurrShell();
3676                     if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() )
3677                     // <--
3678                     {
3679                         pOut->SetClipRegion( aPoly );
3680                     }
3681                     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
3682                         PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
3683                     pOut->Pop();
3684                 }
3685                 else
3686                     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
3687                         PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
3688             }
3689 
3690             pOut->Pop();
3691         }
3692     }
3693 
3694     // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and
3695     // the subsidiary lines of its lowers on its own, due to overlapping with
3696     // other fly frames or other objects.
3697     if( pGlobalShell->GetWin()
3698         && !bIsChart ) //#i102950# don't paint additional borders for charts
3699     {
3700         bool bSubsLineRectsCreated;
3701         if ( pSubsLines )
3702         {
3703             // Lock already existing subsidiary lines
3704             pSubsLines->LockLines( sal_True );
3705             bSubsLineRectsCreated = false;
3706         }
3707         else
3708         {
3709             // create new subsidiardy lines
3710             pSubsLines = new SwSubsRects;
3711             bSubsLineRectsCreated = true;
3712         }
3713 
3714         bool bSpecSubsLineRectsCreated;
3715         if ( pSpecSubsLines )
3716         {
3717             // Lock already existing special subsidiary lines
3718             pSpecSubsLines->LockLines( sal_True );
3719             bSpecSubsLineRectsCreated = false;
3720         }
3721         else
3722         {
3723             // create new special subsidiardy lines
3724             pSpecSubsLines = new SwSubsRects;
3725             bSpecSubsLineRectsCreated = true;
3726         }
3727         // Add subsidiary lines of fly frame and its lowers
3728         RefreshLaySubsidiary( pPage, aRect );
3729         // paint subsidiary lines of fly frame and its lowers
3730         pSpecSubsLines->PaintSubsidiary( pOut, NULL );
3731         pSubsLines->PaintSubsidiary( pOut, pLines );
3732         if ( !bSubsLineRectsCreated )
3733             // unlock subsidiary lines
3734             pSubsLines->LockLines( sal_False );
3735         else
3736             // delete created subsidiary lines container
3737             DELETEZ( pSubsLines );
3738 
3739         if ( !bSpecSubsLineRectsCreated )
3740             // unlock special subsidiary lines
3741             pSpecSubsLines->LockLines( sal_False );
3742         else
3743         {
3744             // delete created special subsidiary lines container
3745             DELETEZ( pSpecSubsLines );
3746         }
3747     }
3748 
3749     SwLayoutFrm::Paint( aRect );
3750 
3751     Validate();
3752 
3753     // OD 19.12.2002 #106318# - first paint lines added by fly frame paint
3754     // and then unlock other lines.
3755     pLines->PaintLines( pOut );
3756     pLines->LockLines( sal_False );
3757 
3758     pOut->Pop();
3759 
3760     if ( pProgress && pNoTxt )
3761         pProgress->Reschedule();
3762 }
3763 /*************************************************************************
3764 |*
3765 |*    SwTabFrm::Paint()
3766 |*
3767 |*    Ersterstellung    MA 11. May. 93
3768 |*    Letzte Aenderung  MA 23. Mar. 95
3769 |*
3770 |*************************************************************************/
3771 
Paint(SwRect const & rRect,SwPrintData const * const) const3772 void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3773 {
3774     if ( pGlobalShell->GetViewOptions()->IsTable() )
3775     {
3776         // --> collapsing borders FME 2005-05-27 #i29550#
3777         if ( IsCollapsingBorders() )
3778         {
3779             SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
3780             const SwBorderAttrs &rAttrs = *aAccess.Get();
3781 
3782             // paint shadow
3783             if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
3784             {
3785                 SwRect aRect;
3786                 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
3787                 PaintShadow( rRect, aRect, rAttrs );
3788             }
3789 
3790             // paint lines
3791             SwTabFrmPainter aHelper( *this );
3792             aHelper.PaintLines( *pGlobalShell->GetOut(), rRect );
3793         }
3794         // <-- collapsing
3795 
3796         SwLayoutFrm::Paint( rRect );
3797     }
3798     // OD 10.01.2003 #i6467# - no light grey rectangle for page preview
3799     else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() )
3800     {
3801         // OD 10.01.2003 #i6467# - intersect output rectangle with table frame
3802         SwRect aTabRect( Prt() );
3803         aTabRect.Pos() += Frm().Pos();
3804         SwRect aTabOutRect( rRect );
3805         aTabOutRect.Intersection( aTabRect );
3806         pGlobalShell->GetViewOptions()->
3807                 DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY );
3808     }
3809     ((SwTabFrm*)this)->ResetComplete();
3810 }
3811 
3812 /*************************************************************************
3813 |*
3814 |*  SwFrm::PaintShadow()
3815 |*
3816 |*  Beschreibung        Malt einen Schatten wenns das FrmFormat fordert.
3817 |*      Der Schatten wird immer an den auesseren Rand des OutRect gemalt.
3818 |*      Das OutRect wird ggf. so verkleinert, dass auf diesem das
3819 |*      malen der Umrandung stattfinden kann.
3820 |*  Ersterstellung      MA 21. Dec. 92
3821 |*  Letzte Aenderung    MA 29. May. 97
3822 |*
3823 |*************************************************************************/
3824 /// OD 23.08.2002 #99657#
3825 ///     draw full shadow rectangle for frames with transparent drawn backgrounds.
PaintShadow(const SwRect & rRect,SwRect & rOutRect,const SwBorderAttrs & rAttrs) const3826 void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
3827                          const SwBorderAttrs &rAttrs ) const
3828 {
3829     const SvxShadowItem &rShadow = rAttrs.GetShadow();
3830     const long nWidth  = ::lcl_AlignWidth ( rShadow.GetWidth() );
3831     const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() );
3832 
3833     SwRects aRegion( 2, 2 );
3834     SwRect aOut( rOutRect );
3835 
3836     const sal_Bool bCnt    = IsCntntFrm();
3837     const sal_Bool bTop    = !bCnt || rAttrs.GetTopLine  ( *(this) ) ? sal_True : sal_False;
3838     const sal_Bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? sal_True : sal_False;
3839 
3840     SvxShadowLocation eLoc = rShadow.GetLocation();
3841 
3842     SWRECTFN( this )
3843     if( IsVertical() )
3844     {
3845         switch( eLoc )
3846         {
3847             case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;  break;
3848             case SVX_SHADOW_TOPLEFT:     eLoc = SVX_SHADOW_TOPRIGHT;    break;
3849             case SVX_SHADOW_TOPRIGHT:    eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
3850             case SVX_SHADOW_BOTTOMLEFT:  eLoc = SVX_SHADOW_TOPLEFT;     break;
3851             default: break;
3852         }
3853     }
3854 
3855     /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to
3856     ///     be drawn or only two shadow rectangles beside the frame.
3857     ///     draw full shadow rectangle, if frame background is drawn transparent.
3858     ///     Status Quo:
3859     ///         SwLayoutFrm can have transparent drawn backgrounds. Thus,
3860     ///         "asked" their frame format.
3861     sal_Bool bDrawFullShadowRectangle =
3862             ( IsLayoutFrm() &&
3863               (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent()
3864             );
3865     switch ( eLoc )
3866     {
3867         case SVX_SHADOW_BOTTOMRIGHT:
3868             {
3869                 if ( bDrawFullShadowRectangle )
3870                 {
3871                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
3872                     aOut.Top( aOut.Top() + nHeight );
3873                     aOut.Left( aOut.Left() + nWidth );
3874                     aRegion.Insert( aOut, aRegion.Count() );
3875                 }
3876                 else
3877                 {
3878                     aOut.Top ( aOut.Bottom() - nHeight );
3879                     aOut.Left( aOut.Left()   + nWidth );
3880                     if ( bBottom )
3881                         aRegion.Insert( aOut, aRegion.Count() );
3882                     aOut.Left( aOut.Right()   - nWidth );
3883                     aOut.Top ( rOutRect.Top() + nHeight );
3884                     if ( bBottom )
3885                         aOut.Bottom( aOut.Bottom() - nHeight );
3886                     if ( bCnt && (!bTop || !bBottom) )
3887                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3888                     aRegion.Insert( aOut, aRegion.Count() );
3889                 }
3890 
3891                 rOutRect.Right ( rOutRect.Right() - nWidth );
3892                 rOutRect.Bottom( rOutRect.Bottom()- nHeight );
3893             }
3894             break;
3895         case SVX_SHADOW_TOPLEFT:
3896             {
3897                 if ( bDrawFullShadowRectangle )
3898                 {
3899                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
3900                     aOut.Bottom( aOut.Bottom() - nHeight );
3901                     aOut.Right( aOut.Right() - nWidth );
3902                     aRegion.Insert( aOut, aRegion.Count() );
3903                 }
3904                 else
3905                 {
3906                     aOut.Bottom( aOut.Top()   + nHeight );
3907                     aOut.Right ( aOut.Right() - nWidth );
3908                     if ( bTop )
3909                         aRegion.Insert( aOut, aRegion.Count() );
3910                     aOut.Right ( aOut.Left() + nWidth );
3911                     aOut.Bottom( rOutRect.Bottom() - nHeight );
3912                     if ( bTop )
3913                         aOut.Top( aOut.Top() + nHeight );
3914                     if ( bCnt && (!bBottom || !bTop) )
3915                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3916                     aRegion.Insert( aOut, aRegion.Count() );
3917                 }
3918 
3919                 rOutRect.Left( rOutRect.Left() + nWidth );
3920                 rOutRect.Top(  rOutRect.Top() + nHeight );
3921             }
3922             break;
3923         case SVX_SHADOW_TOPRIGHT:
3924             {
3925                 if ( bDrawFullShadowRectangle )
3926                 {
3927                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
3928                     aOut.Bottom( aOut.Bottom() - nHeight);
3929                     aOut.Left( aOut.Left() + nWidth );
3930                     aRegion.Insert( aOut, aRegion.Count() );
3931                 }
3932                 else
3933                 {
3934                     aOut.Bottom( aOut.Top() + nHeight );
3935                     aOut.Left (  aOut.Left()+ nWidth );
3936                     if ( bTop )
3937                         aRegion.Insert( aOut, aRegion.Count() );
3938                     aOut.Left  ( aOut.Right() - nWidth );
3939                     aOut.Bottom( rOutRect.Bottom() - nHeight );
3940                     if ( bTop )
3941                         aOut.Top( aOut.Top() + nHeight );
3942                     if ( bCnt && (!bBottom || bTop) )
3943                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3944                     aRegion.Insert( aOut, aRegion.Count() );
3945                 }
3946 
3947                 rOutRect.Right( rOutRect.Right() - nWidth );
3948                 rOutRect.Top( rOutRect.Top() + nHeight );
3949             }
3950             break;
3951         case SVX_SHADOW_BOTTOMLEFT:
3952             {
3953                 if ( bDrawFullShadowRectangle )
3954                 {
3955                     /// OD 06.08.2002 #99657# - draw full shadow rectangle
3956                     aOut.Top( aOut.Top() + nHeight );
3957                     aOut.Right( aOut.Right() - nWidth );
3958                     aRegion.Insert( aOut, aRegion.Count() );
3959                 }
3960                 else
3961                 {
3962                     aOut.Top  ( aOut.Bottom()- nHeight );
3963                     aOut.Right( aOut.Right() - nWidth );
3964                     if ( bBottom )
3965                         aRegion.Insert( aOut, aRegion.Count() );
3966                     aOut.Right( aOut.Left() + nWidth );
3967                     aOut.Top( rOutRect.Top() + nHeight );
3968                     if ( bBottom )
3969                         aOut.Bottom( aOut.Bottom() - nHeight );
3970                     if ( bCnt && (!bTop || !bBottom) )
3971                         ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
3972                     aRegion.Insert( aOut, aRegion.Count() );
3973                 }
3974 
3975                 rOutRect.Left( rOutRect.Left() + nWidth );
3976                 rOutRect.Bottom( rOutRect.Bottom() - nHeight );
3977             }
3978             break;
3979         default:
3980             ASSERT( !this, "new ShadowLocation() ?" )
3981             break;
3982     }
3983 
3984     OutputDevice *pOut = pGlobalShell->GetOut();
3985 
3986     sal_uLong nOldDrawMode = pOut->GetDrawMode();
3987     Color aShadowColor( rShadow.GetColor() );
3988     if( aRegion.Count() && pGlobalShell->GetWin() &&
3989         Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
3990     {
3991         // Is heigh contrast mode, the output device has already set the
3992         // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function
3993         // to ignore the setting of a new color. Therefore we have to reset
3994         // the drawing mode
3995         pOut->SetDrawMode( 0 );
3996         aShadowColor = SwViewOption::GetFontColor();
3997     }
3998 
3999     if ( pOut->GetFillColor() != aShadowColor )
4000         pOut->SetFillColor( aShadowColor );
4001 
4002     pOut->SetDrawMode( nOldDrawMode );
4003 
4004     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
4005     {
4006         SwRect &rOut = aRegion[i];
4007         aOut = rOut;
4008         // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle
4009         // no alignment necessary, because (1) <rRect> is already aligned
4010         // and because (2) paint of border and background will occur later.
4011         // Thus, (1) assures that no conflicts with neighbour object will occure
4012         // and (2) assures that border and background is not affected by the
4013         // shadow paint.
4014         /*
4015         ::SwAlignRect( aOut, pGlobalShell );
4016         */
4017         if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
4018         {
4019             aOut._Intersection( rRect );
4020             pOut->DrawRect( aOut.SVRect() );
4021         }
4022     }
4023 }
4024 
4025 /*************************************************************************
4026 |*
4027 |*  SwFrm::PaintBorderLine()
4028 |*
4029 |*  Ersterstellung      MA 22. Dec. 92
4030 |*  Letzte Aenderung    MA 22. Jan. 95
4031 |*
4032 |*************************************************************************/
4033 
PaintBorderLine(const SwRect & rRect,const SwRect & rOutRect,const SwPageFrm * pPage,const Color * pColor) const4034 void SwFrm::PaintBorderLine( const SwRect& rRect,
4035                              const SwRect& rOutRect,
4036                              const SwPageFrm *pPage,
4037                              const Color *pColor ) const
4038 {
4039     if ( !rOutRect.IsOver( rRect ) )
4040         return;
4041 
4042     SwRect aOut( rOutRect );
4043     aOut._Intersection( rRect );
4044 
4045     const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0;
4046     sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB :
4047                    ( IsInSct() ? SUBCOL_SECT :
4048                    ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
4049     if( pColor && pGlobalShell->GetWin() &&
4050         Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4051     {
4052         pColor = &SwViewOption::GetFontColor();
4053     }
4054 
4055     if ( pPage->GetSortedObjs() )
4056     {
4057         SwRegionRects aRegion( aOut, 4, 1 );
4058         ::lcl_SubtractFlys( this, pPage, aOut, aRegion );
4059         for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
4060             pLines->AddLineRect( aRegion[i], pColor, pTab, nSubCol );
4061     }
4062     else
4063         pLines->AddLineRect( aOut, pColor, pTab, nSubCol );
4064 }
4065 
4066 /*************************************************************************
4067 |*
4068 |*  SwFrm::PaintBorderLines()
4069 |*
4070 |*  Beschreibung        Nur alle Linien einfach oder alle Linien doppelt!!!!
4071 |*  Ersterstellung      MA 22. Dec. 92
4072 |*  Letzte Aenderung    MA 22. Mar. 95
4073 |*
4074 |*************************************************************************/
4075 
4076 // OD 29.04.2003 #107169# - method called for left and right border rectangles.
4077 // For a printer output device perform adjustment for non-overlapping top and
4078 // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate
4079 // printer output device.
4080 // NOTE: For printer output device left/right border rectangle <_iorRect>
4081 //       has to be already non-overlapping the outer top/bottom border rectangle.
lcl_SubTopBottom(SwRect & _iorRect,const SvxBoxItem & _rBox,const SwBorderAttrs & _rAttrs,const SwFrm & _rFrm,const SwRectFn & _rRectFn,const sal_Bool _bPrtOutputDev)4082 void MA_FASTCALL lcl_SubTopBottom( SwRect&              _iorRect,
4083                                    const SvxBoxItem&    _rBox,
4084                                    const SwBorderAttrs& _rAttrs,
4085                                    const SwFrm&         _rFrm,
4086                                    const SwRectFn&      _rRectFn,
4087                                    const sal_Bool       _bPrtOutputDev )
4088 {
4089     const sal_Bool bCnt = _rFrm.IsCntntFrm();
4090     if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() &&
4091          ( !bCnt || _rAttrs.GetTopLine( _rFrm ) )
4092        )
4093     {
4094         // substract distance between outer and inner line.
4095         SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() );
4096         // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4097         // adjust x-/y-position, if inner top line is a hair line (width = 1)
4098         sal_Bool bIsInnerTopLineHairline = sal_False;
4099         if ( !_bPrtOutputDev )
4100         {
4101             // additionally substract width of top outer line
4102             // --> left/right inner/outer line doesn't overlap top outer line.
4103             nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() );
4104         }
4105         else
4106         {
4107             // OD 29.04.2003 #107169# - additionally substract width of top inner line
4108             // --> left/right inner/outer line doesn't overlap top inner line.
4109             nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() );
4110             bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1;
4111         }
4112         (_iorRect.*_rRectFn->fnSubTop)( -nDist );
4113         // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line
4114         // is a hair line
4115         if ( bIsInnerTopLineHairline )
4116         {
4117             if ( _rFrm.IsVertical() )
4118             {
4119                 // right of border rectangle has to be checked and adjusted
4120                 Point aCompPt( _iorRect.Right(), 0 );
4121                 Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4122                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4123                                           aRefPt, aCompPt,
4124                                           sal_True, -1 );
4125                 _iorRect.Right( aCompPt.X() );
4126             }
4127             else
4128             {
4129                 // top of border rectangle has to be checked and adjusted
4130                 Point aCompPt( 0, _iorRect.Top() );
4131                 Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4132                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4133                                           aRefPt, aCompPt,
4134                                           sal_False, +1 );
4135                 _iorRect.Top( aCompPt.Y() );
4136             }
4137         }
4138     }
4139 
4140     if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() &&
4141          ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) )
4142        )
4143     {
4144         // substract distance between outer and inner line.
4145         SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() );
4146         // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4147         // adjust x-/y-position, if inner bottom line is a hair line (width = 1)
4148         sal_Bool bIsInnerBottomLineHairline = sal_False;
4149         if ( !_bPrtOutputDev )
4150         {
4151             // additionally substract width of bottom outer line
4152             // --> left/right inner/outer line doesn't overlap bottom outer line.
4153             nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() );
4154         }
4155         else
4156         {
4157             // OD 29.04.2003 #107169# - additionally substract width of bottom inner line
4158             // --> left/right inner/outer line doesn't overlap bottom inner line.
4159             nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() );
4160             bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1;
4161         }
4162         (_iorRect.*_rRectFn->fnAddBottom)( -nDist );
4163         // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner
4164         // bottom line is a hair line.
4165         if ( bIsInnerBottomLineHairline )
4166         {
4167             if ( _rFrm.IsVertical() )
4168             {
4169                 // left of border rectangle has to be checked and adjusted
4170                 Point aCompPt( _iorRect.Left(), 0 );
4171                 Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4172                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4173                                           aRefPt, aCompPt,
4174                                           sal_True, +1 );
4175                 _iorRect.Left( aCompPt.X() );
4176             }
4177             else
4178             {
4179                 // bottom of border rectangle has to be checked and adjusted
4180                 Point aCompPt( 0, _iorRect.Bottom() );
4181                 Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4182                 lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4183                                           aRefPt, aCompPt,
4184                                           sal_False, -1 );
4185                 _iorRect.Bottom( aCompPt.Y() );
4186             }
4187         }
4188     }
4189 }
4190 
4191 // method called for top and bottom border rectangles.
lcl_SubLeftRight(SwRect & rRect,const SvxBoxItem & rBox,const SwRectFn & rRectFn)4192 void MA_FASTCALL lcl_SubLeftRight( SwRect&           rRect,
4193                                    const SvxBoxItem& rBox,
4194                                    const SwRectFn&   rRectFn )
4195 {
4196     if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() )
4197     {
4198         const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() )
4199                            + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() );
4200         (rRect.*rRectFn->fnSubLeft)( -nDist );
4201     }
4202 
4203     if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() )
4204     {
4205         const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() )
4206                            + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() );
4207         (rRect.*rRectFn->fnAddRight)( -nDist );
4208     }
4209 }
4210 
4211 // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine>
4212 // into new method <lcl_PaintLeftRightLine(..)>
lcl_PaintLeftRightLine(const sal_Bool _bLeft,const SwFrm & _rFrm,const SwPageFrm & _rPage,const SwRect & _rOutRect,const SwRect & _rRect,const SwBorderAttrs & _rAttrs,const SwRectFn & _rRectFn)4213 void lcl_PaintLeftRightLine( const sal_Bool         _bLeft,
4214                              const SwFrm&           _rFrm,
4215                              const SwPageFrm&       _rPage,
4216                              const SwRect&          _rOutRect,
4217                              const SwRect&          _rRect,
4218                              const SwBorderAttrs&   _rAttrs,
4219                              const SwRectFn&        _rRectFn )
4220 {
4221     const SvxBoxItem& rBox = _rAttrs.GetBox();
4222     const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft();
4223     const SvxBorderLine* pLeftRightBorder = 0;
4224     if ( _bLeft )
4225     {
4226         pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft();
4227     }
4228     else
4229     {
4230         pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight();
4231     }
4232     // OD 06.05.2003 #107169# - init boolean indicating printer output device.
4233     const sal_Bool bPrtOutputDev =
4234             ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() );
4235 
4236     if ( !pLeftRightBorder )
4237     {
4238         return;
4239     }
4240 
4241     SwRect aRect( _rOutRect );
4242     if ( _bLeft )
4243     {
4244         (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4245                                        (aRect.*_rRectFn->fnGetWidth)() );
4246     }
4247     else
4248     {
4249         (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( pLeftRightBorder->GetOutWidth() ) -
4250                                       (aRect.*_rRectFn->fnGetWidth)() );
4251     }
4252 
4253     const sal_Bool bCnt = _rFrm.IsCntntFrm();
4254 
4255     if ( bCnt )
4256     {
4257         ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn );
4258     }
4259 
4260     // OD 06.05.2003 #107169# - adjustments for printer output device
4261     if ( bPrtOutputDev )
4262     {
4263         // substract width of outer top line.
4264         if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) )
4265         {
4266             long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() );
4267             (aRect.*_rRectFn->fnSubTop)( -nDist );
4268             // OD 19.05.2003 #109667# - If outer top line is hair line, calculated
4269             // top has to be adjusted.
4270             if ( nDist == 1 )
4271             {
4272                 if ( _rFrm.IsVertical() )
4273                 {
4274                     // right of border rectangle has to be checked and adjusted
4275                     Point aCompPt( aRect.Right(), 0 );
4276                     Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4277                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4278                                               aRefPt, aCompPt,
4279                                               sal_True, -1 );
4280                     aRect.Right( aCompPt.X() );
4281                 }
4282                 else
4283                 {
4284                     // top of border rectangle has to be checked and adjusted
4285                     Point aCompPt( 0, aRect.Top() );
4286                     Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4287                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4288                                               aRefPt, aCompPt,
4289                                               sal_False, +1 );
4290                     aRect.Top( aCompPt.Y() );
4291                 }
4292             }
4293         }
4294         // substract width of outer bottom line.
4295         if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) )
4296         {
4297             long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth());
4298             (aRect.*_rRectFn->fnAddBottom)( -nDist );
4299             // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated
4300             // top has to be adjusted.
4301             if ( nDist == 1 )
4302             {
4303                 if ( _rFrm.IsVertical() )
4304                 {
4305                     // left of border rectangle has to be checked and adjusted
4306                     Point aCompPt( aRect.Left(), 0 );
4307                     Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4308                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4309                                               aRefPt, aCompPt,
4310                                               sal_True, +1 );
4311                     aRect.Left( aCompPt.X() );
4312                 }
4313                 else
4314                 {
4315                     // bottom of border rectangle has to be checked and adjusted
4316                     Point aCompPt( 0, aRect.Bottom() );
4317                     Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4318                     lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4319                                               aRefPt, aCompPt,
4320                                               sal_False, -1 );
4321                     aRect.Bottom( aCompPt.Y() );
4322                 }
4323             }
4324         }
4325     }
4326 
4327     if ( !pLeftRightBorder->GetInWidth() )
4328     {
4329         // OD 06.05.2003 #107169# - add 6th parameter
4330         ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4331     }
4332 
4333     // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4334     {
4335         SwRect aPaintRect( aRect );
4336         ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4337         // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4338         // to the prior left postion with width of one twip.
4339         if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4340         {
4341             if ( _bLeft )
4342             {
4343                 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4344                 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4345                 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4346             }
4347             else
4348             {
4349                 (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4350                 (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4351                 (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4352             }
4353         }
4354         _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4355     }
4356 
4357     if ( pLeftRightBorder->GetInWidth() )
4358     {
4359         const long nDist = ::lcl_MinWidthDist( pLeftRightBorder->GetDistance() );
4360         long nWidth = ::lcl_AlignWidth( pLeftRightBorder->GetInWidth() );
4361         if ( _bLeft )
4362         {
4363             (aRect.*_rRectFn->fnAddRight)( nDist + nWidth );
4364             (aRect.*_rRectFn->fnSubLeft)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4365         }
4366         else
4367         {
4368             (aRect.*_rRectFn->fnSubLeft)( nDist + nWidth );
4369             (aRect.*_rRectFn->fnAddRight)( nWidth - (aRect.*_rRectFn->fnGetWidth)() );
4370         }
4371         // OD 06.05.2003 #107169# - add 6th parameter
4372         ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4373         // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4374         {
4375             SwRect aPaintRect( aRect );
4376             ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4377             // if <SwAlignRect> reveals rectangle with no width, adjust
4378             // rectangle to the prior left postion with width of one twip.
4379             if ( (aPaintRect.*_rRectFn->fnGetWidth)() == 0 )
4380             {
4381                 if ( _bLeft )
4382                 {
4383                     (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetLeft)() );
4384                     (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetLeft)() );
4385                     (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4386                 }
4387                 else
4388                 {
4389                     (aPaintRect.*_rRectFn->fnSetLeft)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4390                     (aPaintRect.*_rRectFn->fnSetRight)( (aRect.*_rRectFn->fnGetRight)() - 1 );
4391                     (aPaintRect.*_rRectFn->fnAddRight)( 1 );
4392                 }
4393             }
4394             _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pLeftRightBorder->GetColor() );
4395         }
4396     }
4397 }
4398 
4399 // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine>
4400 // into <lcl_PaintTopLine>
lcl_PaintTopBottomLine(const sal_Bool _bTop,const SwFrm & _rFrm,const SwPageFrm & _rPage,const SwRect & _rOutRect,const SwRect & _rRect,const SwBorderAttrs & _rAttrs,const SwRectFn & _rRectFn)4401 void lcl_PaintTopBottomLine( const sal_Bool         _bTop,
4402                              const SwFrm&           _rFrm,
4403                              const SwPageFrm&       _rPage,
4404                              const SwRect&          _rOutRect,
4405                              const SwRect&          _rRect,
4406                              const SwBorderAttrs&   _rAttrs,
4407                              const SwRectFn&        _rRectFn )
4408 {
4409     const SvxBoxItem& rBox = _rAttrs.GetBox();
4410     const SvxBorderLine* pTopBottomBorder = 0;
4411     if ( _bTop )
4412     {
4413         pTopBottomBorder = rBox.GetTop();
4414     }
4415     else
4416     {
4417         pTopBottomBorder = rBox.GetBottom();
4418     }
4419 
4420     if ( !pTopBottomBorder )
4421     {
4422         return;
4423     }
4424 
4425     SwRect aRect( _rOutRect );
4426     if ( _bTop )
4427     {
4428         (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4429                                         (aRect.*_rRectFn->fnGetHeight)() );
4430     }
4431     else
4432     {
4433         (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( pTopBottomBorder->GetOutWidth() ) -
4434                                      (aRect.*_rRectFn->fnGetHeight)() );
4435     }
4436 
4437     // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4438     {
4439         SwRect aPaintRect( aRect );
4440         ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4441         // if <SwAlignRect> reveals rectangle with no width, adjust rectangle
4442         // to the prior top postion with width of one twip.
4443         if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4444         {
4445             if ( _bTop )
4446             {
4447                 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4448                 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4449                 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4450             }
4451             else
4452             {
4453                 (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4454                 (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4455                 (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4456             }
4457         }
4458         _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4459     }
4460 
4461     if ( pTopBottomBorder->GetInWidth() )
4462     {
4463         const long nDist = ::lcl_MinHeightDist( pTopBottomBorder->GetDistance() );
4464         const long nHeight = ::lcl_AlignHeight( pTopBottomBorder->GetInWidth() );
4465         if ( _bTop )
4466         {
4467             (aRect.*_rRectFn->fnAddBottom)( nDist + nHeight );
4468             (aRect.*_rRectFn->fnSubTop)( nHeight - (aRect.*_rRectFn->fnGetHeight)() );
4469         }
4470         else
4471         {
4472             (aRect.*_rRectFn->fnSubTop)( nDist + nHeight );
4473             (aRect.*_rRectFn->fnAddBottom)( nHeight -(aRect.*_rRectFn->fnGetHeight)() );
4474         }
4475         ::lcl_SubLeftRight( aRect, rBox, _rRectFn );
4476         // OD 29.04.2003 #107169# - paint SwAligned-rectangle
4477         {
4478             SwRect aPaintRect( aRect );
4479             ::SwAlignRect( aPaintRect, _rFrm.getRootFrm()->GetCurrShell() );
4480             // if <SwAlignRect> reveals rectangle with no width, adjust
4481             // rectangle to the prior top postion with width of one twip.
4482             if ( (aPaintRect.*_rRectFn->fnGetHeight)() == 0 )
4483             {
4484                 if ( _bTop )
4485                 {
4486                     (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetTop)() );
4487                     (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetTop)() );
4488                     (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4489                 }
4490                 else
4491                 {
4492                     (aPaintRect.*_rRectFn->fnSetTop)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4493                     (aPaintRect.*_rRectFn->fnSetBottom)( (aRect.*_rRectFn->fnGetBottom)() - 1 );
4494                     (aPaintRect.*_rRectFn->fnAddBottom)( 1 );
4495                 }
4496             }
4497             _rFrm.PaintBorderLine( _rRect, aPaintRect, &_rPage, &pTopBottomBorder->GetColor() );
4498         }
4499     }
4500 }
4501 
4502 
4503 /*************************************************************************
4504 |*
4505 |*  const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4506 |*
4507 |* No comment. #i15844#
4508 |*
4509 |*************************************************************************/
4510 
lcl_HasNextCell(const SwFrm & rFrm)4511 const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
4512 {
4513     ASSERT( rFrm.IsCellFrm(),
4514             "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" )
4515 
4516     const SwFrm* pTmpFrm = &rFrm;
4517     do
4518     {
4519         if ( pTmpFrm->GetNext() )
4520             return pTmpFrm->GetNext();
4521 
4522         pTmpFrm = pTmpFrm->GetUpper()->GetUpper();
4523     }
4524     while ( pTmpFrm->IsCellFrm() );
4525 
4526     return 0;
4527 }
4528 
4529 
4530 /*************************************************************************
4531 |*
4532 |*  SwFrm::PaintBorder()
4533 |*
4534 |*  Beschreibung        Malt Schatten und Umrandung
4535 |*  Ersterstellung      MA 23.01.92
4536 |*  Letzte Aenderung    MA 29. Jul. 96
4537 |*
4538 |*************************************************************************/
4539 
4540 /** local method to determine cell frame, from which the border attributes
4541     for paint of top/bottom border has to be used.
4542 
4543     OD 21.02.2003 #b4779636#, #107692#
4544 
4545     @author OD
4546 
4547 
4548     @param _pCellFrm
4549     input parameter - constant pointer to cell frame for which the cell frame
4550     for the border attributes has to be determined.
4551 
4552     @param _rCellBorderAttrs
4553     input parameter - constant reference to the border attributes of cell frame
4554     <_pCellFrm>.
4555 
4556     @param _bTop
4557     input parameter - boolean, that controls, if cell frame for top border or
4558     for bottom border has to be determined.
4559 
4560     @return constant pointer to cell frame, for which the border attributes has
4561     to be used
4562 */
lcl_GetCellFrmForBorderAttrs(const SwFrm * _pCellFrm,const SwBorderAttrs & _rCellBorderAttrs,const bool _bTop)4563 const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm*         _pCellFrm,
4564                                            const SwBorderAttrs& _rCellBorderAttrs,
4565                                            const bool           _bTop )
4566 {
4567     ASSERT( _pCellFrm, "No cell frame available, dying soon" )
4568 
4569     // determine, if cell frame is at bottom/top border of a table frame and
4570     // the table frame has/is a follow.
4571     const SwFrm* pTmpFrm = _pCellFrm;
4572     bool bCellAtBorder = true;
4573     bool bCellAtLeftBorder = !_pCellFrm->GetPrev();
4574     bool bCellAtRightBorder = !_pCellFrm->GetNext();
4575     while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() )
4576     {
4577         pTmpFrm = pTmpFrm->GetUpper();
4578         if ( pTmpFrm->IsRowFrm() &&
4579              (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext())
4580            )
4581         {
4582             bCellAtBorder = false;
4583         }
4584         if ( pTmpFrm->IsCellFrm() )
4585         {
4586             if ( pTmpFrm->GetPrev() )
4587             {
4588                 bCellAtLeftBorder = false;
4589             }
4590             if ( pTmpFrm->GetNext() )
4591             {
4592                 bCellAtRightBorder = false;
4593             }
4594         }
4595     }
4596     ASSERT( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" );
4597 
4598     const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm);
4599     const SwTabFrm* pParentTabFrm =
4600             static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper());
4601 
4602     const bool bCellNeedsAttribute = bCellAtBorder &&
4603                                      ( _bTop ?
4604                                       // bCellInFirstRowWithMaster
4605                                        ( !pParentRowFrm->GetPrev() &&
4606                                          pParentTabFrm->IsFollow() &&
4607                                          0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) :
4608                                       // bCellInLastRowWithFollow
4609                                        ( !pParentRowFrm->GetNext() &&
4610                                          pParentTabFrm->GetFollow() )
4611                                      );
4612 
4613     const SwFrm* pRet = _pCellFrm;
4614     if ( bCellNeedsAttribute )
4615     {
4616         // determine, if cell frame has no borders inside the table.
4617         const SwFrm* pNextCell = 0;
4618         bool bNoBordersInside = false;
4619 
4620         if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) )
4621         {
4622             SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell );
4623             const SwBorderAttrs &rBorderAttrs = *aAccess.Get();
4624             const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox();
4625             bCellAtRightBorder = !lcl_HasNextCell( *pNextCell );
4626             bNoBordersInside =
4627                 ( !rBorderBox.GetTop()    || !pParentRowFrm->GetPrev() ) &&
4628                   !rBorderBox.GetLeft() &&
4629                 ( !rBorderBox.GetRight()  || bCellAtRightBorder ) &&
4630                 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4631         }
4632         else
4633         {
4634             const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox();
4635             bNoBordersInside =
4636                 ( !rBorderBox.GetTop()    || !pParentRowFrm->GetPrev() ) &&
4637                 ( !rBorderBox.GetLeft()   || bCellAtLeftBorder ) &&
4638                 ( !rBorderBox.GetRight()  || bCellAtRightBorder ) &&
4639                 ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
4640         }
4641 
4642         if ( bNoBordersInside )
4643         {
4644             if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() )
4645             {
4646                 // #b4779636#-hack:
4647                 // Cell frame has no top border and no border inside the table, but
4648                 // it is at the top border of a table frame, which is a follow.
4649                 // Thus, use border attributes of cell frame in first row of complete table.
4650                 // First, determine first table frame of complete table.
4651                 SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true );
4652                 // determine first row of complete table.
4653                 const SwFrm* pFirstRow = pMasterTabFrm->GetLower();
4654                 // return first cell in first row
4655                 SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower());
4656                 while ( !pLowerCell->IsCellFrm() ||
4657                         ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4658                       )
4659                 {
4660                     pLowerCell = pLowerCell->GetLower();
4661                 }
4662                 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4663                 pRet = pLowerCell;
4664             }
4665             else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() )
4666             {
4667                 // #b4779636#-hack:
4668                 // Cell frame has no bottom border and no border inside the table,
4669                 // but it is at the bottom border of a table frame, which has a follow.
4670                 // Thus, use border attributes of cell frame in last row of complete table.
4671                 // First, determine last table frame of complete table.
4672                 SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow());
4673                 while ( pLastTabFrm->GetFollow() )
4674                 {
4675                     pLastTabFrm = pLastTabFrm->GetFollow();
4676                 }
4677                 // determine last row of complete table.
4678                 SwFrm* pLastRow = pLastTabFrm->GetLastLower();
4679                 // return first bottom border cell in last row
4680                 SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower());
4681                 while ( !pLowerCell->IsCellFrm() ||
4682                         ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
4683                       )
4684                 {
4685                     if ( pLowerCell->IsRowFrm() )
4686                     {
4687                         while ( pLowerCell->GetNext() )
4688                         {
4689                             pLowerCell = pLowerCell->GetNext();
4690                         }
4691                     }
4692                     pLowerCell = pLowerCell->GetLower();
4693                 }
4694                 ASSERT( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
4695                 pRet = pLowerCell;
4696             }
4697         }
4698     }
4699 
4700     return pRet;
4701 }
4702 
PaintBorder(const SwRect & rRect,const SwPageFrm * pPage,const SwBorderAttrs & rAttrs) const4703 void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4704                          const SwBorderAttrs &rAttrs ) const
4705 {
4706     //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun
4707     if ( (GetType() & 0x90C5) || (Prt().SSize() == Frm().SSize()) )
4708         return;
4709 
4710     if ( (GetType() & 0x2000) &&    //Cell
4711          !pGlobalShell->GetViewOptions()->IsTable() )
4712         return;
4713 
4714     // --> collapsing borders FME 2005-05-27 #i29550#
4715     if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
4716     {
4717         const SwTabFrm* pTabFrm = FindTabFrm();
4718         if ( pTabFrm->IsCollapsingBorders() )
4719             return;
4720 
4721         if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) )
4722             return;
4723     }
4724     // <--
4725 
4726     const bool bLine = rAttrs.IsLine() ? true : false;
4727     const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE;
4728 
4729     // OD 24.02.2003 #b4779636#, #107692# - flag to control,
4730     // if #b4779636#-hack has to be used.
4731     const bool bb4779636HackActive = true;
4732     // OD 21.02.2003 #b4779636#, #107692#
4733     const SwFrm* pCellFrmForBottomBorderAttrs = 0;
4734     const SwFrm* pCellFrmForTopBorderAttrs = 0;
4735     bool         bFoundCellForTopOrBorderAttrs = false;
4736     if ( bb4779636HackActive && IsCellFrm() )
4737     {
4738         pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false );
4739         if ( pCellFrmForBottomBorderAttrs != this )
4740             bFoundCellForTopOrBorderAttrs = true;
4741         pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true );
4742         if ( pCellFrmForTopBorderAttrs != this )
4743             bFoundCellForTopOrBorderAttrs = true;
4744     }
4745 
4746     // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4747     // for #b4779636#-hack
4748     if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs )
4749     {
4750         //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt,
4751         //so braucht kein Rand gepaintet werden.
4752         //Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden,
4753         //anderfalls wuerden u.U. Teile nicht verarbeitet.
4754         SwRect aRect( Prt() );
4755         aRect += Frm().Pos();
4756         ::SwAlignRect( aRect, pGlobalShell );
4757         // OD 27.09.2002 #103636# - new local boolean variable in order to
4758         // suspend border paint under special cases - see below.
4759         // NOTE: This is a fix for the implementation of feature #99657#.
4760         bool bDrawOnlyShadowForTransparentFrame = false;
4761         if ( aRect.IsInside( rRect ) )
4762         {
4763             // OD 27.09.2002 #103636# - paint shadow, if background is transparent.
4764             // Because of introduced transparent background for fly frame #99657#,
4765             // the shadow have to be drawn if the background is transparent,
4766             // in spite the fact that the paint rectangle <rRect> lies fully
4767             // in the printing area.
4768             // NOTE to chosen solution:
4769             //     On transparent background, continue processing, but suspend
4770             //     drawing of border by setting <bDrawOnlyShadowForTransparentFrame>
4771             //     to true.
4772             if ( IsLayoutFrm() &&
4773                  static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() )
4774             {
4775                  bDrawOnlyShadowForTransparentFrame = true;
4776             }
4777             else
4778             {
4779                 return;
4780             }
4781         }
4782 
4783         if ( !pPage )
4784             pPage = FindPageFrm();
4785 
4786         ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
4787         rAttrs.SetGetCacheLine( sal_True );
4788         if ( bShadow )
4789             PaintShadow( rRect, aRect, rAttrs );
4790         // OD 27.09.2002 #103636# - suspend drawing of border
4791         // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
4792         // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
4793         // for #b4779636#-hack.
4794         if ( ( bLine || bFoundCellForTopOrBorderAttrs ) &&
4795              !bDrawOnlyShadowForTransparentFrame )
4796         {
4797             const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this;
4798             SWRECTFN( pDirRefFrm )
4799             // OD 19.05.2003 #109667# - use new method <lcl_PaintLeftRightLine(..)>
4800             //::lcl_PaintLeftLine  ( this, pPage, aRect, rRect, rAttrs, fnRect );
4801             //::lcl_PaintRightLine ( this, pPage, aRect, rRect, rAttrs, fnRect );
4802             ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4803             ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4804             if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) )
4805             {
4806                 // OD 21.02.2003 #b4779636#, #107692# -
4807                 // #b4779636#-hack: If another cell frame for top border
4808                 // paint is found, paint its top border.
4809                 if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this )
4810                 {
4811                     SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4812                                                 pCellFrmForTopBorderAttrs );
4813                     const SwBorderAttrs &rTopAttrs = *aAccess.Get();
4814                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4815                     //::lcl_PaintTopLine( this, pPage, aRect, rRect, rTopAttrs, fnRect );
4816                     ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect );
4817                 }
4818                 else
4819                 {
4820                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4821                     //::lcl_PaintTopLine( this, pPage, aRect, rRect, rAttrs, fnRect );
4822                     ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
4823                 }
4824             }
4825             if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) )
4826             {
4827                 // OD 21.02.2003 #b4779636#, #107692# -
4828                 // #b4779636#-hack: If another cell frame for bottom border
4829                 // paint is found, paint its bottom border.
4830                 if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this )
4831                 {
4832                     SwBorderAttrAccess aAccess( SwFrm::GetCache(),
4833                                                 pCellFrmForBottomBorderAttrs );
4834                     const SwBorderAttrs &rBottomAttrs = *aAccess.Get();
4835                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4836                     //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rBottomAttrs, fnRect);
4837                     ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect);
4838                 }
4839                 else
4840                 {
4841                     // OD 19.05.2003 #109667# - use new method <lcl_PaintTopBottomLine(..)>
4842                     //::lcl_PaintBottomLine(this, pPage, aRect, rRect, rAttrs, fnRect);
4843                     ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect);
4844                 }
4845             }
4846         }
4847         rAttrs.SetGetCacheLine( sal_False );
4848     }
4849 }
4850 /*************************************************************************
4851 |*
4852 |*  SwFtnContFrm::PaintBorder()
4853 |*
4854 |*  Beschreibung        Spezialimplementierung wg. der Fussnotenlinie.
4855 |*      Derzeit braucht nur der obere Rand beruecksichtigt werden.
4856 |*      Auf andere Linien und Schatten wird verzichtet.
4857 |*  Ersterstellung      MA 27. Feb. 93
4858 |*  Letzte Aenderung    MA 08. Sep. 93
4859 |*
4860 |*************************************************************************/
4861 
PaintBorder(const SwRect & rRect,const SwPageFrm * pPage,const SwBorderAttrs &) const4862 void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
4863                                 const SwBorderAttrs & ) const
4864 {
4865     //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es
4866     //keinen Rand zu painten.
4867     SwRect aRect( Prt() );
4868     aRect.Pos() += Frm().Pos();
4869     if ( !aRect.IsInside( rRect ) )
4870         PaintLine( rRect, pPage );
4871 }
4872 /*************************************************************************
4873 |*
4874 |*  SwFtnContFrm::PaintLine()
4875 |*
4876 |*  Beschreibung        Fussnotenline malen.
4877 |*  Ersterstellung      MA 02. Mar. 93
4878 |*  Letzte Aenderung    MA 28. Mar. 94
4879 |*
4880 |*************************************************************************/
4881 
PaintLine(const SwRect & rRect,const SwPageFrm * pPage) const4882 void SwFtnContFrm::PaintLine( const SwRect& rRect,
4883                               const SwPageFrm *pPage ) const
4884 {
4885     //Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc.
4886     //Die Position ist ebenfalls am PageDesc angegeben.
4887     //Der Pen steht direkt im PageDesc.
4888 
4889     if ( !pPage )
4890         pPage = FindPageFrm();
4891     const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
4892 
4893     SWRECTFN( this )
4894     SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)();
4895     Fraction aFract( nPrtWidth, 1 );
4896     const SwTwips nWidth = (long)(aFract *= rInf.GetWidth());
4897 
4898     SwTwips nX = (this->*fnRect->fnGetPrtLeft)();
4899     switch ( rInf.GetAdj() )
4900     {
4901         case FTNADJ_CENTER:
4902             nX += nPrtWidth/2 - nWidth/2; break;
4903         case FTNADJ_RIGHT:
4904             nX += nPrtWidth - nWidth; break;
4905         case FTNADJ_LEFT:
4906             /* do nothing */; break;
4907         default:
4908             ASSERT( !this, "Neues Adjustment fuer Fussnotenlinie?" );
4909     }
4910     SwTwips nLineWidth = rInf.GetLineWidth();
4911     const SwRect aLineRect = bVert ?
4912         SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth,
4913                       nX), Size( nLineWidth, nWidth ) )
4914             : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ),
4915                             Size( nWidth, rInf.GetLineWidth()));
4916     if ( aLineRect.HasArea() )
4917         PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor() );
4918 }
4919 
4920 /*************************************************************************
4921 |*
4922 |*  SwLayoutFrm::PaintColLines()
4923 |*
4924 |*  Beschreibung        Painted die Trennlinien fuer die innenliegenden
4925 |*                      Spalten.
4926 |*  Ersterstellung      MA 21. Jun. 93
4927 |*  Letzte Aenderung    MA 28. Mar. 94
4928 |*
4929 |*************************************************************************/
4930 
PaintColLines(const SwRect & rRect,const SwFmtCol & rFmtCol,const SwPageFrm * pPage) const4931 void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol,
4932                                  const SwPageFrm *pPage ) const
4933 {
4934     const SwFrm *pCol = Lower();
4935     if ( !pCol || !pCol->IsColumnFrm() )
4936         return;
4937     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
4938     SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
4939 
4940     SwRect aLineRect = Prt();
4941     aLineRect += Frm().Pos();
4942 
4943     SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight())
4944                    / 100 - (aLineRect.*fnRect->fnGetHeight)();
4945     SwTwips nBottom = 0;
4946 
4947     switch ( rFmtCol.GetLineAdj() )
4948     {
4949         case COLADJ_CENTER:
4950             nBottom = nTop / 2; nTop -= nBottom; break;
4951         case COLADJ_TOP:
4952             nBottom = nTop; nTop = 0; break;
4953         case COLADJ_BOTTOM:
4954             break;
4955         default:
4956             ASSERT( !this, "Neues Adjustment fuer Spaltenlinie?" );
4957     }
4958 
4959     if( nTop )
4960         (aLineRect.*fnRect->fnSubTop)( nTop );
4961     if( nBottom )
4962         (aLineRect.*fnRect->fnAddBottom)( nBottom );
4963 
4964     SwTwips nPenHalf = rFmtCol.GetLineWidth();
4965     (aLineRect.*fnRect->fnSetWidth)( nPenHalf );
4966     nPenHalf /= 2;
4967 
4968     //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein.
4969     SwRect aRect( rRect );
4970     (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW );
4971     (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW );
4972     SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight;
4973     while ( pCol->GetNext() )
4974     {
4975         (aLineRect.*fnRect->fnSetPosX)
4976             ( (pCol->Frm().*fnGetX)() - nPenHalf );
4977         if ( aRect.IsOver( aLineRect ) )
4978             PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor());
4979         pCol = pCol->GetNext();
4980     }
4981 }
4982 
PaintGrid(OutputDevice * pOut,SwRect & rRect) const4983 void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const
4984 {
4985     if( !bHasGrid || pRetoucheFly || pRetoucheFly2 )
4986         return;
4987     GETGRID( this )
4988     if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ?
4989         pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) )
4990     {
4991         const SwLayoutFrm* pBody = FindBodyCont();
4992         if( pBody )
4993         {
4994             SwRect aGrid( pBody->Prt() );
4995             aGrid += pBody->Frm().Pos();
4996 
4997             SwRect aInter( aGrid );
4998             aInter.Intersection( rRect );
4999             if( aInter.HasArea() )
5000             {
5001                 sal_Bool bGrid = pGrid->GetRubyTextBelow();
5002                 sal_Bool bCell = GRID_LINES_CHARS == pGrid->GetGridType();
5003                 long nGrid = pGrid->GetBaseHeight();
5004                 const SwDoc* pDoc = GetFmt()->GetDoc();
5005                 long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor
5006                 long nRuby = pGrid->GetRubyHeight();
5007                 long nSum = nGrid + nRuby;
5008                 const Color *pCol = &pGrid->GetColor();
5009 
5010                 SwTwips nRight = aInter.Left() + aInter.Width();
5011                 SwTwips nBottom = aInter.Top() + aInter.Height();
5012                 if( IsVertical() )
5013                 {
5014                     SwTwips nOrig = aGrid.Left() + aGrid.Width();
5015                     SwTwips nY = nOrig + nSum *
5016                                  ( ( nOrig - aInter.Left() ) / nSum );
5017                     SwRect aTmp( Point( nY, aInter.Top() ),
5018                                 Size( 1, aInter.Height() ) );
5019                     SwTwips nX = aGrid.Top() + nGrid *
5020                                 ( ( aInter.Top() - aGrid.Top() )/ nGrid );
5021                     if( nX < aInter.Top() )
5022                         nX += nGrid;
5023                     SwTwips nGridBottom = aGrid.Top() + aGrid.Height();
5024                     sal_Bool bLeft = aGrid.Top() >= aInter.Top();
5025                     sal_Bool bRight = nGridBottom <= nBottom;
5026                     sal_Bool bBorder = bLeft || bRight;
5027                     while( nY > nRight )
5028                     {
5029                         aTmp.Pos().X() = nY;
5030                         if( bGrid )
5031                         {
5032                             nY -= nGrid;
5033                             SwTwips nPosY = Max( aInter.Left(), nY );
5034                             SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY;
5035                             if( nHeight > 0 )
5036                             {
5037                                 if( bCell )
5038                                 {
5039                                     SwRect aVert( Point( nPosY, nX ),
5040                                                 Size( nHeight, 1 ) );
5041                                     while( aVert.Top() <= nBottom )
5042                                     {
5043                                         PaintBorderLine(rRect,aVert,this,pCol);
5044                                         aVert.Pos().Y() += nGrid;
5045                                     }
5046                                 }
5047                                 else if( bBorder )
5048                                 {
5049                                     SwRect aVert( Point( nPosY, aGrid.Top() ),
5050                                                   Size( nHeight, 1 ) );
5051                                     if( bLeft )
5052                                         PaintBorderLine(rRect,aVert,this,pCol);
5053                                     if( bRight )
5054                                     {
5055                                         aVert.Pos().Y() = nGridBottom;
5056                                         PaintBorderLine(rRect,aVert,this,pCol);
5057                                     }
5058                                 }
5059                             }
5060                         }
5061                         else
5062                         {
5063                             nY -= nRuby;
5064                             if( bBorder )
5065                             {
5066                                 SwTwips nPos = Max( aInter.Left(), nY );
5067                                 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5068                                 SwRect aVert( Point( nPos, aGrid.Top() ),
5069                                               Size( nW, 1 ) );
5070                                 if( nW > 0 )
5071                                 {
5072                                     if( bLeft )
5073                                         PaintBorderLine(rRect,aVert,this,pCol);
5074                                     if( bRight )
5075                                     {
5076                                         aVert.Pos().Y() = nGridBottom;
5077                                         PaintBorderLine(rRect,aVert,this,pCol);
5078                                     }
5079                                 }
5080                             }
5081                         }
5082                         bGrid = !bGrid;
5083                     }
5084                     while( nY >= aInter.Left() )
5085                     {
5086                         aTmp.Pos().X() = nY;
5087                         PaintBorderLine( rRect, aTmp, this, pCol);
5088                         if( bGrid )
5089                         {
5090                             nY -= nGrid;
5091                             SwTwips nHeight = aTmp.Pos().X()
5092                                               - Max(aInter.Left(), nY );
5093                             if( nHeight > 0 )
5094                             {
5095                                 if( bCell )
5096                                 {
5097                                     SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5098                                                   nX ), Size( nHeight, 1 ) );
5099                                     while( aVert.Top() <= nBottom )
5100                                     {
5101                                         PaintBorderLine(rRect,aVert,this,pCol);
5102                                         aVert.Pos().Y() += nGrid;
5103                                     }
5104                                 }
5105                                 else if( bBorder )
5106                                 {
5107                                     SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5108                                             aGrid.Top() ), Size( nHeight, 1 ) );
5109                                     if( bLeft )
5110                                         PaintBorderLine(rRect,aVert,this,pCol);
5111                                     if( bRight )
5112                                     {
5113                                         aVert.Pos().Y() = nGridBottom;
5114                                         PaintBorderLine(rRect,aVert,this,pCol);
5115                                     }
5116                                 }
5117                             }
5118                         }
5119                         else
5120                         {
5121                             nY -= nRuby;
5122                             if( bBorder )
5123                             {
5124                                 SwTwips nPos = Max( aInter.Left(), nY );
5125                                 SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
5126                                 SwRect aVert( Point( nPos, aGrid.Top() ),
5127                                               Size( nW, 1 ) );
5128                                 if( nW > 0 )
5129                                 {
5130                                     if( bLeft )
5131                                         PaintBorderLine(rRect,aVert,this,pCol);
5132                                     if( bRight )
5133                                     {
5134                                         aVert.Pos().Y() = nGridBottom;
5135                                         PaintBorderLine(rRect,aVert,this,pCol);
5136                                     }
5137                                 }
5138                             }
5139                         }
5140                         bGrid = !bGrid;
5141                     }
5142                 }
5143                 else
5144                 {
5145                     SwTwips nOrig = aGrid.Top();
5146                     SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum );
5147                     SwRect aTmp( Point( aInter.Left(), nY ),
5148                                 Size( aInter.Width(), 1 ) );
5149                     //for textgrid refactor
5150                     SwTwips nX = aGrid.Left() + nGridWidth *
5151                         ( ( aInter.Left() - aGrid.Left() )/ nGridWidth );
5152                     if( nX < aInter.Left() )
5153                         nX += nGridWidth;
5154                     SwTwips nGridRight = aGrid.Left() + aGrid.Width();
5155                     sal_Bool bLeft = aGrid.Left() >= aInter.Left();
5156                     sal_Bool bRight = nGridRight <= nRight;
5157                     sal_Bool bBorder = bLeft || bRight;
5158                     while( nY < aInter.Top() )
5159                     {
5160                         aTmp.Pos().Y() = nY;
5161                         if( bGrid )
5162                         {
5163                             nY += nGrid;
5164                             SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() );
5165                             SwTwips nHeight = Min(nBottom, nY ) - nPosY;
5166                             if( nHeight )
5167                             {
5168                                 if( bCell )
5169                                 {
5170                                     SwRect aVert( Point( nX, nPosY ),
5171                                                 Size( 1, nHeight ) );
5172                                     while( aVert.Left() <= nRight )
5173                                     {
5174                                         PaintBorderLine(rRect,aVert,this,pCol);
5175                                         aVert.Pos().X() += nGridWidth;  //for textgrid refactor
5176                                     }
5177                                 }
5178                                 else if ( bBorder )
5179                                 {
5180                                     SwRect aVert( Point( aGrid.Left(), nPosY ),
5181                                                 Size( 1, nHeight ) );
5182                                     if( bLeft )
5183                                         PaintBorderLine(rRect,aVert,this,pCol);
5184                                     if( bRight )
5185                                     {
5186                                         aVert.Pos().X() = nGridRight;
5187                                         PaintBorderLine(rRect,aVert,this,pCol);
5188                                     }
5189                                 }
5190                             }
5191                         }
5192                         else
5193                         {
5194                             nY += nRuby;
5195                             if( bBorder )
5196                             {
5197                                 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5198                                 SwTwips nH = Min( nBottom, nY ) - nPos;
5199                                 SwRect aVert( Point( aGrid.Left(), nPos ),
5200                                             Size( 1, nH ) );
5201                                 if( nH > 0 )
5202                                 {
5203                                     if( bLeft )
5204                                         PaintBorderLine(rRect,aVert,this,pCol);
5205                                     if( bRight )
5206                                     {
5207                                         aVert.Pos().X() = nGridRight;
5208                                         PaintBorderLine(rRect,aVert,this,pCol);
5209                                     }
5210                                 }
5211                             }
5212                         }
5213                         bGrid = !bGrid;
5214                     }
5215                     while( nY <= nBottom )
5216                     {
5217                         aTmp.Pos().Y() = nY;
5218                         PaintBorderLine( rRect, aTmp, this, pCol);
5219                         if( bGrid )
5220                         {
5221                             nY += nGrid;
5222                             SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y();
5223                             if( nHeight )
5224                             {
5225                                 if( bCell )
5226                                 {
5227                                     SwRect aVert( Point( nX, aTmp.Pos().Y() ),
5228                                                 Size( 1, nHeight ) );
5229                                     while( aVert.Left() <= nRight )
5230                                     {
5231                                         PaintBorderLine( rRect, aVert, this, pCol);
5232                                         aVert.Pos().X() += nGridWidth;  //for textgrid refactor
5233                                     }
5234                                 }
5235                                 else if( bBorder )
5236                                 {
5237                                     SwRect aVert( Point( aGrid.Left(),
5238                                         aTmp.Pos().Y() ), Size( 1, nHeight ) );
5239                                     if( bLeft )
5240                                         PaintBorderLine(rRect,aVert,this,pCol);
5241                                     if( bRight )
5242                                     {
5243                                         aVert.Pos().X() = nGridRight;
5244                                         PaintBorderLine(rRect,aVert,this,pCol);
5245                                     }
5246                                 }
5247                             }
5248                         }
5249                         else
5250                         {
5251                             nY += nRuby;
5252                             if( bBorder )
5253                             {
5254                                 SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
5255                                 SwTwips nH = Min( nBottom, nY ) - nPos;
5256                                 SwRect aVert( Point( aGrid.Left(), nPos ),
5257                                             Size( 1, nH ) );
5258                                 if( nH > 0 )
5259                                 {
5260                                     if( bLeft )
5261                                         PaintBorderLine(rRect,aVert,this,pCol);
5262                                     if( bRight )
5263                                     {
5264                                         aVert.Pos().X() = nGridRight;
5265                                         PaintBorderLine(rRect,aVert,this,pCol);
5266                                     }
5267                                 }
5268                             }
5269                         }
5270                         bGrid = !bGrid;
5271                     }
5272                 }
5273             }
5274         }
5275     }
5276 }
5277 
5278 /** paint margin area of a page
5279 
5280     OD 20.11.2002 for #104598#:
5281     implement paint of margin area; margin area will be painted for a
5282     view shell with a window and if the document is not in online layout.
5283 
5284     @author OD
5285 
5286     @param _rOutputRect
5287     input parameter - constant instance reference of the rectangle, for
5288     which an output has to be generated.
5289 
5290     @param _pViewShell
5291     input parameter - instance of the view shell, on which the output
5292     has to be generated.
5293 */
PaintMarginArea(const SwRect & _rOutputRect,ViewShell * _pViewShell) const5294 void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect,
5295                                  ViewShell* _pViewShell ) const
5296 {
5297     if (  _pViewShell->GetWin() &&
5298          !_pViewShell->GetViewOptions()->getBrowseMode() )
5299     {
5300         SwRect aPgPrtRect( Prt() );
5301         aPgPrtRect.Pos() += Frm().Pos();
5302         if ( !aPgPrtRect.IsInside( _rOutputRect ) )
5303         {
5304             SwRect aPgRect = Frm();
5305             aPgRect._Intersection( _rOutputRect );
5306             SwRegionRects aPgRegion( aPgRect );
5307             aPgRegion -= aPgPrtRect;
5308             const SwPageFrm* pPage = static_cast<const SwPageFrm*>(this);
5309             if ( pPage->GetSortedObjs() )
5310                 ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion );
5311             if ( aPgRegion.Count() )
5312             {
5313                 OutputDevice *pOut = _pViewShell->GetOut();
5314                 if ( pOut->GetFillColor() != aGlobalRetoucheColor )
5315                     pOut->SetFillColor( aGlobalRetoucheColor );
5316                 for ( sal_uInt16 i = 0; i < aPgRegion.Count(); ++i )
5317                 {
5318                     if ( 1 < aPgRegion.Count() )
5319                     {
5320                         ::SwAlignRect( aPgRegion[i], pGlobalShell );
5321                         if( !aPgRegion[i].HasArea() )
5322                             continue;
5323                     }
5324                     pOut->DrawRect(aPgRegion[i].SVRect());
5325                 }
5326             }
5327         }
5328     }
5329 }
5330 
5331 // ----------------------------------------------------------------------
5332 //
5333 // const SwPageFrm::mnBorderPxWidth, const SwPageFrm::mnShadowPxWidth
5334 // SwPageFrm::GetBorderRect (..), SwPageFrm::GetRightShadowRect(..),
5335 // SwPageFrm::GetBottomShadowRect(..),
5336 // SwPageFrm::PaintBorderAndShadow(..),
5337 // SwPageFrm::GetBorderAndShadowBoundRect(..)
5338 //
5339 // OD 12.02.2003 for #i9719# and #105645#
5340 // ----------------------------------------------------------------------
5341 
5342 const sal_Int8 SwPageFrm::mnBorderPxWidth = 1;
5343 const sal_Int8 SwPageFrm::mnShadowPxWidth = 2;
5344 
5345 /** determine rectangle for page border
5346 
5347     OD 12.02.2003 for #i9719# and #105645#
5348 
5349     @author OD
5350 */
GetBorderRect(const SwRect & _rPageRect,ViewShell * _pViewShell,SwRect & _orBorderRect,bool bRightSidebar)5351 /*static*/ void SwPageFrm::GetBorderRect( const SwRect& _rPageRect,
5352                                           ViewShell*    _pViewShell,
5353                                           SwRect& _orBorderRect,
5354                                           bool bRightSidebar )
5355 {
5356     SwRect aAlignedPageRect( _rPageRect );
5357     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5358     Rectangle aBorderPxRect =
5359             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5360 
5361     aBorderPxRect.Left() = aBorderPxRect.Left() - mnBorderPxWidth;
5362     aBorderPxRect.Top() = aBorderPxRect.Top() - mnBorderPxWidth;
5363     aBorderPxRect.Right() = aBorderPxRect.Right() + mnBorderPxWidth;
5364     aBorderPxRect.Bottom() = aBorderPxRect.Bottom() + mnBorderPxWidth;
5365 
5366     AddSidebarBorders(aBorderPxRect,_pViewShell, bRightSidebar, true);
5367 
5368     _orBorderRect =
5369             SwRect( _pViewShell->GetOut()->PixelToLogic( aBorderPxRect ) );
5370 }
5371 
5372 /** determine rectangle for right page shadow
5373 
5374     OD 12.02.2003 for #i9719# and #105645#
5375 
5376     @author OD
5377 */
GetRightShadowRect(const SwRect & _rPageRect,ViewShell * _pViewShell,SwRect & _orRightShadowRect,bool bRightSidebar)5378 /*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect,
5379                                                ViewShell*    _pViewShell,
5380                                                SwRect&       _orRightShadowRect,
5381                                                bool bRightSidebar )
5382 {
5383     SwRect aAlignedPageRect( _rPageRect );
5384     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5385     Rectangle aPagePxRect =
5386             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5387 
5388     Rectangle aRightShadowPxRect(
5389                     aPagePxRect.Right() + mnShadowPxWidth,
5390                     aPagePxRect.Top() + 1,
5391                     aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5392                     aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5393 
5394     if ( bRightSidebar )
5395         AddSidebarBorders(aRightShadowPxRect,_pViewShell, bRightSidebar, true);
5396 
5397     _orRightShadowRect =
5398             SwRect( _pViewShell->GetOut()->PixelToLogic( aRightShadowPxRect ) );
5399 }
5400 
5401 /** determine rectangle for bottom page shadow
5402 
5403     OD 12.02.2003 for #i9719# and #105645#
5404 
5405     @author OD
5406 */
GetBottomShadowRect(const SwRect & _rPageRect,ViewShell * _pViewShell,SwRect & _orBottomShadowRect,bool bRightSidebar)5407 /*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect,
5408                                                 ViewShell*    _pViewShell,
5409                                                 SwRect&       _orBottomShadowRect,
5410                                                 bool bRightSidebar )
5411 {
5412     SwRect aAlignedPageRect( _rPageRect );
5413     ::SwAlignRect( aAlignedPageRect, _pViewShell );
5414     Rectangle aPagePxRect =
5415             _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5416 
5417     Rectangle aBottomShadowPxRect(
5418                     aPagePxRect.Left() + 1,
5419                     aPagePxRect.Bottom() + mnShadowPxWidth,
5420                     aPagePxRect.Right() + mnBorderPxWidth + mnShadowPxWidth,
5421                     aPagePxRect.Bottom() + mnBorderPxWidth + mnShadowPxWidth );
5422 
5423     AddSidebarBorders(aBottomShadowPxRect,_pViewShell, bRightSidebar, true);
5424 
5425     _orBottomShadowRect =
5426             SwRect( _pViewShell->GetOut()->PixelToLogic( aBottomShadowPxRect ) );
5427 }
5428 
5429 /** paint page border and shadow
5430 
5431     OD 12.02.2003 for #i9719# and #105645#
5432     implement paint of page border and shadow
5433 
5434     @author OD
5435 */
PaintBorderAndShadow(const SwRect & _rPageRect,ViewShell * _pViewShell,bool bPaintRightShadow,bool bRightSidebar)5436 /*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect,
5437                                                  ViewShell*    _pViewShell,
5438                                                  bool bPaintRightShadow,
5439                                                  bool bRightSidebar )
5440 {
5441     // --> FME 2004-06-24 #i16816# tagged pdf support
5442     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() );
5443     // <--
5444 
5445     // get color for page border and shadow paint
5446     const Color& rColor = SwViewOption::GetFontColor();
5447 
5448     // save current fill and line color of output device
5449     Color aFill( _pViewShell->GetOut()->GetFillColor() );
5450     Color aLine( _pViewShell->GetOut()->GetLineColor() );
5451 
5452     // paint page border
5453     _pViewShell->GetOut()->SetFillColor(); // OD 20.02.2003 #107369# - no fill color
5454     _pViewShell->GetOut()->SetLineColor( rColor );
5455     SwRect aPaintRect;
5456     SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5457     _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5458 
5459     // paint right shadow
5460 //  if ( bPaintRightShadow )
5461 //  {
5462 //      _pViewShell->GetOut()->SetFillColor( rColor );
5463 //      SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5464 //      _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5465 //  }
5466 
5467     // paint bottom shadow
5468 //  SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
5469 //  _pViewShell->GetOut()->DrawRect( aPaintRect.SVRect() );
5470 
5471 //  _pViewShell->GetOut()->SetFillColor( aFill );
5472 //  _pViewShell->GetOut()->SetLineColor( aLine );
5473 }
5474 
5475 //mod #i6193# paint sidebar for notes
5476 //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit
PaintNotesSidebar(const SwRect & _rPageRect,ViewShell * _pViewShell,sal_uInt16 nPageNum,bool bRight)5477 /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight)
5478 {
5479     //TODO: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons
5480     if (!_pViewShell )
5481         return;
5482 
5483     SwRect aPageRect( _rPageRect );
5484     SwAlignRect( aPageRect, _pViewShell );
5485 
5486     const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
5487     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())  // do not show anything in print preview
5488     {
5489         sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight();
5490         const Rectangle &aVisRect = _pViewShell->VisArea().SVRect();
5491         //draw border and sidepane
5492         _pViewShell->GetOut()->SetLineColor();
5493         if (!bRight)
5494         {
5495             _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5496             _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height())))    ;
5497             if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5498                 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5499             else
5500                 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5501             _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height())))  ;
5502         }
5503         else
5504         {
5505             _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
5506             SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()));
5507             _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect());
5508             if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5509                 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5510             else
5511                 _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
5512             SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()));
5513             _pViewShell->GetOut()->DrawRect(aSidebar.SVRect());
5514         }
5515         if (pMgr->ShowScrollbar(nPageNum))
5516         {
5517             // draw scrollbar area and arrows
5518             Point aPointBottom;
5519             Point aPointTop;
5520             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()) :
5521                                     Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height());
5522             aPointTop = !bRight ?    Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) :
5523                                 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height());
5524             Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ;
5525             Rectangle aRectBottom(aPointBottom,aSize);
5526             Rectangle aRectTop(aPointTop,aSize);
5527 
5528             if (aRectBottom.IsOver(aVisRect))
5529             {
5530 
5531                 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5532                 {
5533                     _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5534                     _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5535                 }
5536                 else
5537                 {
5538                     _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5539                     _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5540                 }
5541                 _pViewShell->GetOut()->DrawRect(aRectBottom);
5542                 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5543 
5544                 _pViewShell->GetOut()->SetLineColor();
5545                 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5546                 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5547                 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5548             }
5549             if (aRectTop.IsOver(aVisRect))
5550             {
5551                 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
5552                 {
5553                     _pViewShell->GetOut()->SetLineColor(COL_WHITE);
5554                     _pViewShell->GetOut()->SetFillColor(COL_BLACK);
5555                 }
5556                 else
5557                 {
5558                     _pViewShell->GetOut()->SetLineColor(COL_BLACK);
5559                     _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
5560                 }
5561                 _pViewShell->GetOut()->DrawRect(aRectTop);
5562                 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
5563 
5564                 _pViewShell->GetOut()->SetLineColor();
5565                 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5566                 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
5567                 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
5568             }
5569         }
5570     }
5571 }
5572 
PaintNotesSidebarArrows(const Point & aMiddleFirst,const Point & aMiddleSecond,ViewShell * _pViewShell,const Color aColorUp,const Color aColorDown)5573 /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown)
5574 {
5575     Polygon aTriangleUp(3);
5576     Polygon aTriangleDown(3);
5577 
5578     aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5579     aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1);
5580     aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5581 
5582     aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
5583     aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1);
5584     aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
5585 
5586     _pViewShell->GetOut()->SetFillColor(aColorUp);
5587     _pViewShell->GetOut()->DrawPolygon(aTriangleUp);
5588     _pViewShell->GetOut()->SetFillColor(aColorDown);
5589     _pViewShell->GetOut()->DrawPolygon(aTriangleDown);
5590 }
5591 
5592 /** get bound rectangle of border and shadow for repaints
5593 
5594     OD 12.02.2003 for #i9719# and #105645#
5595 
5596     author OD
5597 */
GetBorderAndShadowBoundRect(const SwRect & _rPageRect,ViewShell * _pViewShell,SwRect & _orBorderAndShadowBoundRect,bool bRightSidebar)5598 /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect,
5599                                                         ViewShell*    _pViewShell,
5600                                                         SwRect& _orBorderAndShadowBoundRect,
5601                                                         bool bRightSidebar )
5602 {
5603     SwRect aTmpRect;
5604     SwPageFrm::GetBorderRect( _rPageRect, _pViewShell, _orBorderAndShadowBoundRect, bRightSidebar );
5605     SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5606     _orBorderAndShadowBoundRect.Union( aTmpRect );
5607     SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
5608     _orBorderAndShadowBoundRect.Union( aTmpRect );
5609 
5610     AddSidebarBorders(_orBorderAndShadowBoundRect, _pViewShell, bRightSidebar, false);
5611 }
5612 
AddSidebarBorders(SwRect & aRect,ViewShell * _pViewShell,bool bRightSidebar,bool bPx)5613 /*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5614 {
5615     const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5616     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5617     {
5618         if (!bRightSidebar)
5619             aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5620         else
5621             aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5622     }
5623 }
5624 
AddSidebarBorders(Rectangle & aRect,ViewShell * _pViewShell,bool bRightSidebar,bool bPx)5625 /*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
5626 {
5627     const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5628     if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5629     {
5630         if (!bRightSidebar)
5631             aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
5632         else
5633             aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx);
5634     }
5635 }
5636 
GetSidebarBorderWidth(const ViewShell * _pViewShell)5637 /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell )
5638 {
5639     const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
5640     const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
5641     return nRet;
5642 }
5643 
5644 /*************************************************************************
5645 |*
5646 |*  SwFrm::PaintBaBo()
5647 |*
5648 |*  Ersterstellung      MA 22. Oct. 93
5649 |*  Letzte Aenderung    MA 19. Jun. 96
5650 |*
5651 |*************************************************************************/
5652 
PaintBaBo(const SwRect & rRect,const SwPageFrm * pPage,const sal_Bool bLowerBorder) const5653 void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage,
5654                        const sal_Bool bLowerBorder ) const
5655 {
5656     if ( !pPage )
5657         pPage = FindPageFrm();
5658 
5659     OutputDevice *pOut = pGlobalShell->GetOut();
5660 
5661     // --> FME 2004-06-24 #i16816# tagged pdf support
5662     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
5663     // <--
5664 
5665     // OD 2004-04-23 #116347#
5666     pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
5667     pOut->SetLineColor();
5668 
5669     SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
5670     const SwBorderAttrs &rAttrs = *aAccess.Get();
5671 
5672     // OD 20.11.2002 #104598# - take care of page margin area
5673     // Note: code move from <SwFrm::PaintBackground(..)> to new method
5674     // <SwPageFrm::Paintmargin(..)>.
5675     if ( IsPageFrm() )
5676     {
5677         static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell );
5678     }
5679 
5680     // OD 06.08.2002 #99657# - paint border before painting background
5681     // paint grid for page frame and paint border
5682     {
5683         SwRect aRect( rRect );
5684         if( IsPageFrm() )
5685             ((SwPageFrm*)this)->PaintGrid( pOut, aRect );
5686         PaintBorder( aRect, pPage, rAttrs );
5687     }
5688 
5689     // paint background
5690     {
5691         PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder );
5692     }
5693 
5694     pOut->Pop();
5695 }
5696 
5697 /*************************************************************************
5698 |*
5699 |*  SwFrm::PaintBackground()
5700 |*
5701 |*  Ersterstellung      MA 04. Jan. 93
5702 |*  Letzte Aenderung    MA 06. Feb. 97
5703 |*
5704 |*************************************************************************/
5705 /// OD 05.09.2002 #102912#
5706 /// Do not paint background for fly frames without a background brush by
5707 /// calling <PaintBaBo> at the page or at the fly frame its anchored
PaintBackground(const SwRect & rRect,const SwPageFrm * pPage,const SwBorderAttrs & rAttrs,const sal_Bool bLowerMode,const sal_Bool bLowerBorder) const5708 void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
5709                              const SwBorderAttrs & rAttrs,
5710                              const sal_Bool bLowerMode,
5711                              const sal_Bool bLowerBorder ) const
5712 {
5713     // OD 20.01.2003 #i1837# - no paint of table background, if corresponding
5714     // option is *not* set.
5715     if( IsTabFrm() &&
5716         !pGlobalShell->GetViewOptions()->IsTable() )
5717     {
5718         return;
5719     }
5720 
5721     // nothing to do for covered table cells:
5722     if( IsCellFrm() && IsCoveredCell() )
5723         return;
5724 
5725     ViewShell *pSh = pGlobalShell;
5726 
5727     // --> FME 2004-06-24 #i16816# tagged pdf support
5728     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
5729     // <--
5730 
5731     const SvxBrushItem* pItem;
5732     /// OD 05.09.2002 #102912#
5733     /// temporary background brush for a fly frame without a background brush
5734     SvxBrushItem* pTmpBackBrush = 0;
5735     const Color* pCol;
5736     SwRect aOrigBackRect;
5737     const sal_Bool bPageFrm = IsPageFrm();
5738     sal_Bool bLowMode = sal_True;
5739 
5740     sal_Bool bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, bLowerMode );
5741     //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird.
5742     bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm();
5743     if ( bNoFlyBackground )
5744     {
5745         // OD 05.09.2002 #102912# - Fly frame has no background.
5746         // Try to find background brush at parents, if previous call of
5747         // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode>
5748         if ( bLowerMode )
5749         {
5750             bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, false );
5751         }
5752         // If still no background found for the fly frame, initialize the
5753         // background brush <pItem> with global retouche color and set <bBack>
5754         // to sal_True, that fly frame will paint its background using this color.
5755         if ( !bBack )
5756         {
5757             // OD 10.01.2003 #i6467# - on print output, pdf output and
5758             // in embedded mode not editing color COL_WHITE is used instead of
5759             // the global retouche color.
5760             if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
5761                  pSh->GetViewOptions()->IsPDFExport() ||
5762                  ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED &&
5763                    !pSh->GetDoc()->GetDocShell()->IsInPlaceActive()
5764                  )
5765                )
5766             {
5767                 pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND );
5768             }
5769             else
5770             {
5771                 pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND);
5772             }
5773             pItem = pTmpBackBrush;
5774             bBack = true;
5775         }
5776     }
5777 
5778     SwRect aPaintRect( Frm() );
5779     if( IsTxtFrm() || IsSctFrm() )
5780         aPaintRect = UnionFrm( sal_True );
5781 
5782     if ( aPaintRect.IsOver( rRect ) )
5783     {
5784         if ( bBack || bPageFrm || !bLowerMode )
5785         {
5786             const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode();
5787             SwRect aRect;
5788             if ( (bPageFrm && bBrowse) ||
5789                  (IsTxtFrm() && Prt().SSize() == Frm().SSize()) )
5790             {
5791                 aRect = Frm();
5792                 ::SwAlignRect( aRect, pGlobalShell );
5793             }
5794             else
5795             {
5796                 ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_False );
5797                 if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() )
5798                 {
5799                     if ( GetPrev()->GetAttrSet()->GetBackground() ==
5800                          GetAttrSet()->GetBackground() )
5801                     {
5802                         aRect.Top( Frm().Top() );
5803                     }
5804                 }
5805             }
5806             aRect.Intersection( rRect );
5807 
5808             OutputDevice *pOut = pSh->GetOut();
5809 
5810             if ( aRect.HasArea() )
5811             {
5812                 SvxBrushItem* pNewItem = 0;
5813                 SwRegionRects aRegion( aRect );
5814                 if( pCol )
5815                 {
5816                     pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND );
5817                     pItem = pNewItem;
5818                 }
5819                 if ( pPage->GetSortedObjs() )
5820                     ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
5821 
5822                 {
5823                     /// OD 06.08.2002 #99657# - determine, if background transparency
5824                     ///     have to be considered for drawing.
5825                     ///     --> Status Quo: background transparency have to be
5826                     ///        considered for fly frames
5827                     const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm();
5828                     for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
5829                     {
5830                         if ( 1 < aRegion.Count() )
5831                         {
5832                             ::SwAlignRect( aRegion[i], pGlobalShell );
5833                             if( !aRegion[i].HasArea() )
5834                                 continue;
5835                         }
5836                         /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if
5837                         ///     background transparency have to be considered
5838                         ///     Set missing 5th parameter to the default value GRFNUM_NO
5839                         ///         - see declaration in /core/inc/frmtool.hxx.
5840                         ::DrawGraphic( pItem, pOut, aOrigBackRect, aRegion[i], GRFNUM_NO,
5841                                 bConsiderBackgroundTransparency );
5842                     }
5843                 }
5844                 if( pCol )
5845                     delete pNewItem;
5846             }
5847         }
5848         else
5849             bLowMode = bLowerMode ? sal_True : sal_False;
5850     }
5851 
5852     /// OD 05.09.2002 #102912#
5853     /// delete temporary background brush.
5854     delete pTmpBackBrush;
5855 
5856     //Jetzt noch Lower und dessen Nachbarn.
5857     //Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist
5858     //so hoert der Spass auf.
5859     const SwFrm *pFrm = GetLower();
5860     if ( pFrm )
5861     {
5862         SwRect aFrmRect;
5863         SwRect aRect( PaintArea() );
5864         aRect._Intersection( rRect );
5865         SwRect aBorderRect( aRect );
5866         SwShortCut aShortCut( *pFrm, aBorderRect );
5867         do
5868         {   if ( pProgress )
5869                 pProgress->Reschedule();
5870 
5871             aFrmRect = pFrm->PaintArea();
5872             if ( aFrmRect.IsOver( aBorderRect ) )
5873             {
5874                 SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
5875                 const SwBorderAttrs &rTmpAttrs = *aAccess.Get();
5876                 /// OD 06.08.2002 #99657# - paint border before painting background
5877                 if ( bLowerBorder )
5878                     pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs );
5879                 if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) ||
5880                      aFrmRect.IsOver( aRect ) )
5881                     pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode,
5882                                            bLowerBorder );
5883             }
5884             pFrm = pFrm->GetNext();
5885         } while ( pFrm && pFrm->GetUpper() == this &&
5886                   !aShortCut.Stop( aFrmRect ) );
5887     }
5888 }
5889 
5890 /*************************************************************************
5891 |*
5892 |*  SwPageFrm::RefreshSubsidiary()
5893 |*
5894 |*  Beschreibung        Erneuert alle Hilfslinien der Seite.
5895 |*  Ersterstellung      MA 04. Nov. 92
5896 |*  Letzte Aenderung    MA 10. May. 95
5897 |*
5898 |*************************************************************************/
5899 
RefreshSubsidiary(const SwRect & rRect) const5900 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
5901 {
5902     if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS )
5903     {
5904         SwRect aRect( rRect );
5905         // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of
5906         // the output rectangle.
5907         //::SwAlignRect( aRect, pGlobalShell );
5908         if ( aRect.HasArea() )
5909         {
5910             //Beim Paint ueber die Root wird das Array von dort gesteuert.
5911             //Anderfalls kuemmern wir uns selbst darum.
5912             sal_Bool bDelSubs = sal_False;
5913             if ( !pSubsLines )
5914             {
5915                 pSubsLines = new SwSubsRects;
5916                 // OD 20.12.2002 #106318# - create container for special subsidiary lines
5917                 pSpecSubsLines = new SwSubsRects;
5918                 bDelSubs = sal_True;
5919             }
5920 
5921             RefreshLaySubsidiary( this, aRect );
5922 
5923             if ( bDelSubs )
5924             {
5925                 // OD 20.12.2002 #106318# - paint special subsidiary lines
5926                 // and delete its container
5927                 pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL );
5928                 DELETEZ( pSpecSubsLines );
5929 
5930                 pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines );
5931                 DELETEZ( pSubsLines );
5932             }
5933         }
5934     }
5935 }
5936 
5937 /*************************************************************************
5938 |*
5939 |*  SwLayoutFrm::RefreshLaySubsidiary()
5940 |*
5941 |*  Ersterstellung      MA 04. Nov. 92
5942 |*  Letzte Aenderung    MA 22. Jan. 95
5943 |*
5944 |*************************************************************************/
RefreshLaySubsidiary(const SwPageFrm * pPage,const SwRect & rRect) const5945 void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage,
5946                                         const SwRect &rRect ) const
5947 {
5948     const sal_Bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm();
5949     const sal_Bool bSubsOpt   = IS_SUBS;
5950     const sal_Bool bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE);
5951     const sal_Bool bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt;
5952     const sal_Bool bSubsSect  = IsSctFrm() &&
5953                                 bNoLowerColumn &&
5954                                 IS_SUBS_SECTION;
5955     const sal_Bool bSubsFly   = IS_SUBS_FLYS &&
5956                                 (GetType() & FRM_FLY) &&
5957                                 bNoLowerColumn &&
5958                                 (!Lower() || !Lower()->IsNoTxtFrm() ||
5959                                  !((SwNoTxtFrm*)Lower())->HasAnimation());
5960     sal_Bool bSubsBody = sal_False;
5961     if ( GetType() & FRM_BODY )
5962     {
5963         if ( IsPageBodyFrm() )
5964             bSubsBody = bSubsOpt && bNoLowerColumn;                                 //nur ohne Spalten
5965         else    //Spaltenbody
5966         {
5967             if ( GetUpper()->GetUpper()->IsSctFrm() )
5968                 bSubsBody = IS_SUBS_SECTION;
5969             else
5970                 bSubsBody = bSubsOpt;
5971         }
5972     }
5973 
5974     if ( bSubsOther || bSubsSect  || bSubsBody || bSubsTable || bSubsFly )
5975         PaintSubsidiaryLines( pPage, rRect );
5976 
5977     const SwFrm *pLow = Lower();
5978     if( !pLow )
5979         return;
5980     SwShortCut aShortCut( *pLow, rRect );
5981     while( pLow && !aShortCut.Stop( pLow->Frm() ) )
5982     {
5983         if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() )
5984         {
5985             if ( pLow->IsLayoutFrm() )
5986                 ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect);
5987             else if ( pLow->GetDrawObjs() )
5988             {
5989                 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs());
5990                 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
5991                 {
5992                     const SwAnchoredObject* pAnchoredObj = rObjs[i];
5993                     if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
5994                                     pAnchoredObj->GetDrawObj()->GetLayer() ) &&
5995                          pAnchoredObj->ISA(SwFlyFrm) )
5996                     {
5997                         const SwFlyFrm *pFly =
5998                                     static_cast<const SwFlyFrm*>(pAnchoredObj);
5999                         if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) )
6000                         {
6001                             if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
6002                                  !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
6003                                 pFly->RefreshLaySubsidiary( pPage, rRect );
6004                         }
6005                     }
6006                 }
6007             }
6008         }
6009         pLow = pLow->GetNext();
6010     }
6011 }
6012 
6013 /*************************************************************************
6014 |*
6015 |*  SwLayoutFrm::PaintSubsidiaryLines()
6016 |*
6017 |*  Beschreibung        Hilfslinien um die PrtAreas malen
6018 |*      Nur die LayoutFrm's die direkt Cntnt enthalten.
6019 |*  Ersterstellung      MA 21. May. 92
6020 |*  Letzte Aenderung    MA 22. Jan. 95
6021 |*
6022 |*************************************************************************/
6023 
6024 //Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden.
6025 
6026 typedef long Size::* SizePtr;
6027 typedef long Point::* PointPtr;
6028 
6029 PointPtr pX = &Point::nA;
6030 PointPtr pY = &Point::nB;
6031 SizePtr pWidth = &Size::nA;
6032 SizePtr pHeight = &Size::nB;
6033 
6034 // OD 18.11.2002 #99672# - new parameter <_pSubsLines>
lcl_RefreshLine(const SwLayoutFrm * pLay,const SwPageFrm * pPage,const Point & rP1,const Point & rP2,const sal_uInt8 nSubColor,SwLineRects * _pSubsLines)6035 void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay,
6036                                   const SwPageFrm *pPage,
6037                                   const Point &rP1,
6038                                   const Point &rP2,
6039                                   const sal_uInt8 nSubColor,
6040                                   SwLineRects* _pSubsLines )
6041 {
6042     //In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein.
6043     ASSERT( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
6044             "Schraege Hilfslinien sind nicht erlaubt." );
6045     const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX;
6046     const PointPtr pOthPt = pDirPt == pX ? pY : pX;
6047     const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight;
6048     const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth;
6049     Point aP1( rP1 ),
6050           aP2( rP2 );
6051 
6052     while ( aP1.*pDirPt < aP2.*pDirPt )
6053     {   //Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt
6054         //hinter den Fly gesetzt.
6055         //Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt
6056         //ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen.
6057         //Auf diese art und weise wird eine Portion nach der anderen
6058         //ausgegeben.
6059 
6060         //Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus,
6061         //die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen.
6062         //Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche
6063         //ich keinem dieser Flys aus.
6064         SwOrderIter aIter( pPage );
6065         const SwFlyFrm *pMyFly = pLay->FindFlyFrm();
6066         if ( pMyFly )
6067         {
6068             aIter.Current( pMyFly->GetVirtDrawObj() );
6069             while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) )
6070             {
6071                 if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
6072                     aIter.Current( pMyFly->GetVirtDrawObj() );
6073             }
6074         }
6075         else
6076             aIter.Bottom();
6077 
6078         while ( aIter() )
6079         {
6080             const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
6081             const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
6082 
6083             //Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich
6084             //_in_ dem Fly sitze weiche ich nicht aus.
6085             if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
6086             {
6087                 aIter.Next();
6088                 continue;
6089             }
6090 
6091             // OD 19.12.2002 #106318# - do *not* consider fly frames with
6092             // a transparent background.
6093             // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which
6094             // belongs to a invisible layer
6095             if ( pFly->IsBackgroundTransparent() ||
6096                  !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) )
6097             {
6098                 aIter.Next();
6099                 continue;
6100             }
6101 
6102             //Sitzt das Obj auf der Linie
6103             const Rectangle &rBound = pObj->GetCurrentBoundRect();
6104             const Point aDrPt( rBound.TopLeft() );
6105             const Size  aDrSz( rBound.GetSize() );
6106             if ( rP1.*pOthPt >= aDrPt.*pOthPt &&
6107                  rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) )
6108             {
6109                 if ( aP1.*pDirPt >= aDrPt.*pDirPt &&
6110                      aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) )
6111                     aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz;
6112 
6113                 if ( aP2.*pDirPt >= aDrPt.*pDirPt &&
6114                      aP1.*pDirPt < (aDrPt.*pDirPt - 1) )
6115                     aP2.*pDirPt = aDrPt.*pDirPt - 1;
6116             }
6117             aIter.Next();
6118         }
6119 
6120         if ( aP1.*pDirPt < aP2.*pDirPt )
6121         {
6122             SwRect aRect( aP1, aP2 );
6123             // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of
6124             // global variable <pSubsLines>.
6125             _pSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6126         }
6127         aP1 = aP2;
6128         aP1.*pDirPt += 1;
6129         aP2 = rP2;
6130     }
6131 }
6132 
PaintSubsidiaryLines(const SwPageFrm * pPage,const SwRect & rRect) const6133 void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage,
6134                                         const SwRect &rRect ) const
6135 {
6136     bool bNewTableModel = false;
6137 
6138     // --> collapsing borders FME 2005-05-27 #i29550#
6139     if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
6140     {
6141         const SwTabFrm* pTabFrm = FindTabFrm();
6142         if ( pTabFrm->IsCollapsingBorders() )
6143             return;
6144 
6145         bNewTableModel = pTabFrm->GetTable()->IsNewModel();
6146         // in the new table model, we have an early return for all cell-related
6147         // frames, except from non-covered table cells
6148         if ( bNewTableModel )
6149             if ( IsTabFrm() ||
6150                  IsRowFrm() ||
6151                  ( IsCellFrm() && IsCoveredCell() ) )
6152                 return;
6153     }
6154     // <-- collapsing
6155 
6156     const bool bFlys = pPage->GetSortedObjs() ? true : false;
6157 
6158     const bool bCell = IsCellFrm() ? true : false;
6159     // use frame area for cells
6160     // OD 13.02.2003 #i3662# - for section use also frame area
6161     const bool bUseFrmArea = bCell || IsSctFrm();
6162     SwRect aOriginal( bUseFrmArea ? Frm() : Prt() );
6163     if ( !bUseFrmArea )
6164         aOriginal.Pos() += Frm().Pos();
6165 
6166     // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area
6167     // in sections to top of section frame.
6168     const bool bColBodyInSection = IsBodyFrm() &&
6169                                    !IsPageBodyFrm() &&
6170                                    GetUpper()->GetUpper()->IsSctFrm();
6171     if ( bColBodyInSection )
6172     {
6173         if ( IsVertical() )
6174             aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() );
6175         else
6176             aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() );
6177     }
6178 
6179     ::SwAlignRect( aOriginal, pGlobalShell );
6180 
6181     if ( !aOriginal.IsOver( rRect ) )
6182         return;
6183 
6184     SwRect aOut( aOriginal );
6185     aOut._Intersection( rRect );
6186     // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's
6187     // printing area with the paint area of the body frame. Otherwise enlargement
6188     // will get lost.
6189     if ( !bColBodyInSection )
6190     {
6191         aOut.Intersection( PaintArea() );
6192     }
6193 
6194     const SwTwips nRight = aOut.Right();
6195     const SwTwips nBottom= aOut.Bottom();
6196 
6197     const Point aRT( nRight, aOut.Top() );
6198     const Point aRB( nRight, nBottom );
6199     const Point aLB( aOut.Left(), nBottom );
6200 
6201     sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB :
6202                      ( IsInSct() ? SUBCOL_SECT :
6203                      ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
6204 
6205     // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks.
6206     sal_Bool bBreak = sal_False;
6207     if ( IsBodyFrm() )
6208     {
6209         const SwCntntFrm *pCnt = ContainsCntnt();
6210         if ( pCnt )
6211         {
6212             // OD 05.11.2002 #102406# - adjust setting of <bBreak>.
6213             bBreak = pCnt->IsPageBreak( sal_True ) ||
6214                      ( IsColBodyFrm() && pCnt->IsColBreak( sal_True ) );
6215         }
6216     }
6217 
6218     // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section
6219     // sub-lines in <pSpecSubsLine> array.
6220     const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() ||
6221                                   IsFtnFrm() || IsSctFrm();
6222     SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines;
6223 
6224     // NOTE: for cell frames only left and right (horizontal layout) respectively
6225     //      top and bottom (vertical layout) lines painted.
6226     // NOTE2: this does not hold for the new table model!!! We paint the top border
6227     // of each non-covered table cell.
6228     const bool bVert = IsVertical() ? true : false;
6229     if ( bFlys )
6230     {
6231         // OD 14.11.2002 #104822# - add control for drawing left and right lines
6232         if ( !bCell || bNewTableModel || !bVert )
6233         {
6234             if ( aOriginal.Left() == aOut.Left() )
6235                 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor,
6236                                    pUsedSubsLines );
6237             // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6238             if ( aOriginal.Right() == nRight )
6239                 ::lcl_RefreshLine( this, pPage, aRT, aRB,
6240                                    (bBreak && bVert) ? SUBCOL_BREAK : nSubColor,
6241                                    pUsedSubsLines );
6242         }
6243         // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6244         if ( !bCell || bNewTableModel || bVert )
6245         {
6246             if ( aOriginal.Top() == aOut.Top() )
6247                 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6248                 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT,
6249                                    (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor,
6250                                    pUsedSubsLines );
6251             if ( aOriginal.Bottom() == nBottom )
6252                 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor,
6253                                    pUsedSubsLines );
6254         }
6255     }
6256     else
6257     {
6258         // OD 14.11.2002 #104822# - add control for drawing left and right lines
6259         if ( !bCell || bNewTableModel || !bVert )
6260         {
6261             if ( aOriginal.Left() == aOut.Left() )
6262             {
6263                 const SwRect aRect( aOut.Pos(), aLB );
6264                 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6265             }
6266             // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
6267             if ( aOriginal.Right() == nRight )
6268             {
6269                 const SwRect aRect( aRT, aRB );
6270                 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6271                         (bBreak && bVert) ? SUBCOL_BREAK : nSubColor );
6272             }
6273         }
6274         // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
6275         if ( !bCell || bNewTableModel || bVert )
6276         {
6277             if ( aOriginal.Top() == aOut.Top() )
6278             {
6279                 // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
6280                 const SwRect aRect( aOut.Pos(), aRT );
6281                 pUsedSubsLines->AddLineRect( aRect, 0, 0,
6282                         (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor );
6283             }
6284             if ( aOriginal.Bottom() == nBottom )
6285             {
6286                 const SwRect aRect( aLB, aRB );
6287                 pUsedSubsLines->AddLineRect( aRect, 0, 0, nSubColor );
6288             }
6289         }
6290     }
6291 }
6292 
6293 /*************************************************************************
6294 |*
6295 |*  SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData()
6296 |*
6297 |*  Beschreibung        Erneuert alle Extradaten (Zeilennummern usw) der Seite.
6298 |*                      Grundsaetzlich sind nur diejenigen Objekte beruecksichtig,
6299 |*                      die in die seitliche Ausdehnung des Rects ragen.
6300 |*  Ersterstellung      MA 20. Jan. 98
6301 |*  Letzte Aenderung    MA 18. Feb. 98
6302 |*
6303 |*************************************************************************/
6304 
RefreshExtraData(const SwRect & rRect) const6305 void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const
6306 {
6307     const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6308     sal_Bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys())
6309         || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE;
6310 
6311     SwRect aRect( rRect );
6312     ::SwAlignRect( aRect, pGlobalShell );
6313     if ( aRect.HasArea() )
6314     {
6315         SwLayoutFrm::RefreshExtraData( aRect );
6316 
6317         if ( bLineInFly && GetSortedObjs() )
6318             for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i )
6319             {
6320                 const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
6321                 if ( pAnchoredObj->ISA(SwFlyFrm) )
6322                 {
6323                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6324                     if ( pFly->Frm().Top() <= aRect.Bottom() &&
6325                          pFly->Frm().Bottom() >= aRect.Top() )
6326                         pFly->RefreshExtraData( aRect );
6327                 }
6328             }
6329     }
6330 }
6331 
RefreshExtraData(const SwRect & rRect) const6332 void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const
6333 {
6334 
6335     const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
6336     sal_Bool bLineInBody = rInfo.IsPaintLineNumbers(),
6337              bLineInFly  = bLineInBody && rInfo.IsCountInFlys(),
6338              bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE;
6339 
6340     const SwCntntFrm *pCnt = ContainsCntnt();
6341     while ( pCnt && IsAnLower( pCnt ) )
6342     {
6343         if ( pCnt->IsTxtFrm() && ( bRedLine ||
6344              ( !pCnt->IsInTab() &&
6345                ((bLineInBody && pCnt->IsInDocBody()) ||
6346                (bLineInFly  && pCnt->IsInFly())) ) ) &&
6347              pCnt->Frm().Top() <= rRect.Bottom() &&
6348              pCnt->Frm().Bottom() >= rRect.Top() )
6349         {
6350             ((SwTxtFrm*)pCnt)->PaintExtraData( rRect );
6351         }
6352         if ( bLineInFly && pCnt->GetDrawObjs() )
6353             for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i )
6354             {
6355                 const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i];
6356                 if ( pAnchoredObj->ISA(SwFlyFrm) )
6357                 {
6358                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
6359                     if ( pFly->IsFlyInCntFrm() &&
6360                          pFly->Frm().Top() <= rRect.Bottom() &&
6361                          pFly->Frm().Bottom() >= rRect.Top() )
6362                         pFly->RefreshExtraData( rRect );
6363                 }
6364         }
6365         pCnt = pCnt->GetNextCntntFrm();
6366     }
6367 }
6368 
6369 /** SwPageFrm::GetDrawBackgrdColor - for #102450#
6370 
6371     determine the color, that is respectively will be drawn as background
6372     for the page frame.
6373     Using existing method SwFrm::GetBackgroundBrush to determine the color
6374     that is set at the page frame respectively is parent. If none is found
6375     return the global retouche color
6376 
6377     @author OD
6378 
6379     @return Color
6380 */
GetDrawBackgrdColor() const6381 const Color& SwPageFrm::GetDrawBackgrdColor() const
6382 {
6383     const SvxBrushItem* pBrushItem;
6384     const Color* pDummyColor;
6385     SwRect aDummyRect;
6386 
6387     if ( GetBackgroundBrush( pBrushItem, pDummyColor, aDummyRect, true) )
6388     {
6389         const Graphic* pGraphic = pBrushItem->GetGraphic();
6390 
6391         if(pGraphic)
6392         {
6393             // #29105# when a graphic is set, it may be possible to calculate a single
6394             // color which looks good in all places of the graphic. Since it is
6395             // planned to have text edit on the overlay one day and the fallback
6396             // to aGlobalRetoucheColor returns something useful, just use that
6397             // for now.
6398         }
6399         else
6400         {
6401             // not a graphic, use (hopefully) initialized color
6402             return pBrushItem->GetColor();
6403         }
6404     }
6405 
6406     return aGlobalRetoucheColor;
6407 }
6408 
6409 /*************************************************************************
6410 |*
6411 |*    SwPageFrm::GetEmptyPageFont()
6412 |*
6413 |*    create/return font used to paint the "empty page" string
6414 |*
6415 |*************************************************************************/
6416 
GetEmptyPageFont()6417 const Font& SwPageFrm::GetEmptyPageFont()
6418 {
6419     static Font* pEmptyPgFont = 0;
6420     if ( 0 == pEmptyPgFont )
6421     {
6422         pEmptyPgFont = new Font;
6423         pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt
6424         pEmptyPgFont->SetWeight( WEIGHT_BOLD );
6425         pEmptyPgFont->SetStyleName( aEmptyStr );
6426         pEmptyPgFont->SetName( String::CreateFromAscii(
6427                 RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) );
6428         pEmptyPgFont->SetFamily( FAMILY_SWISS );
6429         pEmptyPgFont->SetTransparent( sal_True );
6430         pEmptyPgFont->SetColor( COL_GRAY );
6431     }
6432 
6433     return *pEmptyPgFont;
6434 }
6435 
6436 /*************************************************************************
6437 |*
6438 |*    SwFrm::Retouche
6439 |*
6440 |*    Beschreibung      Retouche fuer einen Bereich.
6441 |*      Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner
6442 |*      Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird
6443 |*      per PaintBackground gecleared.
6444 |*    Ersterstellung    MA 13. Apr. 93
6445 |*    Letzte Aenderung  MA 25. Jul. 96
6446 |*
6447 |*************************************************************************/
6448 
Retouche(const SwPageFrm * pPage,const SwRect & rRect) const6449 void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const
6450 {
6451     if ( bFlyMetafile )
6452         return;
6453 
6454     ASSERT( GetUpper(), "Retoucheversuch ohne Upper." );
6455     ASSERT( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" );
6456 
6457     SwRect aRetouche( GetUpper()->PaintArea() );
6458     aRetouche.Top( Frm().Top() + Frm().Height() );
6459     aRetouche.Intersection( pGlobalShell->VisArea() );
6460 
6461     if ( aRetouche.HasArea() )
6462     {
6463         //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region
6464         //zum ausstanzen.
6465         SwRegionRects aRegion( aRetouche );
6466         aRegion -= rRect;
6467         ViewShell *pSh = getRootFrm()->GetCurrShell();
6468 
6469         // --> FME 2004-06-24 #i16816# tagged pdf support
6470         SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
6471         // <--
6472 
6473         for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
6474         {
6475             SwRect &rRetouche = aRegion[i];
6476 
6477             GetUpper()->PaintBaBo( rRetouche, pPage, sal_True );
6478 
6479             //Hoelle und Himmel muessen auch refreshed werden.
6480             //Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst
6481             //zurueckgesetzt werden!
6482             ResetRetouche();
6483             SwRect aRetouchePart( rRetouche );
6484             if ( aRetouchePart.HasArea() )
6485             {
6486                 const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
6487                 const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6488                 // --> OD #i76669#
6489                 SwViewObjectContactRedirector aSwRedirector( *pSh );
6490                 // <--
6491 
6492                 pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0,
6493                                         aRetouchePart, &aPageBackgrdColor,
6494                                         (pPage->IsRightToLeft() ? true : false),
6495                                         &aSwRedirector );
6496                 pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0,
6497                                         aRetouchePart, &aPageBackgrdColor,
6498                                         (pPage->IsRightToLeft() ? true : false),
6499                                         &aSwRedirector );
6500             }
6501 
6502             SetRetouche();
6503 
6504             //Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier
6505             //leider die Hilfslinien erneuert werden.
6506             pPage->RefreshSubsidiary( aRetouchePart );
6507         }
6508     }
6509     if ( ViewShell::IsLstEndAction() )
6510         ResetRetouche();
6511 }
6512 
6513 /** SwFrm::GetBackgroundBrush
6514 
6515     @descr
6516     determine the background brush for the frame:
6517     the background brush is taken from it-self or from its parent (anchor/upper).
6518     Normally, the background brush is taken, which has no transparent color or
6519     which has a background graphic. But there are some special cases:
6520     (1) No background brush is taken from a page frame, if view option "IsPageBack"
6521         isn't set.
6522     (2) Background brush from a index section is taken under special conditions.
6523         In this case parameter <rpCol> is set to the index shading color.
6524     (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing
6525         of the frame transparency is considered and its color is not "no fill"/"auto fill"
6526     ---- old description in german:
6527     Beschreibung        Liefert die Backgroundbrush fuer den Bereich des
6528         des Frm. Die Brush wird entweder von ihm selbst oder von einem
6529         Upper vorgegeben, die erste Brush wird benutzt.
6530         Ist fuer keinen Frm eine Brush angegeben, so wird sal_False zurueck-
6531         geliefert.
6532     Ersterstellung      MA 23. Dec. 92
6533     Letzte Aenderung    MA 04. Feb. 97
6534 
6535     @param rpBrush
6536     output parameter - constant reference pointer the found background brush
6537 
6538     @param rpCol
6539     output parameter - constant reference pointer to the color of the index shading
6540     set under special conditions, if background brush is taken from an index section.
6541 
6542     @param rOrigRect
6543     in-/output parameter - reference to the retangle the background brush is
6544     considered for - adjusted to the frame, from which the background brush is
6545     taken.
6546 
6547     @parem bLowerMode
6548     input parameter - boolean indicating, if background brush should *not* be
6549     taken from parent.
6550 
6551     @author MA
6552     @change 20.08.2002 by OD
6553     @docdate 20.08.2002
6554 
6555     @return true, if a background brush for the frame is found
6556 */
GetBackgroundBrush(const SvxBrushItem * & rpBrush,const Color * & rpCol,SwRect & rOrigRect,sal_Bool bLowerMode) const6557 sal_Bool SwFrm::GetBackgroundBrush( const SvxBrushItem* & rpBrush,
6558                                 const Color*& rpCol,
6559                                 SwRect &rOrigRect,
6560                                 sal_Bool bLowerMode ) const
6561 {
6562     const SwFrm *pFrm = this;
6563     ViewShell *pSh = getRootFrm()->GetCurrShell();
6564     const SwViewOption *pOpt = pSh->GetViewOptions();
6565     rpBrush = 0;
6566     rpCol = NULL;
6567     do
6568     {   if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() )
6569             return sal_False;
6570 
6571         const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
6572         if( pFrm->IsSctFrm() )
6573         {
6574             const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
6575             /// OD 20.08.2002 #99657# #GetTransChg#
6576             ///     Note: If frame <pFrm> is a section of the index and
6577             ///         it its background color is "no fill"/"auto fill" and
6578             ///         it has no background graphic and
6579             ///         we are not in the page preview and
6580             ///         we are not in read-only mode and
6581             ///         option "index shadings" is set and
6582             ///         the output is not the printer
6583             ///         then set <rpCol> to the color of the index shading
6584             if( pSection && (   TOX_HEADER_SECTION == pSection->GetType() ||
6585                                 TOX_CONTENT_SECTION == pSection->GetType() ) &&
6586                 (rBack.GetColor() == COL_TRANSPARENT) &&
6587                 ///rBack.GetColor().GetTransparency() &&
6588                 rBack.GetGraphicPos() == GPOS_NONE &&
6589                 !pOpt->IsPagePreview() &&
6590                 !pOpt->IsReadonly() &&
6591                 // --> FME 2004-06-29 #114856# Formular view
6592                 !pOpt->IsFormView() &&
6593                 // <--
6594                 SwViewOption::IsIndexShadings() &&
6595                 !pOpt->IsPDFExport() &&
6596                 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
6597             {
6598                 rpCol = &SwViewOption::GetIndexShadingsColor();
6599             }
6600         }
6601 
6602         /// OD 20.08.2002 #99657#
6603         ///     determine, if background draw of frame <pFrm> considers transparency
6604         ///     --> Status Quo: background transparency have to be
6605         ///                     considered for fly frames
6606         const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm();
6607         /// OD 20.08.2002 #99657#
6608         ///     add condition:
6609         ///     If <bConsiderBackgroundTransparency> is set - see above -,
6610         ///     return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill"
6611         if ( !rBack.GetColor().GetTransparency() ||
6612              rBack.GetGraphicPos() != GPOS_NONE ||
6613              rpCol ||
6614              (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT))
6615            )
6616         {
6617             rpBrush = &rBack;
6618             if ( pFrm->IsPageFrm() &&
6619                  pSh->GetViewOptions()->getBrowseMode() )
6620                 rOrigRect = pFrm->Frm();
6621             else
6622             {
6623                 if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() )
6624                 {
6625                     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
6626                     const SwBorderAttrs &rAttrs = *aAccess.Get();
6627                     ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, sal_False );
6628                 }
6629                 else
6630                 {
6631                     rOrigRect = pFrm->Prt();
6632                     rOrigRect += pFrm->Frm().Pos();
6633                 }
6634             }
6635             return sal_True;
6636         }
6637 
6638         if ( bLowerMode )
6639             /// Do not try to get background brush from parent (anchor/upper)
6640             return sal_False;
6641 
6642         /// get parent frame - anchor or upper - for next loop
6643         if ( pFrm->IsFlyFrm() )
6644             /// OD 20.08.2002 - use "static_cast" instead of "old C-cast"
6645             pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm();
6646             ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
6647         else
6648             pFrm = pFrm->GetUpper();
6649 
6650     } while ( pFrm );
6651 
6652     return sal_False;
6653 }
6654 
6655 /*************************************************************************
6656 |*
6657 |*  SwFrmFmt::GetGraphic()
6658 |*
6659 |*  Ersterstellung      MA 23. Jul. 96
6660 |*  Letzte Aenderung    MA 23. Jul. 96
6661 |*
6662 |*************************************************************************/
6663 
SetOutDevAndWin(ViewShell * pSh,OutputDevice * pO,Window * pW,sal_uInt16 nZoom)6664 void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO,
6665                       Window *pW, sal_uInt16 nZoom )
6666 {
6667     pSh->pOut = pO;
6668     pSh->pWin = pW;
6669     pSh->pOpt->SetZoom( nZoom );
6670 }
6671 
MakeGraphic(ImageMap *)6672 Graphic SwFrmFmt::MakeGraphic( ImageMap* )
6673 {
6674     return Graphic();
6675 }
6676 
MakeGraphic(ImageMap * pMap)6677 Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap )
6678 {
6679     Graphic aRet;
6680     //irgendeinen Fly suchen!
6681     SwIterator<SwFrm,SwFmt> aIter( *this );
6682     SwFrm *pFirst = aIter.First();
6683     ViewShell *pSh;
6684     if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) )
6685     {
6686         ViewShell *pOldGlobal = pGlobalShell;
6687         pGlobalShell = pSh;
6688 
6689         sal_Bool bNoteURL = pMap &&
6690             SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, sal_True );
6691         if( bNoteURL )
6692         {
6693             ASSERT( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
6694             pNoteURL = new SwNoteURL;
6695         }
6696         SwFlyFrm *pFly = (SwFlyFrm*)pFirst;
6697 
6698         OutputDevice *pOld = pSh->GetOut();
6699         VirtualDevice aDev( *pOld );
6700         aDev.EnableOutput( sal_False );
6701 
6702         GDIMetaFile aMet;
6703         MapMode aMap( pOld->GetMapMode().GetMapUnit() );
6704         aDev.SetMapMode( aMap );
6705         aMet.SetPrefMapMode( aMap );
6706 
6707         ::SwCalcPixStatics( pSh->GetOut() );
6708         aMet.SetPrefSize( pFly->Frm().SSize() );
6709 
6710         aMet.Record( &aDev );
6711         aDev.SetLineColor();
6712         aDev.SetFillColor();
6713         aDev.SetFont( pOld->GetFont() );
6714 
6715         //Rechteck ggf. ausdehnen, damit die Umrandungen mit aufgezeichnet werden.
6716         SwRect aOut( pFly->Frm() );
6717         SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
6718         const SwBorderAttrs &rAttrs = *aAccess.Get();
6719         if ( rAttrs.CalcRightLine() )
6720             aOut.SSize().Width() += 2*nPixelSzW;
6721         if ( rAttrs.CalcBottomLine() )
6722             aOut.SSize().Height()+= 2*nPixelSzH;
6723 
6724         // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
6725         const Region aRepaintRegion(aOut.SVRect());
6726         pSh->DLPrePaint2(aRepaintRegion);
6727 
6728         Window *pWin = pSh->GetWin();
6729         sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom();
6730         ::SetOutDevAndWin( pSh, &aDev, 0, 100 );
6731         bFlyMetafile = sal_True;
6732         pFlyMetafileOut = pWin;
6733 
6734         SwViewImp *pImp = pSh->Imp();
6735         pFlyOnlyDraw = pFly;
6736         pLines = new SwLineRects;
6737 
6738         // OD 09.12.2002 #103045# - determine page, fly frame is on
6739         const SwPageFrm* pFlyPage = pFly->FindPageFrm();
6740         const Color aPageBackgrdColor = pFlyPage->GetDrawBackgrdColor();
6741         const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
6742         // --> OD #i76669#
6743         SwViewObjectContactRedirector aSwRedirector( *pSh );
6744         // <--
6745         pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor,
6746                           (pFlyPage->IsRightToLeft() ? true : false),
6747                           &aSwRedirector );
6748         pLines->PaintLines( &aDev );
6749         if ( pFly->IsFlyInCntFrm() )
6750             pFly->Paint( aOut );
6751         pLines->PaintLines( &aDev );
6752         /// OD 30.08.2002 #102450# - add 3rd parameter
6753         pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor,
6754                           (pFlyPage->IsRightToLeft() ? true : false),
6755                           &aSwRedirector );
6756         pLines->PaintLines( &aDev );
6757         DELETEZ( pLines );
6758         pFlyOnlyDraw = 0;
6759 
6760         pFlyMetafileOut = 0;
6761         bFlyMetafile = sal_False;
6762         ::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
6763 
6764         // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted
6765         pSh->DLPostPaint2(true);
6766 
6767         aMet.Stop();
6768         aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() );
6769         aRet = Graphic( aMet );
6770 
6771         if( bNoteURL )
6772         {
6773             ASSERT( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
6774             pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap );
6775             delete pNoteURL;
6776             pNoteURL = NULL;
6777         }
6778         pGlobalShell = pOldGlobal;
6779     }
6780     return aRet;
6781 }
6782 
MakeGraphic(ImageMap *)6783 Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* )
6784 {
6785     Graphic aRet;
6786     SdrModel *pMod = getIDocumentDrawModelAccess()->GetDrawModel();
6787     if ( pMod )
6788     {
6789         SdrObject *pObj = FindSdrObject();
6790         SdrView *pView = new SdrView( pMod );
6791         SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0));
6792         pView->MarkObj( pObj, pPgView );
6793         aRet = pView->GetMarkedObjBitmapEx();
6794         pView->HideSdrPage();
6795         delete pView;
6796     }
6797     return aRet;
6798 }
6799 
6800