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