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