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