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