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