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