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