Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/lazydelete.hxx>
21 : #include <vcl/gradient.hxx>
22 : #include <sfx2/docfile.hxx>
23 : #include <sfx2/progress.hxx>
24 : #include <editeng/brushitem.hxx>
25 : #include <editeng/opaqitem.hxx>
26 : #include <editeng/prntitem.hxx>
27 : #include <editeng/boxitem.hxx>
28 : #include <editeng/shaditem.hxx>
29 : #include <svx/framelink.hxx>
30 : #include <svx/xflgrit.hxx>
31 : #include <tgrditem.hxx>
32 : #include <switerator.hxx>
33 : #include <fmtsrnd.hxx>
34 : #include <fmtclds.hxx>
35 : #include <comcore.hrc>
36 : #include <swmodule.hxx>
37 : #include <rootfrm.hxx>
38 : #include <pagefrm.hxx>
39 : #include <section.hxx>
40 : #include <sectfrm.hxx>
41 : #include <viewimp.hxx>
42 : #include <dflyobj.hxx>
43 : #include <flyfrm.hxx>
44 : #include <frmtool.hxx>
45 : #include <viewopt.hxx>
46 : #include <dview.hxx>
47 : #include <dcontact.hxx>
48 : #include <txtfrm.hxx>
49 : #include <ftnfrm.hxx>
50 : #include <tabfrm.hxx>
51 : #include <rowfrm.hxx>
52 : #include <cellfrm.hxx>
53 : #include <notxtfrm.hxx>
54 : #include <layact.hxx>
55 : #include <pagedesc.hxx>
56 : #include <ptqueue.hxx>
57 : #include <noteurl.hxx>
58 : #include <virtoutp.hxx>
59 : #include <lineinfo.hxx>
60 : #include <dbg_lay.hxx>
61 : #include <docsh.hxx>
62 : #include <svx/svdogrp.hxx>
63 : #include <sortedobjs.hxx>
64 : #include <EnhancedPDFExportHelper.hxx>
65 : #include <bodyfrm.hxx>
66 : #include <hffrm.hxx>
67 : #include <colfrm.hxx>
68 : // --> OD #i76669#
69 : #include <svx/sdr/contact/viewobjectcontactredirector.hxx>
70 : #include <svx/sdr/contact/viewobjectcontact.hxx>
71 : #include <svx/sdr/contact/viewcontact.hxx>
72 : // <--
73 :
74 : #include <ndole.hxx>
75 : #include <svx/charthelper.hxx>
76 : #include <PostItMgr.hxx>
77 : #include <vcl/svapp.hxx>
78 : #include <vcl/settings.hxx>
79 :
80 : //UUUU
81 : #include <drawinglayer/processor2d/processor2dtools.hxx>
82 :
83 : #define COL_NOTES_SIDEPANE RGB_COLORDATA(230,230,230)
84 : #define COL_NOTES_SIDEPANE_BORDER RGB_COLORDATA(200,200,200)
85 : #define COL_NOTES_SIDEPANE_SCROLLAREA RGB_COLORDATA(230,230,220)
86 :
87 : #include <svtools/borderhelper.hxx>
88 :
89 : #include "pagefrm.hrc"
90 : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
91 : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
92 : #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
93 : #include <drawinglayer/primitive2d/discreteshadowprimitive2d.hxx>
94 : #include <drawinglayer/primitive2d/textprimitive2d.hxx>
95 : #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
96 : #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
97 : #include <svx/unoapi.hxx>
98 : #include <comphelper/sequenceasvector.hxx>
99 : #include <basegfx/matrix/b2dhommatrixtools.hxx>
100 : #include <basegfx/color/bcolortools.hxx>
101 :
102 : #include <vector>
103 : #include <algorithm>
104 : #include <wrtsh.hxx>
105 : #include <edtwin.hxx>
106 : #include <view.hxx>
107 :
108 : using namespace ::editeng;
109 : using namespace ::com::sun::star;
110 : using ::drawinglayer::primitive2d::BorderLinePrimitive2D;
111 : using ::std::pair;
112 : using ::std::make_pair;
113 :
114 : //other subsidiary lines enabled?
115 : #define IS_SUBS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
116 : !pGlobalShell->GetViewOptions()->IsReadonly() && \
117 : !pGlobalShell->GetViewOptions()->IsFormView() &&\
118 : SwViewOption::IsDocBoundaries())
119 : //subsidiary lines for sections
120 : #define IS_SUBS_SECTION (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
121 : !pGlobalShell->GetViewOptions()->IsReadonly()&&\
122 : !pGlobalShell->GetViewOptions()->IsFormView() &&\
123 : SwViewOption::IsSectionBoundaries())
124 : #define IS_SUBS_FLYS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
125 : !pGlobalShell->GetViewOptions()->IsReadonly()&&\
126 : !pGlobalShell->GetViewOptions()->IsFormView() &&\
127 : SwViewOption::IsObjectBoundaries())
128 :
129 : //Class declaration; here because they are only used in this file
130 :
131 : #define SUBCOL_PAGE 0x01 //Helplines of the page
132 : #define SUBCOL_TAB 0x08 //Helplines inside tables
133 : #define SUBCOL_FLY 0x10 //Helplines inside fly frames
134 : #define SUBCOL_SECT 0x20 //Helplines inside sections
135 :
136 : // Classes collecting the border lines and help lines
137 0 : class SwLineRect : public SwRect
138 : {
139 : Color aColor;
140 : SvxBorderStyle nStyle;
141 : const SwTabFrm *pTab;
142 : sal_uInt8 nSubColor; //colorize subsidiary lines
143 : bool bPainted; //already painted?
144 : sal_uInt8 nLock; //To distinguish the line and the hell layer.
145 : public:
146 : SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderStyle nStyle,
147 : const SwTabFrm *pT , const sal_uInt8 nSCol );
148 :
149 0 : const Color *GetColor() const { return &aColor;}
150 0 : SvxBorderStyle GetStyle() const { return nStyle; }
151 0 : const SwTabFrm *GetTab() const { return pTab; }
152 0 : void SetPainted() { bPainted = true; }
153 0 : void Lock( sal_Bool bLock ) { if ( bLock )
154 0 : ++nLock;
155 0 : else if ( nLock )
156 0 : --nLock;
157 0 : }
158 0 : bool IsPainted() const { return bPainted; }
159 0 : bool IsLocked() const { return nLock != 0; }
160 0 : sal_uInt8 GetSubColor() const { return nSubColor;}
161 :
162 : bool MakeUnion( const SwRect &rRect );
163 : };
164 :
165 0 : class SwLineRects : public std::vector< SwLineRect >
166 : {
167 : size_t nLastCount; //avoid unnecessary cycles in PaintLines
168 : public:
169 0 : SwLineRects() : nLastCount( 0 ) {}
170 : void AddLineRect( const SwRect& rRect, const Color *pColor, const SvxBorderStyle nStyle,
171 : const SwTabFrm *pTab, const sal_uInt8 nSCol );
172 : void ConnectEdges( OutputDevice *pOut );
173 : void PaintLines ( OutputDevice *pOut );
174 : void LockLines( sal_Bool bLock );
175 :
176 : //Limit lines to 100
177 0 : bool isFull() const { return this->size()>100 ? true : false; }
178 : };
179 :
180 0 : class SwSubsRects : public SwLineRects
181 : {
182 : void RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects );
183 : public:
184 : void PaintSubsidiary( OutputDevice *pOut, const SwLineRects *pRects );
185 :
186 : inline void Ins( const SwRect &rRect, const sal_uInt8 nSCol );
187 : };
188 :
189 0 : class BorderLines
190 : {
191 : typedef ::comphelper::SequenceAsVector<
192 : ::rtl::Reference<BorderLinePrimitive2D> > Lines_t;
193 : Lines_t m_Lines;
194 : public:
195 : void AddBorderLine(::rtl::Reference<BorderLinePrimitive2D> const& xLine);
196 0 : drawinglayer::primitive2d::Primitive2DSequence GetBorderLines_Clear()
197 : {
198 : ::comphelper::SequenceAsVector<
199 0 : ::drawinglayer::primitive2d::Primitive2DReference> lines;
200 0 : for (Lines_t::const_iterator it = m_Lines.begin(); it != m_Lines.end();
201 : ++it)
202 : {
203 0 : lines.push_back(it->get());
204 : }
205 0 : m_Lines.clear();
206 0 : return lines.getAsConstList();
207 : }
208 : };
209 :
210 : //----------------- End of classes for border lines ----------------------
211 :
212 : static SwViewShell *pGlobalShell = 0;
213 :
214 : //Only repaint the Fly content as well as the background of the Fly content if
215 : //a metafile is taken of the Fly.
216 : static sal_Bool bFlyMetafile = sal_False;
217 : static OutputDevice *pFlyMetafileOut = 0;
218 :
219 : //Retouch for transparent Flys is done by the background of the Flys.
220 : //The Fly itself should certainly not be spared out. See PaintBackground and
221 : //lcl_SubtractFlys()
222 : static SwFlyFrm *pRetoucheFly = 0;
223 : static SwFlyFrm *pRetoucheFly2 = 0;
224 :
225 : // Sizes of a pixel and the corresponding halves. Will be reset when
226 : // entering SwRootFrm::Paint
227 : static long nPixelSzW = 0, nPixelSzH = 0;
228 : static long nHalfPixelSzW = 0, nHalfPixelSzH = 0;
229 : static long nMinDistPixelW = 0, nMinDistPixelH = 0;
230 :
231 : // Current zoom factor
232 : static double aScaleX = 1.0;
233 : static double aScaleY = 1.0;
234 : static double aMinDistScale = 0.73;
235 : static double aEdgeScale = 0.5;
236 :
237 : // The borders will be collected in pLines during the Paint and later
238 : // possibly merge them.
239 : // The help lines will be collected and merged in pSubsLines. These will
240 : // be compared with pLines before the work in order to avoid help lines
241 : // to hide borders.
242 : // bTablines is sal_True during the Paint of a table.
243 : static BorderLines *g_pBorderLines = 0;
244 : static SwLineRects *pLines = 0;
245 : static SwSubsRects *pSubsLines = 0;
246 : // global variable for sub-lines of body, header, footer, section and footnote frames.
247 : static SwSubsRects *pSpecSubsLines = 0;
248 :
249 : static SfxProgress *pProgress = 0;
250 :
251 : static SwFlyFrm *pFlyOnlyDraw = 0;
252 :
253 : //So the flys can also be painted right for the hack.
254 : static sal_Bool bTableHack = sal_False;
255 :
256 : //To optimize the expensive RetouchColor determination
257 0 : Color aGlobalRetoucheColor;
258 :
259 : namespace {
260 :
261 0 : bool isTableBoundariesEnabled()
262 : {
263 0 : if (!pGlobalShell->GetViewOptions()->IsTable())
264 0 : return false;
265 :
266 0 : if (pGlobalShell->GetViewOptions()->IsPagePreview())
267 0 : return false;
268 :
269 0 : if (pGlobalShell->GetViewOptions()->IsReadonly())
270 0 : return false;
271 :
272 0 : if (pGlobalShell->GetViewOptions()->IsFormView())
273 0 : return false;
274 :
275 0 : return SwViewOption::IsTableBoundaries();
276 : }
277 :
278 : }
279 :
280 : // Set borders alignment statics.
281 : // adjustment for 'small' twip-to-pixel relations:
282 : // For 'small' twip-to-pixel relations (less then 2:1)
283 : // values of <nHalfPixelSzW> and <nHalfPixelSzH> are set to ZERO.
284 0 : void SwCalcPixStatics( OutputDevice *pOut )
285 : {
286 : // determine 'small' twip-to-pixel relation
287 0 : sal_Bool bSmallTwipToPxRelW = sal_False;
288 0 : sal_Bool bSmallTwipToPxRelH = sal_False;
289 : {
290 0 : Size aCheckTwipToPxRelSz( pOut->PixelToLogic( Size( 100, 100 )) );
291 0 : if ( (aCheckTwipToPxRelSz.Width()/100.0) < 2.0 )
292 : {
293 0 : bSmallTwipToPxRelW = sal_True;
294 : }
295 0 : if ( (aCheckTwipToPxRelSz.Height()/100.0) < 2.0 )
296 : {
297 0 : bSmallTwipToPxRelH = sal_True;
298 : }
299 : }
300 :
301 0 : Size aSz( pOut->PixelToLogic( Size( 1,1 )) );
302 :
303 0 : nPixelSzW = aSz.Width();
304 0 : if( !nPixelSzW )
305 0 : nPixelSzW = 1;
306 0 : nPixelSzH = aSz.Height();
307 0 : if( !nPixelSzH )
308 0 : nPixelSzH = 1;
309 :
310 : // consider 'small' twip-to-pixel relations
311 0 : if ( !bSmallTwipToPxRelW )
312 : {
313 0 : nHalfPixelSzW = nPixelSzW / 2 + 1;
314 : }
315 : else
316 : {
317 0 : nHalfPixelSzW = 0;
318 : }
319 : // consider 'small' twip-to-pixel relations
320 0 : if ( !bSmallTwipToPxRelH )
321 : {
322 0 : nHalfPixelSzH = nPixelSzH / 2 + 1;
323 : }
324 : else
325 : {
326 0 : nHalfPixelSzH = 0;
327 : }
328 :
329 0 : nMinDistPixelW = nPixelSzW * 2 + 1;
330 0 : nMinDistPixelH = nPixelSzH * 2 + 1;
331 :
332 0 : const MapMode &rMap = pOut->GetMapMode();
333 0 : aScaleX = rMap.GetScaleX();
334 0 : aScaleY = rMap.GetScaleY();
335 0 : }
336 :
337 : //To be able to save the statics so the paint is more or lees reentrant.
338 : class SwSavePaintStatics
339 : {
340 : sal_Bool bSFlyMetafile;
341 : SwViewShell *pSGlobalShell;
342 : OutputDevice *pSFlyMetafileOut;
343 : SwFlyFrm *pSRetoucheFly,
344 : *pSRetoucheFly2,
345 : *pSFlyOnlyDraw;
346 : BorderLines *pBLines;
347 : SwLineRects *pSLines;
348 : SwSubsRects *pSSubsLines;
349 : SwSubsRects* pSSpecSubsLines;
350 : SfxProgress *pSProgress;
351 : long nSPixelSzW,
352 : nSPixelSzH,
353 : nSHalfPixelSzW,
354 : nSHalfPixelSzH,
355 : nSMinDistPixelW,
356 : nSMinDistPixelH;
357 : Color aSGlobalRetoucheColor;
358 : double aSScaleX,
359 : aSScaleY;
360 : public:
361 : SwSavePaintStatics();
362 : ~SwSavePaintStatics();
363 : };
364 :
365 0 : SwSavePaintStatics::SwSavePaintStatics() :
366 : bSFlyMetafile ( bFlyMetafile ),
367 : pSGlobalShell ( pGlobalShell ),
368 : pSFlyMetafileOut ( pFlyMetafileOut ),
369 : pSRetoucheFly ( pRetoucheFly ),
370 : pSRetoucheFly2 ( pRetoucheFly2 ),
371 : pSFlyOnlyDraw ( pFlyOnlyDraw ),
372 : pBLines ( g_pBorderLines ),
373 : pSLines ( pLines ),
374 : pSSubsLines ( pSubsLines ),
375 : pSSpecSubsLines ( pSpecSubsLines ),
376 : pSProgress ( pProgress ),
377 : nSPixelSzW ( nPixelSzW ),
378 : nSPixelSzH ( nPixelSzH ),
379 : nSHalfPixelSzW ( nHalfPixelSzW ),
380 : nSHalfPixelSzH ( nHalfPixelSzH ),
381 : nSMinDistPixelW ( nMinDistPixelW ),
382 : nSMinDistPixelH ( nMinDistPixelH ),
383 : aSGlobalRetoucheColor( aGlobalRetoucheColor ),
384 : aSScaleX ( aScaleX ),
385 0 : aSScaleY ( aScaleY )
386 : {
387 0 : bFlyMetafile = sal_False;
388 0 : pFlyMetafileOut = 0;
389 0 : pRetoucheFly = 0;
390 0 : pRetoucheFly2 = 0;
391 : nPixelSzW = nPixelSzH =
392 : nHalfPixelSzW = nHalfPixelSzH =
393 0 : nMinDistPixelW = nMinDistPixelH = 0;
394 0 : aScaleX = aScaleY = 1.0;
395 0 : aMinDistScale = 0.73;
396 0 : aEdgeScale = 0.5;
397 0 : g_pBorderLines = 0;
398 0 : pLines = 0;
399 0 : pSubsLines = 0;
400 0 : pSpecSubsLines = 0L;
401 0 : pProgress = 0;
402 0 : }
403 :
404 0 : SwSavePaintStatics::~SwSavePaintStatics()
405 : {
406 0 : pGlobalShell = pSGlobalShell;
407 0 : bFlyMetafile = bSFlyMetafile;
408 0 : pFlyMetafileOut = pSFlyMetafileOut;
409 0 : pRetoucheFly = pSRetoucheFly;
410 0 : pRetoucheFly2 = pSRetoucheFly2;
411 0 : pFlyOnlyDraw = pSFlyOnlyDraw;
412 0 : g_pBorderLines = pBLines;
413 0 : pLines = pSLines;
414 0 : pSubsLines = pSSubsLines;
415 0 : pSpecSubsLines = pSSpecSubsLines;
416 0 : pProgress = pSProgress;
417 0 : nPixelSzW = nSPixelSzW;
418 0 : nPixelSzH = nSPixelSzH;
419 0 : nHalfPixelSzW = nSHalfPixelSzW;
420 0 : nHalfPixelSzH = nSHalfPixelSzH;
421 0 : nMinDistPixelW = nSMinDistPixelW;
422 0 : nMinDistPixelH = nSMinDistPixelH;
423 0 : aGlobalRetoucheColor = aSGlobalRetoucheColor;
424 0 : aScaleX = aSScaleX;
425 0 : aScaleY = aSScaleY;
426 0 : }
427 :
428 : //----------------- Implementation for the table borders --------------
429 :
430 : /**
431 : * Check whether the two primitve can be merged
432 : *
433 : * @param[in] mergeA A primitive start and end position
434 : * @param[in] mergeB B primitive start and end position
435 : * @return 1 if A and B can be merged to a primite staring with A, ending with B
436 : * 2 if A and B can be merged to a primite staring with B, ending with A
437 : * 0 if A and B can't be merged
438 : **/
439 0 : static sal_uInt8 lcl_TryMergeLines(
440 : pair<double, double> const mergeA,
441 : pair<double, double> const mergeB)
442 : {
443 0 : double const fMergeGap(nPixelSzW + nHalfPixelSzW); // NOT static!
444 : // A is above/before B
445 0 : if( mergeA.second <= mergeB.second &&
446 0 : mergeA.second + fMergeGap >= mergeB.first )
447 : {
448 0 : return 1;
449 : }
450 : // B is above/before A
451 0 : else if( mergeB.second <= mergeA.second &&
452 0 : mergeB.second + fMergeGap >= mergeA.first )
453 : {
454 0 : return 2;
455 : }
456 0 : return 0;
457 : }
458 :
459 : /**
460 : * Make a new primitive from the two input borderline primitive
461 : *
462 : * @param[in] rLine starting primitive
463 : * @param[in] rOther ending primitive
464 : * @param[in] rStart starting point of merged primitive
465 : * @param[in] rEnd ending point of merged primitive
466 : * @return merged primitive
467 : **/
468 : static ::rtl::Reference<BorderLinePrimitive2D>
469 0 : lcl_MergeBorderLines(
470 : BorderLinePrimitive2D const& rLine, BorderLinePrimitive2D const& rOther,
471 : basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd)
472 : {
473 : return new BorderLinePrimitive2D(rStart, rEnd,
474 : rLine.getLeftWidth(),
475 : rLine.getDistance(),
476 : rLine.getRightWidth(),
477 : rLine.getExtendLeftStart(),
478 : rOther.getExtendLeftEnd(),
479 : rLine.getExtendRightStart(),
480 : rOther.getExtendRightEnd(),
481 : rLine.getRGBColorLeft(),
482 : rLine.getRGBColorGap(),
483 : rLine.getRGBColorRight(),
484 0 : rLine.hasGapColor(),
485 0 : rLine.getStyle());
486 : }
487 :
488 : /**
489 : * Merge the two borderline if possible.
490 : *
491 : * @param[in] rThis one borderline primitive
492 : * @param[in] rOther other borderline primitive
493 : * @return merged borderline including the two input primitive, if they can be merged
494 : * 0, otherwise
495 : **/
496 : static ::rtl::Reference<BorderLinePrimitive2D>
497 0 : lcl_TryMergeBorderLine(BorderLinePrimitive2D const& rThis,
498 : BorderLinePrimitive2D const& rOther)
499 : {
500 : assert(rThis.getEnd().getX() >= rThis.getStart().getX());
501 : assert(rThis.getEnd().getY() >= rThis.getStart().getY());
502 : assert(rOther.getEnd().getX() >= rOther.getStart().getX());
503 : assert(rOther.getEnd().getY() >= rOther.getStart().getY());
504 0 : double thisHeight = rThis.getEnd().getY() - rThis.getStart().getY();
505 0 : double thisWidth = rThis.getEnd().getX() - rThis.getStart().getX();
506 0 : double otherHeight = rOther.getEnd().getY() - rOther.getStart().getY();
507 0 : double otherWidth = rOther.getEnd().getX() - rOther.getStart().getX();
508 : // check for same orientation, same line width, same style and matching colors
509 0 : if ( ((thisHeight > thisWidth) == (otherHeight > otherWidth))
510 0 : && (rThis.getLeftWidth() == rOther.getLeftWidth())
511 0 : && (rThis.getDistance() == rOther.getDistance())
512 0 : && (rThis.getRightWidth() == rOther.getRightWidth())
513 0 : && (rThis.getStyle() == rOther.getStyle())
514 0 : && (rThis.getRGBColorLeft() == rOther.getRGBColorLeft())
515 0 : && (rThis.getRGBColorRight() == rOther.getRGBColorRight())
516 0 : && (rThis.hasGapColor() == rOther.hasGapColor())
517 0 : && (!rThis.hasGapColor() ||
518 0 : (rThis.getRGBColorGap() == rOther.getRGBColorGap())))
519 : {
520 0 : int nRet = 0;
521 0 : if (thisHeight > thisWidth) // vertical line
522 : {
523 0 : if (rThis.getStart().getX() == rOther.getStart().getX())
524 : {
525 : assert(rThis.getEnd().getX() == rOther.getEnd().getX());
526 : nRet = lcl_TryMergeLines(
527 0 : make_pair(rThis.getStart().getY(), rThis.getEnd().getY()),
528 0 : make_pair(rOther.getStart().getY(),rOther.getEnd().getY()));
529 : }
530 : }
531 : else // horizontal line
532 : {
533 0 : if (rThis.getStart().getY() == rOther.getStart().getY())
534 : {
535 : assert(rThis.getEnd().getY() == rOther.getEnd().getY());
536 : nRet = lcl_TryMergeLines(
537 0 : make_pair(rThis.getStart().getX(), rThis.getEnd().getX()),
538 0 : make_pair(rOther.getStart().getX(),rOther.getEnd().getX()));
539 : }
540 : }
541 :
542 : // The merged primitive starts with rThis and ends with rOther
543 0 : if (nRet == 1)
544 : {
545 : basegfx::B2DPoint const start(
546 0 : rThis.getStart().getX(), rThis.getStart().getY());
547 : basegfx::B2DPoint const end(
548 0 : rOther.getEnd().getX(), rOther.getEnd().getY());
549 0 : return lcl_MergeBorderLines(rThis, rOther, start, end);
550 : }
551 : // The merged primitive starts with rOther and ends with rThis
552 0 : else if(nRet == 2)
553 : {
554 : basegfx::B2DPoint const start(
555 0 : rOther.getStart().getX(), rOther.getStart().getY());
556 : basegfx::B2DPoint const end(
557 0 : rThis.getEnd().getX(), rThis.getEnd().getY());
558 0 : return lcl_MergeBorderLines(rOther, rThis, start, end);
559 : }
560 : }
561 0 : return 0;
562 : }
563 :
564 0 : void BorderLines::AddBorderLine(
565 : rtl::Reference<BorderLinePrimitive2D> const& xLine)
566 : {
567 0 : for (Lines_t::reverse_iterator it = m_Lines.rbegin(); it != m_Lines.rend();
568 : ++it)
569 : {
570 : ::rtl::Reference<BorderLinePrimitive2D> const xMerged =
571 0 : lcl_TryMergeBorderLine(**it, *xLine);
572 0 : if (xMerged.is())
573 : {
574 0 : *it = xMerged; // replace existing line with merged
575 0 : return;
576 : }
577 0 : }
578 0 : m_Lines.push_back(xLine);
579 : }
580 :
581 0 : SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderStyle nStyl,
582 : const SwTabFrm *pT, const sal_uInt8 nSCol ) :
583 : SwRect( rRect ),
584 : nStyle( nStyl ),
585 : pTab( pT ),
586 : nSubColor( nSCol ),
587 : bPainted( false ),
588 0 : nLock( 0 )
589 : {
590 0 : if ( pCol != NULL )
591 0 : aColor = *pCol;
592 0 : }
593 :
594 0 : bool SwLineRect::MakeUnion( const SwRect &rRect )
595 : {
596 : // It has already been tested outside, whether the rectangles have
597 : // the same orientation (horizontal or vertical), color, etc.
598 0 : if ( Height() > Width() ) //Vertical line
599 : {
600 0 : if ( Left() == rRect.Left() && Width() == rRect.Width() )
601 : {
602 : // Merge when there is no gap between the lines
603 0 : const long nAdd = nPixelSzW + nHalfPixelSzW;
604 0 : if ( Bottom() + nAdd >= rRect.Top() &&
605 0 : Top() - nAdd <= rRect.Bottom() )
606 : {
607 0 : Bottom( std::max( Bottom(), rRect.Bottom() ) );
608 0 : Top ( std::min( Top(), rRect.Top() ) );
609 0 : return true;
610 : }
611 : }
612 : }
613 : else
614 : {
615 0 : if ( Top() == rRect.Top() && Height() == rRect.Height() )
616 : {
617 : // Merge when there is no gap between the lines
618 0 : const long nAdd = nPixelSzW + nHalfPixelSzW;
619 0 : if ( Right() + nAdd >= rRect.Left() &&
620 0 : Left() - nAdd <= rRect.Right() )
621 : {
622 0 : Right( std::max( Right(), rRect.Right() ) );
623 0 : Left ( std::min( Left(), rRect.Left() ) );
624 0 : return true;
625 : }
626 : }
627 : }
628 0 : return false;
629 : }
630 :
631 0 : void SwLineRects::AddLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderStyle nStyle,
632 : const SwTabFrm *pTab, const sal_uInt8 nSCol )
633 : {
634 : //Loop backwards because lines which can be combined, can usually be painted
635 : //in the same context.
636 :
637 0 : for (SwLineRects::reverse_iterator it = this->rbegin(); it != this->rend();
638 : ++it)
639 : {
640 0 : SwLineRect &rLRect = (*it);
641 : // Test for the orientation, color, table
642 0 : if ( rLRect.GetTab() == pTab &&
643 0 : !rLRect.IsPainted() && rLRect.GetSubColor() == nSCol &&
644 0 : (rLRect.Height() > rLRect.Width()) == (rRect.Height() > rRect.Width()) &&
645 0 : ((!rLRect.GetColor() && !pCol) ||
646 0 : (rLRect.GetColor() && pCol && *rLRect.GetColor() == *pCol)) )
647 : {
648 0 : if ( rLRect.MakeUnion( rRect ) )
649 0 : return;
650 : }
651 : }
652 0 : this->push_back( SwLineRect( rRect, pCol, nStyle, pTab, nSCol ) );
653 : }
654 :
655 0 : void SwLineRects::ConnectEdges( OutputDevice *pOut )
656 : {
657 0 : if ( pOut->GetOutDevType() != OUTDEV_PRINTER )
658 : {
659 : // I'm not doing anything for a too small zoom
660 0 : if ( aScaleX < aEdgeScale || aScaleY < aEdgeScale )
661 0 : return;
662 : }
663 :
664 : static const long nAdd = 20;
665 :
666 0 : std::vector<SwLineRect*> aCheck;
667 :
668 0 : for (size_t i = 0; i < this->size(); ++i)
669 : {
670 0 : SwLineRect &rL1 = (*this)[i];
671 0 : if ( !rL1.GetTab() || rL1.IsPainted() || rL1.IsLocked() )
672 0 : continue;
673 :
674 0 : aCheck.clear();
675 :
676 0 : const bool bVert = rL1.Height() > rL1.Width();
677 : long nL1a, nL1b, nL1c, nL1d;
678 :
679 0 : if ( bVert )
680 : {
681 0 : nL1a = rL1.Top(); nL1b = rL1.Left();
682 0 : nL1c = rL1.Right(); nL1d = rL1.Bottom();
683 : }
684 : else
685 : {
686 0 : nL1a = rL1.Left(); nL1b = rL1.Top();
687 0 : nL1c = rL1.Bottom(); nL1d = rL1.Right();
688 : }
689 :
690 : // Collect all lines to possibly link with i1
691 0 : for (SwLineRects::iterator it2 = this->begin(); it2 != this->end(); ++it2)
692 : {
693 0 : SwLineRect &rL2 = (*it2);
694 0 : if ( rL2.GetTab() != rL1.GetTab() ||
695 0 : rL2.IsPainted() ||
696 0 : rL2.IsLocked() ||
697 0 : (bVert == (rL2.Height() > rL2.Width())) )
698 0 : continue;
699 :
700 : long nL2a, nL2b, nL2c, nL2d;
701 0 : if ( bVert )
702 : {
703 0 : nL2a = rL2.Top(); nL2b = rL2.Left();
704 0 : nL2c = rL2.Right(); nL2d = rL2.Bottom();
705 : }
706 : else
707 : {
708 0 : nL2a = rL2.Left(); nL2b = rL2.Top();
709 0 : nL2c = rL2.Bottom(); nL2d = rL2.Right();
710 : }
711 :
712 0 : if ( (nL1a - nAdd < nL2d && nL1d + nAdd > nL2a) &&
713 0 : ((nL1b > nL2b && nL1c < nL2c) ||
714 0 : (nL1c >= nL2c && nL1b - nAdd < nL2c) ||
715 0 : (nL1b <= nL2b && nL1c + nAdd > nL2b)) )
716 : {
717 0 : aCheck.push_back( &rL2 );
718 : }
719 : }
720 0 : if ( aCheck.size() < 2 )
721 0 : continue;
722 :
723 0 : bool bRemove = false;
724 :
725 : // For each line test all following ones.
726 0 : for ( sal_uInt16 k = 0; !bRemove && k < aCheck.size(); ++k )
727 : {
728 0 : SwLineRect &rR1 = *aCheck[k];
729 :
730 0 : for ( sal_uInt16 k2 = k+1; !bRemove && k2 < aCheck.size(); ++k2 )
731 : {
732 0 : SwLineRect &rR2 = *aCheck[k2];
733 0 : if ( bVert )
734 : {
735 0 : SwLineRect *pLA = 0;
736 0 : SwLineRect *pLB = 0;
737 0 : if ( rR1.Top() < rR2.Top() )
738 : {
739 0 : pLA = &rR1; pLB = &rR2;
740 : }
741 0 : else if ( rR1.Top() > rR2.Top() )
742 : {
743 0 : pLA = &rR2; pLB = &rR1;
744 : }
745 : // are k1 and k2 describing a double line?
746 0 : if ( pLA && pLA->Bottom() + 60 > pLB->Top() )
747 : {
748 0 : if ( rL1.Top() < pLA->Top() )
749 : {
750 0 : if ( rL1.Bottom() == pLA->Bottom() )
751 0 : continue; //Small mistake (where?)
752 :
753 0 : SwRect aIns( rL1 );
754 0 : aIns.Bottom( pLA->Bottom() );
755 0 : if ( !rL1.IsInside( aIns ) )
756 0 : continue;
757 : this->push_back( SwLineRect( aIns, rL1.GetColor(),
758 : table::BorderLineStyle::SOLID,
759 0 : rL1.GetTab(), SUBCOL_TAB ) );
760 0 : if ( isFull() )
761 : {
762 0 : --i;
763 0 : k = aCheck.size();
764 0 : break;
765 : }
766 : }
767 :
768 0 : if ( rL1.Bottom() > pLB->Bottom() )
769 0 : rL1.Top( pLB->Top() ); // extend i1 on the top
770 : else
771 0 : bRemove = true; //stopping, remove i1
772 : }
773 : }
774 : else
775 : {
776 0 : SwLineRect *pLA = 0;
777 0 : SwLineRect *pLB = 0;
778 0 : if ( rR1.Left() < rR2.Left() )
779 : {
780 0 : pLA = &rR1; pLB = &rR2;
781 : }
782 0 : else if ( rR1.Left() > rR2.Left() )
783 : {
784 0 : pLA = &rR2; pLB = &rR1;
785 : }
786 : // Is it double line?
787 0 : if ( pLA && pLA->Right() + 60 > pLB->Left() )
788 : {
789 0 : if ( rL1.Left() < pLA->Left() )
790 : {
791 0 : if ( rL1.Right() == pLA->Right() )
792 0 : continue; //small error
793 :
794 0 : SwRect aIns( rL1 );
795 0 : aIns.Right( pLA->Right() );
796 0 : if ( !rL1.IsInside( aIns ) )
797 0 : continue;
798 : this->push_back( SwLineRect( aIns, rL1.GetColor(),
799 : table::BorderLineStyle::SOLID,
800 0 : rL1.GetTab(), SUBCOL_TAB ) );
801 0 : if ( isFull() )
802 : {
803 0 : --i;
804 0 : k = aCheck.size();
805 0 : break;
806 : }
807 : }
808 0 : if ( rL1.Right() > pLB->Right() )
809 0 : rL1.Left( pLB->Left() );
810 : else
811 0 : bRemove = true;
812 : }
813 : }
814 : }
815 : }
816 0 : if ( bRemove )
817 : {
818 0 : this->erase(this->begin() + i);
819 0 : --i;
820 : }
821 0 : }
822 : }
823 :
824 : inline void SwSubsRects::Ins( const SwRect &rRect, const sal_uInt8 nSCol )
825 : {
826 : // Lines that are shorted than the largest line width won't be inserted
827 : if ( rRect.Height() > DEF_LINE_WIDTH_4 || rRect.Width() > DEF_LINE_WIDTH_4 )
828 : {
829 : this->push_back(
830 : SwLineRect(rRect, 0, table::BorderLineStyle::SOLID, 0, nSCol));
831 : }
832 : }
833 :
834 0 : void SwSubsRects::RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects )
835 : {
836 : // All help lines that are covered by any border will be removed or split
837 :
838 0 : for (size_t i = 0; i < this->size(); ++i)
839 : {
840 : // get a copy instead of a reference, because an <insert> may destroy
841 : // the object due to a necessary array resize.
842 0 : const SwLineRect aSubsLineRect = SwLineRect((*this)[i]);
843 :
844 : // add condition <aSubsLineRect.IsLocked()> in order to consider only
845 : // border lines, which are *not* locked.
846 0 : if ( aSubsLineRect.IsPainted() ||
847 0 : aSubsLineRect.IsLocked() )
848 0 : continue;
849 :
850 0 : const bool bVerticalSubs = aSubsLineRect.Height() > aSubsLineRect.Width();
851 0 : SwRect aSubsRect( aSubsLineRect );
852 0 : if ( bVerticalSubs )
853 : {
854 0 : aSubsRect.Left ( aSubsRect.Left() - (nPixelSzW+nHalfPixelSzW) );
855 0 : aSubsRect.Right ( aSubsRect.Right() + (nPixelSzW+nHalfPixelSzW) );
856 : }
857 : else
858 : {
859 0 : aSubsRect.Top ( aSubsRect.Top() - (nPixelSzH+nHalfPixelSzH) );
860 0 : aSubsRect.Bottom( aSubsRect.Bottom() + (nPixelSzH+nHalfPixelSzH) );
861 : }
862 0 : for (SwLineRects::const_iterator itK = rRects.begin(); itK != rRects.end(); ++itK)
863 : {
864 0 : const SwLineRect &rLine = *itK;
865 :
866 : // do *not* consider painted or locked border lines.
867 : // #i1837# - locked border lines have to be considered.
868 0 : if ( rLine.IsLocked () )
869 0 : continue;
870 :
871 0 : if ( !bVerticalSubs == ( rLine.Height() > rLine.Width() ) ) //same direction?
872 0 : continue;
873 :
874 0 : if ( aSubsRect.IsOver( rLine ) )
875 : {
876 0 : if ( bVerticalSubs ) // Vertical?
877 : {
878 0 : if ( aSubsRect.Left() <= rLine.Right() &&
879 0 : aSubsRect.Right() >= rLine.Left() )
880 : {
881 0 : long nTmp = rLine.Top()-(nPixelSzH+1);
882 0 : if ( aSubsLineRect.Top() < nTmp )
883 : {
884 0 : SwRect aNewSubsRect( aSubsLineRect );
885 0 : aNewSubsRect.Bottom( nTmp );
886 0 : this->push_back( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
887 0 : aSubsLineRect.GetSubColor() ) );
888 : }
889 0 : nTmp = rLine.Bottom()+nPixelSzH+1;
890 0 : if ( aSubsLineRect.Bottom() > nTmp )
891 : {
892 0 : SwRect aNewSubsRect( aSubsLineRect );
893 0 : aNewSubsRect.Top( nTmp );
894 0 : this->push_back( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
895 0 : aSubsLineRect.GetSubColor() ) );
896 : }
897 0 : this->erase(this->begin() + i);
898 0 : --i;
899 0 : break;
900 : }
901 : }
902 : else //horizontal
903 : {
904 0 : if ( aSubsRect.Top() <= rLine.Bottom() &&
905 0 : aSubsRect.Bottom() >= rLine.Top() )
906 : {
907 0 : long nTmp = rLine.Left()-(nPixelSzW+1);
908 0 : if ( aSubsLineRect.Left() < nTmp )
909 : {
910 0 : SwRect aNewSubsRect( aSubsLineRect );
911 0 : aNewSubsRect.Right( nTmp );
912 0 : this->push_back( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
913 0 : aSubsLineRect.GetSubColor() ) );
914 : }
915 0 : nTmp = rLine.Right()+nPixelSzW+1;
916 0 : if ( aSubsLineRect.Right() > nTmp )
917 : {
918 0 : SwRect aNewSubsRect( aSubsLineRect );
919 0 : aNewSubsRect.Left( nTmp );
920 0 : this->push_back( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
921 0 : aSubsLineRect.GetSubColor() ) );
922 : }
923 0 : this->erase(this->begin() + i);
924 0 : --i;
925 0 : break;
926 : }
927 : }
928 : }
929 : }
930 : }
931 0 : }
932 :
933 0 : void SwLineRects::LockLines( sal_Bool bLock )
934 : {
935 0 : for (SwLineRects::iterator it = this->begin(); it != this->end(); ++it)
936 0 : (*it).Lock( bLock );
937 0 : }
938 :
939 0 : static void lcl_DrawDashedRect( OutputDevice * pOut, SwLineRect & rLRect )
940 : {
941 0 : double nHalfLWidth = rLRect.Height( );
942 0 : if ( nHalfLWidth > 1 )
943 : {
944 0 : nHalfLWidth = nHalfLWidth / 2;
945 : }
946 : else
947 : {
948 0 : nHalfLWidth = 1;
949 : }
950 :
951 0 : long startX = rLRect.Left( );
952 0 : long startY = rLRect.Top( ) + static_cast<long>(nHalfLWidth);
953 0 : long endX = rLRect.Left( ) + rLRect.Width( );
954 0 : long endY = rLRect.Top( ) + static_cast<long>(nHalfLWidth);
955 :
956 0 : if ( rLRect.Height( ) > rLRect.Width( ) )
957 : {
958 0 : nHalfLWidth = rLRect.Width( );
959 0 : if ( nHalfLWidth > 1 )
960 : {
961 0 : nHalfLWidth = nHalfLWidth / 2;
962 : }
963 : else
964 : {
965 0 : nHalfLWidth = 1;
966 : }
967 0 : startX = rLRect.Left( ) + static_cast<long>(nHalfLWidth);
968 0 : startY = rLRect.Top( );
969 0 : endX = rLRect.Left( ) + static_cast<long>(nHalfLWidth);
970 0 : endY = rLRect.Top( ) + rLRect.Height( );
971 : }
972 :
973 : svtools::DrawLine( *pOut, Point( startX, startY ), Point( endX, endY ),
974 0 : sal_uInt32( nHalfLWidth * 2 ), rLRect.GetStyle( ) );
975 0 : }
976 :
977 0 : void SwLineRects::PaintLines( OutputDevice *pOut )
978 : {
979 : // Paint the borders. Sadly two passes are needed.
980 : // Once for the inside and once for the outside edges of tables
981 0 : if ( this->size() != nLastCount )
982 : {
983 : // #i16816# tagged pdf support
984 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
985 :
986 0 : pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
987 0 : pOut->SetFillColor();
988 0 : pOut->SetLineColor();
989 0 : ConnectEdges( pOut );
990 0 : const Color *pLast = 0;
991 :
992 0 : bool bPaint2nd = false;
993 0 : size_t nMinCount = this->size();
994 :
995 0 : for ( size_t i = 0; i < size(); ++i )
996 : {
997 0 : SwLineRect &rLRect = operator[](i);
998 :
999 0 : if ( rLRect.IsPainted() )
1000 0 : continue;
1001 :
1002 0 : if ( rLRect.IsLocked() )
1003 : {
1004 0 : nMinCount = std::min( nMinCount, i );
1005 0 : continue;
1006 : }
1007 :
1008 : // Paint it now or in the second pass?
1009 0 : bool bPaint = true;
1010 0 : if ( rLRect.GetTab() )
1011 : {
1012 0 : if ( rLRect.Height() > rLRect.Width() )
1013 : {
1014 : // Vertical edge, overlapping with the table edge?
1015 0 : SwTwips nLLeft = rLRect.Left() - 30,
1016 0 : nLRight = rLRect.Right() + 30,
1017 0 : nTLeft = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Left(),
1018 0 : nTRight = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Right();
1019 0 : if ( (nTLeft >= nLLeft && nTLeft <= nLRight) ||
1020 0 : (nTRight>= nLLeft && nTRight<= nLRight) )
1021 0 : bPaint = false;
1022 : }
1023 : else
1024 : {
1025 : // Horizontal edge, overlapping with the table edge?
1026 0 : SwTwips nLTop = rLRect.Top() - 30,
1027 0 : nLBottom = rLRect.Bottom() + 30,
1028 0 : nTTop = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Top(),
1029 0 : nTBottom = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Bottom();
1030 0 : if ( (nTTop >= nLTop && nTTop <= nLBottom) ||
1031 0 : (nTBottom >= nLTop && nTBottom <= nLBottom) )
1032 0 : bPaint = false;
1033 : }
1034 : }
1035 0 : if ( bPaint )
1036 : {
1037 0 : if ( !pLast || *pLast != *rLRect.GetColor() )
1038 : {
1039 0 : pLast = rLRect.GetColor();
1040 :
1041 0 : sal_uLong nOldDrawMode = pOut->GetDrawMode();
1042 0 : if( pGlobalShell->GetWin() &&
1043 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1044 0 : pOut->SetDrawMode( 0 );
1045 :
1046 0 : pOut->SetLineColor( *pLast );
1047 0 : pOut->SetFillColor( *pLast );
1048 0 : pOut->SetDrawMode( nOldDrawMode );
1049 : }
1050 :
1051 0 : if( !rLRect.IsEmpty() )
1052 0 : lcl_DrawDashedRect( pOut, rLRect );
1053 0 : rLRect.SetPainted();
1054 : }
1055 : else
1056 0 : bPaint2nd = true;
1057 : }
1058 0 : if ( bPaint2nd )
1059 : {
1060 0 : for ( size_t i = 0; i < size(); ++i )
1061 : {
1062 0 : SwLineRect &rLRect = operator[](i);
1063 0 : if ( rLRect.IsPainted() )
1064 0 : continue;
1065 :
1066 0 : if ( rLRect.IsLocked() )
1067 : {
1068 0 : nMinCount = std::min( nMinCount, i );
1069 0 : continue;
1070 : }
1071 :
1072 0 : if ( !pLast || *pLast != *rLRect.GetColor() )
1073 : {
1074 0 : pLast = rLRect.GetColor();
1075 :
1076 0 : sal_uLong nOldDrawMode = pOut->GetDrawMode();
1077 0 : if( pGlobalShell->GetWin() &&
1078 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1079 : {
1080 0 : pOut->SetDrawMode( 0 );
1081 : }
1082 :
1083 0 : pOut->SetFillColor( *pLast );
1084 0 : pOut->SetDrawMode( nOldDrawMode );
1085 : }
1086 0 : if( !rLRect.IsEmpty() )
1087 0 : lcl_DrawDashedRect( pOut, rLRect );
1088 0 : rLRect.SetPainted();
1089 : }
1090 : }
1091 0 : nLastCount = nMinCount;
1092 0 : pOut->Pop();
1093 : }
1094 0 : }
1095 :
1096 0 : void SwSubsRects::PaintSubsidiary( OutputDevice *pOut,
1097 : const SwLineRects *pRects )
1098 : {
1099 0 : if ( !this->empty() )
1100 : {
1101 : // #i16816# tagged pdf support
1102 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
1103 :
1104 : // Remove all help line that are almost covered (tables)
1105 0 : for (SwSubsRects::size_type i = 0; i != this->size(); ++i)
1106 : {
1107 0 : SwLineRect &rLi = (*this)[i];
1108 0 : const bool bVerticalSubs = rLi.Height() > rLi.Width();
1109 :
1110 0 : for (SwSubsRects::size_type k = i + 1; k != this->size(); ++k)
1111 : {
1112 0 : SwLineRect &rLk = (*this)[k];
1113 0 : if ( rLi.SSize() == rLk.SSize() )
1114 : {
1115 0 : if ( bVerticalSubs == ( rLk.Height() > rLk.Width() ) )
1116 : {
1117 0 : if ( bVerticalSubs )
1118 : {
1119 0 : long nLi = rLi.Right();
1120 0 : long nLk = rLk.Right();
1121 0 : if ( rLi.Top() == rLk.Top() &&
1122 0 : ((nLi < rLk.Left() && nLi+21 > rLk.Left()) ||
1123 0 : (nLk < rLi.Left() && nLk+21 > rLi.Left())))
1124 : {
1125 0 : this->erase(this->begin() + k);
1126 : // don't continue with inner loop any more:
1127 : // the array may shrink!
1128 0 : --i;
1129 0 : break;
1130 : }
1131 : }
1132 : else
1133 : {
1134 0 : long nLi = rLi.Bottom();
1135 0 : long nLk = rLk.Bottom();
1136 0 : if ( rLi.Left() == rLk.Left() &&
1137 0 : ((nLi < rLk.Top() && nLi+21 > rLk.Top()) ||
1138 0 : (nLk < rLi.Top() && nLk+21 > rLi.Top())))
1139 : {
1140 0 : this->erase(this->begin() + k);
1141 : // don't continue with inner loop any more:
1142 : // the array may shrink!
1143 0 : --i;
1144 0 : break;
1145 : }
1146 : }
1147 : }
1148 : }
1149 : }
1150 : }
1151 :
1152 0 : if ( pRects && (!pRects->empty()) )
1153 0 : RemoveSuperfluousSubsidiaryLines( *pRects );
1154 :
1155 0 : if ( !this->empty() )
1156 : {
1157 0 : pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
1158 0 : pOut->SetLineColor();
1159 :
1160 : // Reset draw mode in high contrast mode in order to get fill color
1161 : // set at output device. Recover draw mode after draw of lines.
1162 : // Necessary for the subsidiary lines painted by the fly frames.
1163 0 : sal_uLong nOldDrawMode = pOut->GetDrawMode();
1164 0 : if( pGlobalShell->GetWin() &&
1165 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1166 : {
1167 0 : pOut->SetDrawMode( 0 );
1168 : }
1169 :
1170 0 : for (SwSubsRects::iterator it = this->begin(); it != this->end();
1171 : ++it)
1172 : {
1173 0 : SwLineRect &rLRect = (*it);
1174 : // Add condition <!rLRect.IsLocked()> to prevent paint of locked subsidiary lines.
1175 0 : if ( !rLRect.IsPainted() &&
1176 0 : !rLRect.IsLocked() )
1177 : {
1178 0 : const Color *pCol = 0;
1179 0 : switch ( rLRect.GetSubColor() )
1180 : {
1181 0 : case SUBCOL_PAGE: pCol = &SwViewOption::GetDocBoundariesColor(); break;
1182 0 : case SUBCOL_FLY: pCol = &SwViewOption::GetObjectBoundariesColor(); break;
1183 0 : case SUBCOL_TAB: pCol = &SwViewOption::GetTableBoundariesColor(); break;
1184 0 : case SUBCOL_SECT: pCol = &SwViewOption::GetSectionBoundColor(); break;
1185 : }
1186 :
1187 0 : if (pCol && pOut->GetFillColor() != *pCol)
1188 0 : pOut->SetFillColor( *pCol );
1189 0 : pOut->DrawRect( rLRect.SVRect() );
1190 :
1191 0 : rLRect.SetPainted();
1192 : }
1193 : }
1194 :
1195 0 : pOut->SetDrawMode( nOldDrawMode );
1196 :
1197 0 : pOut->Pop();
1198 0 : }
1199 : }
1200 0 : }
1201 :
1202 : // Various functions that are use in this file.
1203 :
1204 : // Note: function <SwAlignRect(..)> also used outside this file.
1205 : // Correction: adjust rectangle on pixel level in order
1206 : // to assure, that the border 'leaves its original pixel', if it has to.
1207 : // No prior adjustments for odd relation between pixel and twip.
1208 0 : void SwAlignRect( SwRect &rRect, const SwViewShell *pSh )
1209 : {
1210 0 : if( !rRect.HasArea() )
1211 0 : return;
1212 :
1213 : // Assure that view shell (parameter <pSh>) exists, if the output device
1214 : // is taken from this view shell --> no output device, no alignment.
1215 : // Output device taken from view shell <pSh>, if <bFlyMetafile> not set.
1216 0 : if ( !bFlyMetafile && !pSh )
1217 : {
1218 0 : return;
1219 : }
1220 :
1221 : const OutputDevice *pOut = bFlyMetafile ?
1222 0 : pFlyMetafileOut : pSh->GetOut();
1223 :
1224 : // Hold original rectangle in pixel
1225 0 : const Rectangle aOrgPxRect = pOut->LogicToPixel( rRect.SVRect() );
1226 : // Determine pixel-center rectangle in twip
1227 0 : const SwRect aPxCenterRect( pOut->PixelToLogic( aOrgPxRect ) );
1228 :
1229 : // Perform adjustments on pixel level.
1230 0 : SwRect aAlignedPxRect( aOrgPxRect );
1231 0 : if ( rRect.Top() > aPxCenterRect.Top() )
1232 : {
1233 : // 'leave pixel overlapping on top'
1234 0 : aAlignedPxRect.Top( aAlignedPxRect.Top() + 1 );
1235 : }
1236 :
1237 0 : if ( rRect.Bottom() < aPxCenterRect.Bottom() )
1238 : {
1239 : // 'leave pixel overlapping on bottom'
1240 0 : aAlignedPxRect.Bottom( aAlignedPxRect.Bottom() - 1 );
1241 : }
1242 :
1243 0 : if ( rRect.Left() > aPxCenterRect.Left() )
1244 : {
1245 : // 'leave pixel overlapping on left'
1246 0 : aAlignedPxRect.Left( aAlignedPxRect.Left() + 1 );
1247 : }
1248 :
1249 0 : if ( rRect.Right() < aPxCenterRect.Right() )
1250 : {
1251 : // 'leave pixel overlapping on right'
1252 0 : aAlignedPxRect.Right( aAlignedPxRect.Right() - 1 );
1253 : }
1254 :
1255 : // Consider negative width/height check, if aligned SwRect has negative width/height.
1256 : // If Yes, adjust it to width/height = 0 twip.
1257 : // NOTE: A SwRect with negative width/height can occur, if the width/height
1258 : // of the given SwRect in twip was less than a pixel in twip and that
1259 : // the alignment calculates that the aligned SwRect should not contain
1260 : // the pixels the width/height is on.
1261 0 : if ( aAlignedPxRect.Width() < 0 )
1262 : {
1263 0 : aAlignedPxRect.Width(0);
1264 : }
1265 0 : if ( aAlignedPxRect.Height() < 0 )
1266 : {
1267 0 : aAlignedPxRect.Height(0);
1268 : }
1269 : // Consider zero width/height for converting a rectangle from
1270 : // pixel to logic it needs a width/height. Thus, set width/height
1271 : // to one, if it's zero and correct this on the twip level after the conversion.
1272 0 : bool bZeroWidth = false;
1273 0 : if ( aAlignedPxRect.Width() == 0 )
1274 : {
1275 0 : aAlignedPxRect.Width(1);
1276 0 : bZeroWidth = true;
1277 : }
1278 0 : bool bZeroHeight = false;
1279 0 : if ( aAlignedPxRect.Height() == 0 )
1280 : {
1281 0 : aAlignedPxRect.Height(1);
1282 0 : bZeroHeight = true;
1283 : }
1284 :
1285 0 : rRect = pOut->PixelToLogic( aAlignedPxRect.SVRect() );
1286 :
1287 : // Consider zero width/height and adjust calculated aligned twip rectangle.
1288 : // Reset width/height to zero; previous negative width/height haven't to be considered.
1289 0 : if ( bZeroWidth )
1290 : {
1291 0 : rRect.Width(0);
1292 : }
1293 0 : if ( bZeroHeight )
1294 : {
1295 0 : rRect.Height(0);
1296 : }
1297 : }
1298 :
1299 : /** Helper method for twip adjustments on pixel base
1300 :
1301 : method compares the x- or y-pixel position of two twip-point. If the x-/y-pixel
1302 : positions are the same, the x-/y-pixel position of the second twip point is
1303 : adjusted by a given amount of pixels.
1304 : */
1305 0 : static void lcl_CompPxPosAndAdjustPos( const OutputDevice& _rOut,
1306 : const Point& _rRefPt,
1307 : Point& _rCompPt,
1308 : const bool _bChkXPos,
1309 : const sal_Int8 _nPxAdjustment )
1310 : {
1311 0 : const Point aRefPxPt = _rOut.LogicToPixel( _rRefPt );
1312 0 : Point aCompPxPt = _rOut.LogicToPixel( _rCompPt );
1313 :
1314 0 : if ( _bChkXPos )
1315 : {
1316 0 : if ( aCompPxPt.X() == aRefPxPt.X() )
1317 : {
1318 0 : aCompPxPt.X() += _nPxAdjustment ;
1319 0 : const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
1320 0 : _rCompPt.X() = aAdjustedCompPt.X();
1321 : }
1322 : }
1323 : else
1324 : {
1325 0 : if ( aCompPxPt.Y() == aRefPxPt.Y() )
1326 : {
1327 0 : aCompPxPt.Y() += _nPxAdjustment ;
1328 0 : const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
1329 0 : _rCompPt.Y() = aAdjustedCompPt.Y();
1330 : }
1331 : }
1332 0 : }
1333 :
1334 : /** Method to pixel-align rectangle for drawing graphic object
1335 :
1336 : Because for drawing a graphic left-top-corner and size coordinations are
1337 : used, these coordinations have to be determined on pixel level.
1338 : Thus, convert rectangle to pixel and then convert left-top-corner and
1339 : size of pixel rectangle back to logic.
1340 : This calculation is necessary, because there exists a different between
1341 : the convert from logic to pixel of a normal rectangle with its left-top-
1342 : and right-bottom-corner and the same convert of the same rectangle
1343 : with left-top-corner and size.
1344 : Call this method before each <GraphicObject.Draw(...)>
1345 : */
1346 0 : void SwAlignGrfRect( SwRect *pGrfRect, const OutputDevice &rOut )
1347 : {
1348 0 : Rectangle aPxRect = rOut.LogicToPixel( pGrfRect->SVRect() );
1349 0 : pGrfRect->Pos( rOut.PixelToLogic( aPxRect.TopLeft() ) );
1350 0 : pGrfRect->SSize( rOut.PixelToLogic( aPxRect.GetSize() ) );
1351 0 : }
1352 :
1353 0 : static long lcl_AlignWidth( const long nWidth )
1354 : {
1355 0 : if ( nWidth )
1356 : {
1357 0 : const long nW = nWidth % nPixelSzW;
1358 :
1359 0 : if ( !nW || nW > nHalfPixelSzW )
1360 0 : return std::max(1L, nWidth - nHalfPixelSzW);
1361 : }
1362 0 : return nWidth;
1363 : }
1364 :
1365 0 : static long lcl_AlignHeight( const long nHeight )
1366 : {
1367 0 : if ( nHeight )
1368 : {
1369 0 : const long nH = nHeight % nPixelSzH;
1370 :
1371 0 : if ( !nH || nH > nHalfPixelSzH )
1372 0 : return std::max(1L, nHeight - nHalfPixelSzH);
1373 : }
1374 0 : return nHeight;
1375 : }
1376 :
1377 0 : static long lcl_MinHeightDist( const long nDist )
1378 : {
1379 0 : if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale )
1380 0 : return nDist;
1381 0 : return ::lcl_AlignHeight( std::max( nDist, nMinDistPixelH ));
1382 : }
1383 :
1384 : //Calculate PrtArea plus surrounding plus shadow.
1385 0 : static void lcl_CalcBorderRect( SwRect &rRect, const SwFrm *pFrm,
1386 : const SwBorderAttrs &rAttrs,
1387 : const bool bShadow )
1388 : {
1389 : // Special handling for cell frames.
1390 : // The printing area of a cell frame is completely enclosed in the frame area
1391 : // and a cell frame has no shadow. Thus, for cell frames the calculated
1392 : // area equals the frame area.
1393 : // Notes: Borders of cell frames in R2L text direction will switch its side
1394 : // - left border is painted on the right; right border on the left.
1395 : // See <lcl_PaintLeftLine> and <lcl_PaintRightLine>.
1396 0 : if( pFrm->IsSctFrm() )
1397 : {
1398 0 : rRect = pFrm->Prt();
1399 0 : rRect.Pos() += pFrm->Frm().Pos();
1400 : }
1401 0 : else if ( pFrm->IsCellFrm() )
1402 0 : rRect = pFrm->Frm();
1403 : else
1404 : {
1405 0 : rRect = pFrm->Prt();
1406 0 : rRect.Pos() += pFrm->Frm().Pos();
1407 :
1408 0 : if ( rAttrs.IsLine() || rAttrs.IsBorderDist() ||
1409 0 : (bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE) )
1410 : {
1411 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1412 0 : SwRectFn fnRect = pFrm->IsVertical() ? ( pFrm->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
1413 :
1414 0 : const SvxBoxItem &rBox = rAttrs.GetBox();
1415 0 : const bool bTop = 0 != (pFrm->*fnRect->fnGetTopMargin)();
1416 0 : if ( bTop )
1417 : {
1418 0 : SwTwips nDiff = rBox.GetTop() ?
1419 0 : rBox.CalcLineSpace( BOX_LINE_TOP ) :
1420 0 : ( rAttrs.IsBorderDist() ?
1421 : // Increase of distance by one twip is incorrect.
1422 0 : rBox.GetDistance( BOX_LINE_TOP ) : 0 );
1423 0 : if( nDiff )
1424 0 : (rRect.*fnRect->fnSubTop)( nDiff );
1425 : }
1426 :
1427 0 : const bool bBottom = 0 != (pFrm->*fnRect->fnGetBottomMargin)();
1428 0 : if ( bBottom )
1429 : {
1430 0 : SwTwips nDiff = 0;
1431 : // #i29550#
1432 0 : if ( pFrm->IsTabFrm() &&
1433 0 : ((SwTabFrm*)pFrm)->IsCollapsingBorders() )
1434 : {
1435 : // For collapsing borders, we have to add the height of
1436 : // the height of the last line
1437 0 : nDiff = ((SwTabFrm*)pFrm)->GetBottomLineSize();
1438 : }
1439 : else
1440 : {
1441 0 : nDiff = rBox.GetBottom() ?
1442 0 : rBox.CalcLineSpace( BOX_LINE_BOTTOM ) :
1443 0 : ( rAttrs.IsBorderDist() ?
1444 : // Increase of distance by one twip is incorrect.
1445 0 : rBox.GetDistance( BOX_LINE_BOTTOM ) : 0 );
1446 : }
1447 0 : if( nDiff )
1448 0 : (rRect.*fnRect->fnAddBottom)( nDiff );
1449 : }
1450 :
1451 0 : if ( rBox.GetLeft() )
1452 0 : (rRect.*fnRect->fnSubLeft)( rBox.CalcLineSpace( BOX_LINE_LEFT ) );
1453 0 : else if ( rAttrs.IsBorderDist() )
1454 : // Increase of distance by one twip is incorrect.
1455 0 : (rRect.*fnRect->fnSubLeft)( rBox.GetDistance( BOX_LINE_LEFT ) );
1456 :
1457 0 : if ( rBox.GetRight() )
1458 0 : (rRect.*fnRect->fnAddRight)( rBox.CalcLineSpace( BOX_LINE_RIGHT ) );
1459 0 : else if ( rAttrs.IsBorderDist() )
1460 : // Increase of distance by one twip is incorrect.
1461 0 : (rRect.*fnRect->fnAddRight)( rBox.GetDistance( BOX_LINE_RIGHT ) );
1462 :
1463 0 : if ( bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
1464 : {
1465 0 : const SvxShadowItem &rShadow = rAttrs.GetShadow();
1466 0 : if ( bTop )
1467 0 : (rRect.*fnRect->fnSubTop)(rShadow.CalcShadowSpace(SHADOW_TOP));
1468 0 : (rRect.*fnRect->fnSubLeft)(rShadow.CalcShadowSpace(SHADOW_LEFT));
1469 0 : if ( bBottom )
1470 : (rRect.*fnRect->fnAddBottom)
1471 0 : (rShadow.CalcShadowSpace( SHADOW_BOTTOM ));
1472 0 : (rRect.*fnRect->fnAddRight)(rShadow.CalcShadowSpace(SHADOW_RIGHT));
1473 : }
1474 : }
1475 : }
1476 :
1477 0 : ::SwAlignRect( rRect, pGlobalShell );
1478 0 : }
1479 :
1480 0 : static void lcl_ExtendLeftAndRight( SwRect& _rRect,
1481 : const SwFrm& _rFrm,
1482 : const SwBorderAttrs& _rAttrs,
1483 : const SwRectFn& _rRectFn )
1484 : {
1485 : // Extend left/right border/shadow rectangle to bottom of previous frame/to
1486 : // top of next frame, if border/shadow is joined with previous/next frame.
1487 0 : if ( _rAttrs.JoinedWithPrev( _rFrm ) )
1488 : {
1489 0 : const SwFrm* pPrevFrm = _rFrm.GetPrev();
1490 0 : (_rRect.*_rRectFn->fnSetTop)( (pPrevFrm->*_rRectFn->fnGetPrtBottom)() );
1491 : }
1492 0 : if ( _rAttrs.JoinedWithNext( _rFrm ) )
1493 : {
1494 0 : const SwFrm* pNextFrm = _rFrm.GetNext();
1495 0 : (_rRect.*_rRectFn->fnSetBottom)( (pNextFrm->*_rRectFn->fnGetPrtTop)() );
1496 : }
1497 0 : }
1498 :
1499 : //static void lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage,
1500 : // const SwRect &rRect, SwRegionRects &rRegion )
1501 : //{
1502 : // const SwSortedObjs& rObjs = *pPage->GetSortedObjs();
1503 : // const SwFlyFrm* pSelfFly = pFrm->IsInFly() ? pFrm->FindFlyFrm() : pRetoucheFly2;
1504 : // if ( !pRetoucheFly )
1505 : // pRetoucheFly = pRetoucheFly2;
1506 : //
1507 : // for ( sal_uInt16 j = 0; (j < rObjs.Count()) && !rRegion.empty(); ++j )
1508 : // {
1509 : // const SwAnchoredObject* pAnchoredObj = rObjs[j];
1510 : // const SdrObject* pSdrObj = pAnchoredObj->GetDrawObj();
1511 : //
1512 : // // Do not consider invisible objects
1513 : // if ( !pPage->GetFmt()->GetDoc()->IsVisibleLayerId( pSdrObj->GetLayer() ) )
1514 : // continue;
1515 : //
1516 : // if ( !pAnchoredObj->ISA(SwFlyFrm) )
1517 : // continue;
1518 : //
1519 : // const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
1520 : //
1521 : // if ( pSelfFly == pFly || pRetoucheFly == pFly || !rRect.IsOver( pFly->Frm() ) )
1522 : // continue;
1523 : //
1524 : // if ( !pFly->GetFmt()->GetPrint().GetValue() &&
1525 : // (OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() ||
1526 : // pGlobalShell->IsPreview()))
1527 : // continue;
1528 : //
1529 : // const bool bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly );
1530 : //
1531 : // //For character bound Flys only examine those Flys in which it is not
1532 : // //anchored itself.
1533 : // //Why only for character bound ones you may ask? It never makes sense to
1534 : // //subtract frames in which it is anchored itself right?
1535 : // if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
1536 : // continue;
1537 : //
1538 : // //Any why does it not apply for the RetoucheFly too?
1539 : // if ( pRetoucheFly && pRetoucheFly->IsLowerOf( pFly ) )
1540 : // continue;
1541 : //
1542 : //#if OSL_DEBUG_LEVEL > 0
1543 : // //Flys who are anchored inside their own one, must have a bigger OrdNum
1544 : // //or be character bound.
1545 : // if ( pSelfFly && bLowerOfSelf )
1546 : // {
1547 : // OSL_ENSURE( pFly->IsFlyInCntFrm() ||
1548 : // pSdrObj->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(),
1549 : // "Fly with wrong z-Order" );
1550 : // }
1551 : //#endif
1552 : //
1553 : // bool bStopOnHell = true;
1554 : // if ( pSelfFly )
1555 : // {
1556 : // const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
1557 : // if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
1558 : // {
1559 : // if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
1560 : // //In the same layer we only observe those that are above.
1561 : // continue;
1562 : // }
1563 : // else
1564 : // {
1565 : // if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
1566 : // //From other layers we are only interested in non
1567 : // //transparent ones or those that are internal
1568 : // continue;
1569 : // bStopOnHell = false;
1570 : // }
1571 : // }
1572 : // if ( pRetoucheFly )
1573 : // {
1574 : // const SdrObject *pTmp = pRetoucheFly->GetVirtDrawObj();
1575 : // if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
1576 : // {
1577 : // if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
1578 : // //In the same layer we only observe those that are above.
1579 : // continue;
1580 : // }
1581 : // else
1582 : // {
1583 : // if ( !pFly->IsLowerOf( pRetoucheFly ) && !pFly->GetFmt()->GetOpaque().GetValue() )
1584 : // //From other layers we are only interested in non
1585 : // //transparent ones or those that are internal
1586 : // continue;
1587 : // bStopOnHell = false;
1588 : // }
1589 : // }
1590 : //
1591 : // //If the content of the Fly is transparent, we subtract it only if it's
1592 : // //contained in the hell layer.
1593 : // const IDocumentDrawModelAccess* pIDDMA = pFly->GetFmt()->getIDocumentDrawModelAccess();
1594 : // bool bHell = pSdrObj->GetLayer() == pIDDMA->GetHellId();
1595 : // if ( (bStopOnHell && bHell) ||
1596 : // /// Change internal order of condition
1597 : // /// first check "!bHell", then "..->Lower()" and "..->IsNoTxtFrm()"
1598 : // /// have not to be performed, if frame is in "Hell"
1599 : // ( !bHell && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() &&
1600 : // ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
1601 : // ((SwNoTxtFrm*)pFly->Lower())->HasAnimation() ||
1602 : // pFly->GetFmt()->GetSurround().IsContour()
1603 : // )
1604 : // )
1605 : // )
1606 : // continue;
1607 : //
1608 : // // Own if-statements for transparent background/shadow of fly frames
1609 : // // in order to handle special conditions.
1610 : // if ( pFly->IsBackgroundTransparent() )
1611 : // {
1612 : // // Background <pFly> is transparent drawn. Thus normally, its region
1613 : // // have not to be substracted from given region.
1614 : // // But, if method is called for a fly frame and
1615 : // // <pFly> is a direct lower of this fly frame and
1616 : // // <pFly> inherites its transparent background brush from its parent,
1617 : // // then <pFly> frame area have to be subtracted from given region.
1618 : // // NOTE: Because in Status Quo transparent backgrounds can only be
1619 : // // assigned to fly frames, the handle of this special case
1620 : // // avoids drawing of transparent areas more than once, if
1621 : // // a fly frame inherites a transparent background from its
1622 : // // parent fly frame.
1623 : // if ( pFrm->IsFlyFrm() &&
1624 : // (pFly->GetAnchorFrm()->FindFlyFrm() == pFrm) &&
1625 : // static_cast<const SwFlyFrmFmt*>(pFly->GetFmt())->IsBackgroundBrushInherited()
1626 : // )
1627 : // {
1628 : // SwRect aRect;
1629 : // SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
1630 : // const SwBorderAttrs &rAttrs = *aAccess.Get();
1631 : // ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true );
1632 : // rRegion -= aRect;
1633 : // continue;
1634 : // }
1635 : // else
1636 : // {
1637 : // continue;
1638 : // }
1639 : // }
1640 : // if ( pFly->IsShadowTransparent() )
1641 : // {
1642 : // continue;
1643 : // }
1644 : //
1645 : // if ( bHell && pFly->GetAnchorFrm()->IsInFly() )
1646 : // {
1647 : // //So the border won't get dismantled by the background of the other
1648 : // //Fly.
1649 : // SwRect aRect;
1650 : // SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
1651 : // const SwBorderAttrs &rAttrs = *aAccess.Get();
1652 : // ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true );
1653 : // rRegion -= aRect;
1654 : // }
1655 : // else
1656 : // {
1657 : // SwRect aRect( pFly->Prt() );
1658 : // aRect += pFly->Frm().Pos();
1659 : // rRegion -= aRect;
1660 : // }
1661 : // }
1662 : // if ( pRetoucheFly == pRetoucheFly2 )
1663 : // pRetoucheFly = 0;
1664 : //}
1665 :
1666 : //---------------- Output for BrushItem ----------------
1667 :
1668 0 : static void lcl_implDrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush,
1669 : OutputDevice* _pOut,
1670 : const SwRect& _rAlignedPaintRect,
1671 : const GraphicObject& _rGraphicObj )
1672 : {
1673 : /// determine color of background
1674 : /// If color of background brush is not "no fill"/"auto fill" or
1675 : /// <bFlyMetafile> is set, use color of background brush, otherwise
1676 : /// use global retouche color.
1677 0 : const Color aColor( ( (_rBackgrdBrush.GetColor() != COL_TRANSPARENT) || bFlyMetafile )
1678 : ? _rBackgrdBrush.GetColor()
1679 0 : : aGlobalRetoucheColor );
1680 :
1681 : /// determine, if background color have to be drawn transparent
1682 : /// and calculate transparency percent value
1683 0 : sal_Int8 nTransparencyPercent = 0;
1684 0 : bool bDrawTransparent = false;
1685 0 : if ( aColor.GetTransparency() != 0 )
1686 : /// background color is transparent --> draw transparent.
1687 : {
1688 0 : bDrawTransparent = true;
1689 0 : nTransparencyPercent = (aColor.GetTransparency()*100 + 0x7F)/0xFF;
1690 : }
1691 0 : else if ( (_rGraphicObj.GetAttr().GetTransparency() != 0) &&
1692 0 : (_rBackgrdBrush.GetColor() == COL_TRANSPARENT) )
1693 : /// graphic is drawn transparent and background color is
1694 : /// "no fill"/"auto fill" --> draw transparent
1695 : {
1696 0 : bDrawTransparent = true;
1697 0 : nTransparencyPercent = (_rGraphicObj.GetAttr().GetTransparency()*100 + 0x7F)/0xFF;
1698 : }
1699 :
1700 0 : if ( bDrawTransparent )
1701 : {
1702 : /// draw background transparent
1703 0 : if( _pOut->GetFillColor() != aColor.GetRGBColor() )
1704 0 : _pOut->SetFillColor( aColor.GetRGBColor() );
1705 0 : PolyPolygon aPoly( _rAlignedPaintRect.SVRect() );
1706 0 : _pOut->DrawTransparent( aPoly, nTransparencyPercent );
1707 : }
1708 : else
1709 : {
1710 : /// draw background opaque
1711 0 : if ( _pOut->GetFillColor() != aColor )
1712 0 : _pOut->SetFillColor( aColor );
1713 0 : _pOut->DrawRect( _rAlignedPaintRect.SVRect() );
1714 : }
1715 0 : }
1716 :
1717 : /** lcl_DrawGraphicBackgrd - local help method to draw a background for a graphic
1718 :
1719 : Under certain circumstances we have to draw a background for a graphic.
1720 : This method takes care of the conditions and draws the background with the
1721 : corresponding color.
1722 : Method introduced for bug fix #103876# in order to optimize drawing tiled
1723 : background graphics. Previously, this code was integrated in method
1724 : <lcl_DrawGraphic>.
1725 : Method implemented as a inline, checking the conditions and calling method
1726 : method <lcl_implDrawGraphicBackgrd(..)> for the intrinsic drawing.
1727 :
1728 : @param _rBackgrdBrush
1729 : background brush contain the color the background has to be drawn.
1730 :
1731 : @param _pOut
1732 : output device the background has to be drawn in.
1733 :
1734 : @param _rAlignedPaintRect
1735 : paint retangle in the output device, which has to be drawn with the background.
1736 : rectangle have to be aligned by method ::SwAlignRect
1737 :
1738 : @param _rGraphicObj
1739 : graphic object, for which the background has to be drawn. Used for checking
1740 : the transparency of its bitmap, its type and if the graphic is drawn transparent
1741 :
1742 : @param _bNumberingGraphic
1743 : boolean indicating that graphic is used as a numbering.
1744 :
1745 : @param _bBackgrdAlreadyDrawn
1746 : boolean (optional; default: false) indicating, if the background is already drawn.
1747 : */
1748 0 : static inline void lcl_DrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush,
1749 : OutputDevice* _pOut,
1750 : const SwRect& _rAlignedPaintRect,
1751 : const GraphicObject& _rGraphicObj,
1752 : bool _bNumberingGraphic,
1753 : bool _bBackgrdAlreadyDrawn = false )
1754 : {
1755 : // draw background with background color, if
1756 : // (1) graphic is not used as a numbering AND
1757 : // (2) background is not already drawn AND
1758 : // (3) intrinsic graphic is transparent OR intrinsic graphic doesn't exists
1759 0 : if ( !_bNumberingGraphic &&
1760 0 : !_bBackgrdAlreadyDrawn &&
1761 0 : ( _rGraphicObj.IsTransparent() || _rGraphicObj.GetType() == GRAPHIC_NONE )
1762 : )
1763 : {
1764 0 : lcl_implDrawGraphicBackgrd( _rBackgrdBrush, _pOut, _rAlignedPaintRect, _rGraphicObj );
1765 : }
1766 0 : }
1767 :
1768 : // Note: the transparency of the background graphic
1769 : // is saved in SvxBrushItem.GetGraphicObject(<shell>).GetAttr().Set/GetTransparency()
1770 : // and is considered in the drawing of the graphic.
1771 : // Thus, to provide transparent background graphic for text frames nothing
1772 : // has to be coded.
1773 : // Use align rectangle for drawing graphic
1774 : // Pixel-align coordinations for drawing graphic.
1775 : // Outsource code for drawing background of the graphic
1776 : // with a background color in method <lcl_DrawGraphicBackgrd>
1777 : // Also, change type of <bGrfNum> and <bClip> from <sal_Bool> to <bool>.
1778 0 : static void lcl_DrawGraphic( const SvxBrushItem& rBrush, OutputDevice *pOut,
1779 : SwViewShell &rSh, const SwRect &rGrf, const SwRect &rOut,
1780 : bool bClip, bool bGrfNum,
1781 : bool bBackgrdAlreadyDrawn = false )
1782 : // add parameter <bBackgrdAlreadyDrawn> to indicate
1783 : // that the background is already drawn.
1784 : {
1785 : // Calculate align rectangle from parameter <rGrf> and use aligned
1786 : // rectangle <aAlignedGrfRect> in the following code
1787 0 : SwRect aAlignedGrfRect = rGrf;
1788 0 : ::SwAlignRect( aAlignedGrfRect, &rSh );
1789 :
1790 : // Change type from <sal_Bool> to <bool>.
1791 0 : const bool bNotInside = bClip && !rOut.IsInside( aAlignedGrfRect );
1792 0 : if ( bNotInside )
1793 : {
1794 0 : pOut->Push( PUSH_CLIPREGION );
1795 0 : pOut->IntersectClipRegion( rOut.SVRect() );
1796 : }
1797 :
1798 : // No Link here, we want to load the graphic synchronously!
1799 0 : ((SvxBrushItem&)rBrush).SetDoneLink( Link() );
1800 0 : GraphicObject *pGrf = (GraphicObject*)rBrush.GetGraphicObject();
1801 :
1802 : // Outsource drawing of background with a background color
1803 0 : ::lcl_DrawGraphicBackgrd( rBrush, pOut, aAlignedGrfRect, *pGrf, bGrfNum, bBackgrdAlreadyDrawn );
1804 :
1805 : // Because for drawing a graphic left-top-corner and size coordinations are
1806 : // used, these coordinations have to be determined on pixel level.
1807 0 : ::SwAlignGrfRect( &aAlignedGrfRect, *pOut );
1808 :
1809 0 : if (pGrf->GetGraphic().getSvgData().get())
1810 : { // fdo#68927 - SVGs are rasterized badly by DrawWithPDFHandling
1811 : paintGraphicUsingPrimitivesHelper(*pOut,
1812 0 : pGrf->GetGraphic(), pGrf->GetAttr(), aAlignedGrfRect);
1813 : }
1814 : else
1815 : {
1816 0 : pGrf->DrawWithPDFHandling( *pOut, aAlignedGrfRect.Pos(), aAlignedGrfRect.SSize() );
1817 : }
1818 :
1819 0 : if ( bNotInside )
1820 0 : pOut->Pop();
1821 0 : }
1822 :
1823 0 : bool DrawFillAttributes(
1824 : const FillAttributesPtr& rFillAttributes,
1825 : const SwRect& rOriginalLayoutRect,
1826 : const SwRect& rPaintRect,
1827 : OutputDevice& rOut)
1828 : {
1829 : static bool bUseNew(true);
1830 : static bool bReturnWhenNew(true);
1831 :
1832 0 : if(bUseNew && rFillAttributes.get() && rFillAttributes->isUsed())
1833 : {
1834 : const basegfx::B2DRange aPaintRange(
1835 0 : rPaintRect.Left(),
1836 0 : rPaintRect.Top(),
1837 0 : rPaintRect.Right(),
1838 0 : rPaintRect.Bottom());
1839 :
1840 0 : if(!aPaintRange.isEmpty() &&
1841 0 : !basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
1842 0 : !basegfx::fTools::equalZero(aPaintRange.getHeight()))
1843 : {
1844 : const basegfx::B2DRange aDefineRange(
1845 0 : rOriginalLayoutRect.Left(),
1846 0 : rOriginalLayoutRect.Top(),
1847 0 : rOriginalLayoutRect.Right(),
1848 0 : rOriginalLayoutRect.Bottom());
1849 :
1850 : const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rFillAttributes->getPrimitive2DSequence(
1851 : aPaintRange,
1852 0 : aDefineRange);
1853 :
1854 0 : if(rSequence.getLength())
1855 : {
1856 : const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
1857 : basegfx::B2DHomMatrix(),
1858 : rOut.GetViewTransformation(),
1859 : aPaintRange,
1860 : 0,
1861 : 0.0,
1862 0 : uno::Sequence< beans::PropertyValue >());
1863 : drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice(
1864 : rOut,
1865 0 : aViewInformation2D);
1866 :
1867 0 : if(pProcessor)
1868 : {
1869 0 : pProcessor->process(rSequence);
1870 :
1871 0 : delete pProcessor;
1872 :
1873 0 : if(bReturnWhenNew)
1874 : {
1875 0 : return true;
1876 : }
1877 0 : }
1878 : }
1879 : }
1880 : }
1881 :
1882 0 : return false;
1883 : }
1884 :
1885 0 : void DrawGraphic(
1886 : const SvxBrushItem *pBrush,
1887 : OutputDevice *pOutDev,
1888 : const SwRect &rOrg,
1889 : const SwRect &rOut,
1890 : const sal_uInt8 nGrfNum,
1891 : const sal_Bool bConsiderBackgroundTransparency )
1892 : // Add 6th parameter to indicate that method should
1893 : // consider background transparency, saved in the color of the brush item
1894 : {
1895 0 : SwViewShell &rSh = *pGlobalShell;
1896 0 : bool bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum;
1897 0 : bool bGrfNum = GRFNUM_NO != nGrfNum;
1898 0 : Size aGrfSize;
1899 0 : SvxGraphicPosition ePos = GPOS_NONE;
1900 0 : if( pBrush && !bReplaceGrfNum )
1901 : {
1902 0 : if( rSh.GetViewOptions()->IsGraphic() )
1903 : {
1904 : // load graphic directly in PDF import
1905 : // #i68953# - also during print load graphic directly.
1906 0 : if ( (rSh).GetViewOptions()->IsPDFExport() ||
1907 0 : rSh.GetOut()->GetOutDevType() == OUTDEV_PRINTER )
1908 : {
1909 0 : ((SvxBrushItem*)pBrush)->PurgeMedium();
1910 0 : ((SvxBrushItem*)pBrush)->SetDoneLink( Link() );
1911 : }
1912 : else
1913 0 : ((SvxBrushItem*)pBrush)->SetDoneLink( STATIC_LINK(
1914 0 : rSh.GetDoc(), SwDoc, BackgroundDone ) );
1915 0 : OUString referer;
1916 0 : SfxObjectShell * sh = rSh.GetDoc()->GetPersist();
1917 0 : if (sh != 0 && sh->HasName()) {
1918 0 : referer = sh->GetMedium()->GetName();
1919 : }
1920 0 : const Graphic* pGrf = pBrush->GetGraphic(referer);
1921 0 : if( pGrf && GRAPHIC_NONE != pGrf->GetType() )
1922 : {
1923 0 : ePos = pBrush->GetGraphicPos();
1924 0 : if( pGrf->IsSupportedGraphic() )
1925 : // don't the use the specific output device! Bug 94802
1926 0 : aGrfSize = ::GetGraphicSizeTwip( *pGrf, 0 );
1927 0 : }
1928 : }
1929 : else
1930 0 : bReplaceGrfNum = bGrfNum;
1931 : }
1932 :
1933 0 : SwRect aGrf;
1934 0 : aGrf.SSize( aGrfSize );
1935 0 : bool bDraw = true;
1936 0 : bool bRetouche = true;
1937 0 : switch ( ePos )
1938 : {
1939 : case GPOS_LT:
1940 0 : aGrf.Pos() = rOrg.Pos();
1941 0 : break;
1942 :
1943 : case GPOS_MT:
1944 0 : aGrf.Pos().Y() = rOrg.Top();
1945 0 : aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1946 0 : break;
1947 :
1948 : case GPOS_RT:
1949 0 : aGrf.Pos().Y() = rOrg.Top();
1950 0 : aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1951 0 : break;
1952 :
1953 : case GPOS_LM:
1954 0 : aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1955 0 : aGrf.Pos().X() = rOrg.Left();
1956 0 : break;
1957 :
1958 : case GPOS_MM:
1959 0 : aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1960 0 : aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1961 0 : break;
1962 :
1963 : case GPOS_RM:
1964 0 : aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
1965 0 : aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1966 0 : break;
1967 :
1968 : case GPOS_LB:
1969 0 : aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1970 0 : aGrf.Pos().X() = rOrg.Left();
1971 0 : break;
1972 :
1973 : case GPOS_MB:
1974 0 : aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1975 0 : aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
1976 0 : break;
1977 :
1978 : case GPOS_RB:
1979 0 : aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
1980 0 : aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
1981 0 : break;
1982 :
1983 : case GPOS_AREA:
1984 0 : aGrf = rOrg;
1985 : // In spite the fact that the background graphic have to fill the complete
1986 : // area, it has been checked, if the graphic will completely fill out
1987 : // the region to be painted <rOut> and thus, nothing has to be retouched.
1988 : // For example, this is the case for a fly frame without a background
1989 : // brush positioned on the border of the page and inherited the
1990 : // background brush from the page.
1991 0 : bRetouche = !rOut.IsInside( aGrf );
1992 0 : break;
1993 :
1994 : case GPOS_TILED:
1995 : {
1996 : // draw background of tiled graphic before drawing tiled graphic in loop
1997 : // determine graphic object
1998 0 : GraphicObject* pGraphicObj = const_cast< GraphicObject* >(pBrush->GetGraphicObject());
1999 : // calculate aligned paint rectangle
2000 0 : SwRect aAlignedPaintRect = rOut;
2001 0 : ::SwAlignRect( aAlignedPaintRect, &rSh );
2002 : // draw background color for aligned paint rectangle
2003 0 : lcl_DrawGraphicBackgrd( *pBrush, pOutDev, aAlignedPaintRect, *pGraphicObj, bGrfNum );
2004 :
2005 : // set left-top-corner of background graphic to left-top-corner of the
2006 : // area, from which the background brush is determined.
2007 0 : aGrf.Pos() = rOrg.Pos();
2008 : // setup clipping at output device
2009 0 : pOutDev->Push( PUSH_CLIPREGION );
2010 0 : pOutDev->IntersectClipRegion( rOut.SVRect() );
2011 : // use new method <GraphicObject::DrawTiled(::)>
2012 : {
2013 : // calculate paint offset
2014 0 : Point aPaintOffset( aAlignedPaintRect.Pos() - aGrf.Pos() );
2015 : // draw background graphic tiled for aligned paint rectangle
2016 : // #i42643#
2017 : // For PDF export, every draw operation for bitmaps takes a
2018 : // noticeable amount of place (~50 characters). Thus, optimize
2019 : // between tile bitmap size and number of drawing operations here.
2020 :
2021 : // A_out
2022 : // n_chars = k1 * ---------- + k2 * A_bitmap
2023 : // A_bitmap
2024 :
2025 : // minimum n_chars is obtained for (derive for A_bitmap,
2026 : // set to 0, take positive solution):
2027 : // k1
2028 : // A_bitmap = Sqrt( ---- A_out )
2029 : // k2
2030 :
2031 : // where k1 is the number of chars per draw operation, and
2032 : // k2 is the number of chars per bitmap pixel.
2033 : // This is approximately 50 and 7 for current PDF writer, respectively.
2034 :
2035 0 : const double k1( 50 );
2036 0 : const double k2( 7 );
2037 0 : const Size aSize( aAlignedPaintRect.SSize() );
2038 0 : const double Abitmap( k1/k2 * static_cast<double>(aSize.Width())*aSize.Height() );
2039 :
2040 : pGraphicObj->DrawTiled( pOutDev,
2041 : aAlignedPaintRect.SVRect(),
2042 0 : aGrf.SSize(),
2043 0 : Size( aPaintOffset.X(), aPaintOffset.Y() ),
2044 : NULL, GRFMGR_DRAW_STANDARD,
2045 0 : ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
2046 : }
2047 : // reset clipping at output device
2048 0 : pOutDev->Pop();
2049 : // set <bDraw> and <bRetouche> to false, indicating that background
2050 : // graphic and background are already drawn.
2051 0 : bDraw = bRetouche = false;
2052 : }
2053 0 : break;
2054 :
2055 : case GPOS_NONE:
2056 0 : bDraw = false;
2057 0 : break;
2058 :
2059 : default: OSL_ENSURE( !pOutDev, "new Graphic position?" );
2060 : }
2061 :
2062 : /// init variable <bGrfBackgrdAlreadDrawn> to indicate, if background of
2063 : /// graphic is already drawn or not.
2064 0 : bool bGrfBackgrdAlreadyDrawn = false;
2065 0 : if ( bRetouche )
2066 : {
2067 0 : pOutDev->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
2068 0 : pOutDev->SetLineColor();
2069 :
2070 : // check, if a existing background graphic (not filling the complete
2071 : // background) is transparent drawn and the background color is
2072 : // "no fill" respectively "auto fill", if background transparency
2073 : // has to be considered.
2074 : // If YES, memorise transparency of background graphic.
2075 : // check also, if background graphic bitmap is transparent.
2076 0 : bool bTransparentGrfWithNoFillBackgrd = false;
2077 0 : sal_Int32 nGrfTransparency = 0;
2078 0 : bool bGrfIsTransparent = false;
2079 0 : if ( (ePos != GPOS_NONE) &&
2080 0 : (ePos != GPOS_TILED) && (ePos != GPOS_AREA)
2081 : )
2082 : {
2083 0 : GraphicObject *pGrf = (GraphicObject*)pBrush->GetGraphicObject();
2084 0 : if ( bConsiderBackgroundTransparency )
2085 : {
2086 0 : GraphicAttr pGrfAttr = pGrf->GetAttr();
2087 0 : if ( (pGrfAttr.GetTransparency() != 0) &&
2088 0 : ( pBrush && (pBrush->GetColor() == COL_TRANSPARENT) )
2089 : )
2090 : {
2091 0 : bTransparentGrfWithNoFillBackgrd = true;
2092 0 : nGrfTransparency = pGrfAttr.GetTransparency();
2093 0 : }
2094 : }
2095 0 : if ( pGrf->IsTransparent() )
2096 : {
2097 0 : bGrfIsTransparent = true;
2098 : }
2099 : }
2100 :
2101 : // to get color of brush, check background color against COL_TRANSPARENT ("no fill"/"auto fill")
2102 : // instead of checking, if transparency is not set.
2103 0 : const Color aColor( pBrush &&
2104 0 : ( !(pBrush->GetColor() == COL_TRANSPARENT) ||
2105 : bFlyMetafile )
2106 : ? pBrush->GetColor()
2107 0 : : aGlobalRetoucheColor );
2108 :
2109 : // determine, if background region have to be
2110 : // drawn transparent.
2111 : // background region has to be drawn transparent, if
2112 : // background transparency have to be considered
2113 : // AND
2114 : // ( background color is transparent OR
2115 : // background graphic is transparent and background color is "no fill"
2116 : // )
2117 :
2118 : enum DrawStyle {
2119 : Default,
2120 : Transparent,
2121 0 : } eDrawStyle = Default;
2122 :
2123 0 : if (bConsiderBackgroundTransparency &&
2124 0 : ( ( aColor.GetTransparency() != 0) ||
2125 : bTransparentGrfWithNoFillBackgrd ) )
2126 : {
2127 0 : eDrawStyle = Transparent;
2128 : }
2129 :
2130 : // #i75614# reset draw mode in high contrast mode in order to get fill color set
2131 0 : const sal_uLong nOldDrawMode = pOutDev->GetDrawMode();
2132 0 : if ( pGlobalShell->GetWin() &&
2133 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
2134 : {
2135 0 : pOutDev->SetDrawMode( 0 );
2136 : }
2137 :
2138 : // OD 06.08.2002 #99657# - if background region have to be drawn
2139 : // transparent, set only the RGB values of the background color as
2140 : // the fill color for the output device.
2141 0 : switch (eDrawStyle)
2142 : {
2143 : case Transparent:
2144 : {
2145 0 : if( pOutDev->GetFillColor() != aColor.GetRGBColor() )
2146 0 : pOutDev->SetFillColor( aColor.GetRGBColor() );
2147 0 : break;
2148 : }
2149 : default:
2150 : {
2151 0 : if( pOutDev->GetFillColor() != aColor )
2152 0 : pOutDev->SetFillColor( aColor );
2153 0 : break;
2154 : }
2155 : }
2156 :
2157 : // #i75614#
2158 : // restore draw mode
2159 0 : pOutDev->SetDrawMode( nOldDrawMode );
2160 :
2161 : // OD 02.09.2002 #99657#
2162 0 : switch (eDrawStyle)
2163 : {
2164 : case Transparent:
2165 : {
2166 : // background region have to be drawn transparent.
2167 : // Thus, create a poly-polygon from the region and draw it with
2168 : // the corresponding transparency precent.
2169 0 : PolyPolygon aDrawPoly( rOut.SVRect() );
2170 0 : if ( aGrf.HasArea() )
2171 : {
2172 0 : if ( !bGrfIsTransparent )
2173 : {
2174 : // substract area of background graphic from draw area
2175 : // OD 08.10.2002 #103898# - consider only that part of the
2176 : // graphic area that is overlapping with draw area.
2177 0 : SwRect aTmpGrf = aGrf;
2178 0 : aTmpGrf.Intersection( rOut );
2179 0 : if ( aTmpGrf.HasArea() )
2180 : {
2181 0 : Polygon aGrfPoly( aTmpGrf.SVRect() );
2182 0 : aDrawPoly.Insert( aGrfPoly );
2183 : }
2184 : }
2185 : else
2186 0 : bGrfBackgrdAlreadyDrawn = true;
2187 : }
2188 : // calculate transparency percent:
2189 : // ( <transparency value[0x01..0xFF]>*100 + 0x7F ) / 0xFF
2190 : // If there is a background graphic with a background color "no fill"/"auto fill",
2191 : // the transparency value is taken from the background graphic,
2192 : // otherwise take the transparency value from the color.
2193 : sal_Int8 nTransparencyPercent = static_cast<sal_Int8>(
2194 0 : (( bTransparentGrfWithNoFillBackgrd ? nGrfTransparency : aColor.GetTransparency()
2195 0 : )*100 + 0x7F)/0xFF);
2196 : // draw poly-polygon transparent
2197 0 : pOutDev->DrawTransparent( aDrawPoly, nTransparencyPercent );
2198 :
2199 0 : break;
2200 : }
2201 : case Default:
2202 : default:
2203 : {
2204 0 : SwRegionRects aRegion( rOut, 4 );
2205 0 : if ( !bGrfIsTransparent )
2206 0 : aRegion -= aGrf;
2207 : else
2208 0 : bGrfBackgrdAlreadyDrawn = true;
2209 : // loop rectangles of background region, which has to be drawn
2210 0 : for( sal_uInt16 i = 0; i < aRegion.size(); ++i )
2211 : {
2212 0 : pOutDev->DrawRect( aRegion[i].SVRect() );
2213 0 : }
2214 : }
2215 : }
2216 0 : pOutDev ->Pop();
2217 : }
2218 :
2219 0 : if( bDraw && aGrf.IsOver( rOut ) )
2220 : // OD 02.09.2002 #99657#
2221 : // add parameter <bGrfBackgrdAlreadyDrawn>
2222 : lcl_DrawGraphic( *pBrush, pOutDev, rSh, aGrf, rOut, true, bGrfNum,
2223 0 : bGrfBackgrdAlreadyDrawn );
2224 :
2225 0 : if( bReplaceGrfNum )
2226 : {
2227 0 : const BitmapEx& rBmp = SwViewShell::GetReplacementBitmap( false );
2228 0 : Font aTmp( pOutDev->GetFont() );
2229 0 : Graphic::DrawEx( pOutDev, aEmptyOUStr, aTmp, rBmp, rOrg.Pos(), rOrg.SSize() );
2230 : }
2231 0 : }
2232 :
2233 : /** local help method for SwRootFrm::Paint(..) - Adjust given rectangle to pixel size
2234 :
2235 : By OD at 27.09.2002 for #103636#
2236 : In order to avoid paint errors caused by multiple alignments - e.g. method
2237 : ::SwAlignRect(..) - and other changes to the rectangle to be painted,
2238 : this method is called for the rectangle to be painted in order to
2239 : adjust it to the pixel it is overlapping.
2240 : */
2241 0 : static void lcl_AdjustRectToPixelSize( SwRect& io_aSwRect, const OutputDevice &aOut )
2242 : {
2243 : // local constant object of class <Size> to determine number of Twips
2244 : // representing a pixel.
2245 0 : const Size aTwipToPxSize( aOut.PixelToLogic( Size( 1,1 )) );
2246 :
2247 : // local object of class <Rectangle> in Twip coordinates
2248 : // calculated from given rectangle aligned to pixel centers.
2249 : const Rectangle aPxCenterRect = aOut.PixelToLogic(
2250 0 : aOut.LogicToPixel( io_aSwRect.SVRect() ) );
2251 :
2252 : // local constant object of class <Rectangle> representing given rectangle
2253 : // in pixel.
2254 0 : const Rectangle aOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2255 :
2256 : // calculate adjusted rectangle from pixel centered rectangle.
2257 : // Due to rounding differences <aPxCenterRect> doesn't exactly represents
2258 : // the Twip-centers. Thus, adjust borders by half of pixel width/height plus 1.
2259 : // Afterwards, adjust calculated Twip-positions of the all borders.
2260 0 : Rectangle aSizedRect = aPxCenterRect;
2261 0 : aSizedRect.Left() -= (aTwipToPxSize.Width()/2 + 1);
2262 0 : aSizedRect.Right() += (aTwipToPxSize.Width()/2 + 1);
2263 0 : aSizedRect.Top() -= (aTwipToPxSize.Height()/2 + 1);
2264 0 : aSizedRect.Bottom() += (aTwipToPxSize.Height()/2 + 1);
2265 :
2266 : // adjust left()
2267 0 : while ( (aOut.LogicToPixel(aSizedRect)).Left() < aOrgPxRect.Left() )
2268 : {
2269 0 : ++aSizedRect.Left();
2270 : }
2271 : // adjust right()
2272 0 : while ( (aOut.LogicToPixel(aSizedRect)).Right() > aOrgPxRect.Right() )
2273 : {
2274 0 : --aSizedRect.Right();
2275 : }
2276 : // adjust top()
2277 0 : while ( (aOut.LogicToPixel(aSizedRect)).Top() < aOrgPxRect.Top() )
2278 : {
2279 0 : ++aSizedRect.Top();
2280 : }
2281 : // adjust bottom()
2282 0 : while ( (aOut.LogicToPixel(aSizedRect)).Bottom() > aOrgPxRect.Bottom() )
2283 : {
2284 0 : --aSizedRect.Bottom();
2285 : }
2286 :
2287 0 : io_aSwRect = SwRect( aSizedRect );
2288 :
2289 : #if OSL_DEBUG_LEVEL > 0
2290 : Rectangle aTestOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2291 : Rectangle aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2292 : OSL_ENSURE( aTestOrgPxRect == aTestNewPxRect,
2293 : "Error in lcl_AlignRectToPixelSize(..): Adjusted rectangle has incorrect position or size");
2294 : // check Left()
2295 : --aSizedRect.Left();
2296 : aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2297 : OSL_ENSURE( aTestOrgPxRect.Left() >= (aTestNewPxRect.Left()+1),
2298 : "Error in lcl_AlignRectToPixelSize(..): Left() not correct adjusted");
2299 : ++aSizedRect.Left();
2300 : // check Right()
2301 : ++aSizedRect.Right();
2302 : aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2303 : OSL_ENSURE( aTestOrgPxRect.Right() <= (aTestNewPxRect.Right()-1),
2304 : "Error in lcl_AlignRectToPixelSize(..): Right() not correct adjusted");
2305 : --aSizedRect.Right();
2306 : // check Top()
2307 : --aSizedRect.Top();
2308 : aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2309 : OSL_ENSURE( aTestOrgPxRect.Top() >= (aTestNewPxRect.Top()+1),
2310 : "Error in lcl_AlignRectToPixelSize(..): Top() not correct adjusted");
2311 : ++aSizedRect.Top();
2312 : // check Bottom()
2313 : ++aSizedRect.Bottom();
2314 : aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2315 : OSL_ENSURE( aTestOrgPxRect.Bottom() <= (aTestNewPxRect.Bottom()-1),
2316 : "Error in lcl_AlignRectToPixelSize(..): Bottom() not correct adjusted");
2317 : --aSizedRect.Bottom();
2318 : #endif
2319 0 : }
2320 :
2321 : // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES START
2322 :
2323 : struct SwLineEntry
2324 : {
2325 : SwTwips mnKey;
2326 : SwTwips mnStartPos;
2327 : SwTwips mnEndPos;
2328 : SwTwips mnOffset;
2329 :
2330 : bool mbOffsetPerp;
2331 : bool mbOffsetStart;
2332 : bool mbOffsetEnd;
2333 :
2334 : svx::frame::Style maAttribute;
2335 :
2336 : enum OverlapType { NO_OVERLAP, OVERLAP1, OVERLAP2, OVERLAP3 };
2337 :
2338 : public:
2339 : SwLineEntry( SwTwips nKey,
2340 : SwTwips nStartPos,
2341 : SwTwips nEndPos,
2342 : const svx::frame::Style& rAttribute );
2343 :
2344 : OverlapType Overlaps( const SwLineEntry& rComp ) const;
2345 : };
2346 :
2347 0 : SwLineEntry::SwLineEntry( SwTwips nKey,
2348 : SwTwips nStartPos,
2349 : SwTwips nEndPos,
2350 : const svx::frame::Style& rAttribute )
2351 : : mnKey( nKey ),
2352 : mnStartPos( nStartPos ),
2353 : mnEndPos( nEndPos ),
2354 : mnOffset( 0 ),
2355 : mbOffsetPerp(false),
2356 : mbOffsetStart(false),
2357 : mbOffsetEnd(false),
2358 0 : maAttribute( rAttribute )
2359 : {
2360 0 : }
2361 :
2362 : /*
2363 :
2364 : 1. ---------- rOld
2365 : ---------- rNew
2366 :
2367 : 2. ---------- rOld
2368 : ------------- rNew
2369 :
2370 : 3. ------- rOld
2371 : ------------- rNew
2372 :
2373 : 4. ------------- rOld
2374 : ---------- rNew
2375 :
2376 : 5. ---------- rOld
2377 : ---- rNew
2378 :
2379 : 6. ---------- rOld
2380 : ---------- rNew
2381 :
2382 : 7. ------------- rOld
2383 : ---------- rNew
2384 :
2385 : 8. ---------- rOld
2386 : ------------- rNew
2387 :
2388 : 9. ---------- rOld
2389 : ---------- rNew
2390 : */
2391 :
2392 0 : SwLineEntry::OverlapType SwLineEntry::Overlaps( const SwLineEntry& rNew ) const
2393 : {
2394 0 : SwLineEntry::OverlapType eRet = OVERLAP3;
2395 :
2396 0 : if ( mnStartPos >= rNew.mnEndPos || mnEndPos <= rNew.mnStartPos )
2397 0 : eRet = NO_OVERLAP;
2398 :
2399 : // 1, 2, 3
2400 0 : else if ( mnEndPos < rNew.mnEndPos )
2401 0 : eRet = OVERLAP1;
2402 :
2403 : // 4, 5, 6, 7
2404 0 : else if ( mnStartPos <= rNew.mnStartPos && mnEndPos >= rNew.mnEndPos )
2405 0 : eRet = OVERLAP2;
2406 :
2407 : // 8, 9
2408 0 : return eRet;
2409 : }
2410 :
2411 : struct lt_SwLineEntry
2412 : {
2413 0 : bool operator()( const SwLineEntry& e1, const SwLineEntry& e2 ) const
2414 : {
2415 0 : return e1.mnStartPos < e2.mnStartPos;
2416 : }
2417 : };
2418 :
2419 : typedef std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet;
2420 : typedef std::set< SwLineEntry, lt_SwLineEntry >::iterator SwLineEntrySetIter;
2421 : typedef std::set< SwLineEntry, lt_SwLineEntry >::const_iterator SwLineEntrySetConstIter;
2422 : typedef std::map< SwTwips, SwLineEntrySet > SwLineEntryMap;
2423 : typedef std::map< SwTwips, SwLineEntrySet >::iterator SwLineEntryMapIter;
2424 : typedef std::map< SwTwips, SwLineEntrySet >::const_iterator SwLineEntryMapConstIter;
2425 :
2426 0 : class SwTabFrmPainter
2427 : {
2428 : SwLineEntryMap maVertLines;
2429 : SwLineEntryMap maHoriLines;
2430 : const SwTabFrm& mrTabFrm;
2431 :
2432 : void Insert( SwLineEntry&, bool bHori );
2433 : void Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem );
2434 : void HandleFrame( const SwLayoutFrm& rFrm );
2435 : void FindStylesForLine( const Point&,
2436 : const Point&,
2437 : svx::frame::Style*,
2438 : bool bHori ) const;
2439 :
2440 : void AdjustTopLeftFrames();
2441 :
2442 : public:
2443 : SwTabFrmPainter( const SwTabFrm& rTabFrm );
2444 :
2445 : void PaintLines( OutputDevice& rDev, const SwRect& rRect ) const;
2446 : };
2447 :
2448 0 : SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm )
2449 0 : : mrTabFrm( rTabFrm )
2450 : {
2451 0 : HandleFrame( rTabFrm );
2452 0 : AdjustTopLeftFrames();
2453 0 : }
2454 :
2455 0 : void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm )
2456 : {
2457 : // Add border lines of cell frames. Skip covered cells. Skip cells
2458 : // in special row span row, which do not have a negative row span:
2459 0 : if ( rLayoutFrm.IsCellFrm() && !rLayoutFrm.IsCoveredCell() )
2460 : {
2461 0 : const SwCellFrm* pThisCell = static_cast<const SwCellFrm*>(&rLayoutFrm);
2462 0 : const SwRowFrm* pRowFrm = static_cast<const SwRowFrm*>(pThisCell->GetUpper());
2463 0 : const long nRowSpan = pThisCell->GetTabBox()->getRowSpan();
2464 0 : if ( !pRowFrm->IsRowSpanLine() || nRowSpan > 1 || nRowSpan < -1 )
2465 : {
2466 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), &rLayoutFrm );
2467 0 : const SwBorderAttrs& rAttrs = *aAccess.Get();
2468 0 : const SvxBoxItem& rBox = rAttrs.GetBox();
2469 0 : Insert( rLayoutFrm, rBox );
2470 : }
2471 : }
2472 :
2473 : // Recurse into lower layout frames, but do not recurse into lower tabframes.
2474 0 : const SwFrm* pLower = rLayoutFrm.Lower();
2475 0 : while ( pLower )
2476 : {
2477 0 : const SwLayoutFrm* pLowerLayFrm = dynamic_cast<const SwLayoutFrm*>(pLower);
2478 0 : if ( pLowerLayFrm && !pLowerLayFrm->IsTabFrm() )
2479 0 : HandleFrame( *pLowerLayFrm );
2480 :
2481 0 : pLower = pLower->GetNext();
2482 : }
2483 0 : }
2484 :
2485 0 : void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
2486 : {
2487 : // #i16816# tagged pdf support
2488 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev );
2489 :
2490 0 : SwLineEntryMapConstIter aIter = maHoriLines.begin();
2491 0 : bool bHori = true;
2492 :
2493 : // color for subsidiary lines:
2494 0 : const Color& rCol( SwViewOption::GetTableBoundariesColor() );
2495 :
2496 : // high contrast mode:
2497 : // overrides the color of non-subsidiary lines.
2498 0 : const Color* pHCColor = 0;
2499 0 : sal_uLong nOldDrawMode = rDev.GetDrawMode();
2500 0 : if( pGlobalShell->GetWin() &&
2501 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
2502 : {
2503 0 : pHCColor = &SwViewOption::GetFontColor();
2504 0 : rDev.SetDrawMode( 0 );
2505 : }
2506 :
2507 0 : const SwFrm* pUpper = mrTabFrm.GetUpper();
2508 0 : SwRect aUpper( pUpper->Prt() );
2509 0 : aUpper.Pos() += pUpper->Frm().Pos();
2510 0 : SwRect aUpperAligned( aUpper );
2511 0 : ::SwAlignRect( aUpperAligned, pGlobalShell );
2512 :
2513 : while ( true )
2514 : {
2515 0 : if ( bHori && aIter == maHoriLines.end() )
2516 : {
2517 0 : aIter = maVertLines.begin();
2518 0 : bHori = false;
2519 : }
2520 :
2521 0 : if ( !bHori && aIter == maVertLines.end() )
2522 0 : break;
2523 :
2524 0 : const SwLineEntrySet& rEntrySet = (*aIter).second;
2525 0 : for (SwLineEntrySetConstIter aSetIter = rEntrySet.begin();
2526 0 : aSetIter != rEntrySet.end(); ++aSetIter)
2527 : {
2528 0 : const SwLineEntry& rEntry = *aSetIter;
2529 0 : const svx::frame::Style& rEntryStyle( (*aSetIter).maAttribute );
2530 :
2531 0 : Point aStart, aEnd;
2532 0 : if ( bHori )
2533 : {
2534 0 : aStart.X() = rEntry.mnStartPos;
2535 0 : aStart.Y() = rEntry.mnKey;
2536 0 : aEnd.X() = rEntry.mnEndPos;
2537 0 : aEnd.Y() = rEntry.mnKey;
2538 : }
2539 : else
2540 : {
2541 0 : aStart.X() = rEntry.mnKey;
2542 0 : aStart.Y() = rEntry.mnStartPos;
2543 0 : aEnd.X() = rEntry.mnKey;
2544 0 : aEnd.Y() = rEntry.mnEndPos;
2545 : }
2546 :
2547 0 : svx::frame::Style aStyles[ 7 ];
2548 0 : aStyles[ 0 ] = rEntryStyle;
2549 0 : FindStylesForLine( aStart, aEnd, aStyles, bHori );
2550 :
2551 : // Account for double line thicknesses for the top- and left-most borders.
2552 0 : if (rEntry.mnOffset)
2553 : {
2554 0 : if (bHori)
2555 : {
2556 0 : if (rEntry.mbOffsetPerp)
2557 : {
2558 : // Apply offset in perpendicular direction.
2559 0 : aStart.Y() -= rEntry.mnOffset;
2560 0 : aEnd.Y() -= rEntry.mnOffset;
2561 : }
2562 0 : if (rEntry.mbOffsetStart)
2563 : // Apply offset at the start of a border.
2564 0 : aStart.X() -= rEntry.mnOffset;
2565 0 : if (rEntry.mbOffsetEnd)
2566 : // Apply offset at the end of a border.
2567 0 : aEnd.X() += rEntry.mnOffset;
2568 : }
2569 : else
2570 : {
2571 0 : if (rEntry.mbOffsetPerp)
2572 : {
2573 : // Apply offset in perpendicular direction.
2574 0 : aStart.X() -= rEntry.mnOffset;
2575 0 : aEnd.X() -= rEntry.mnOffset;
2576 : }
2577 0 : if (rEntry.mbOffsetStart)
2578 : // Apply offset at the start of a border.
2579 0 : aStart.Y() -= rEntry.mnOffset;
2580 0 : if (rEntry.mbOffsetEnd)
2581 : // Apply offset at the end of a border.
2582 0 : aEnd.Y() += rEntry.mnOffset;
2583 : }
2584 : }
2585 :
2586 0 : SwRect aRepaintRect( aStart, aEnd );
2587 :
2588 : // the repaint rectangle has to be moved a bit for the centered lines:
2589 0 : SwTwips nRepaintRectSize = !rEntryStyle.GetWidth() ? 1 : rEntryStyle.GetWidth();
2590 0 : if ( bHori )
2591 : {
2592 0 : aRepaintRect.Height( 2 * nRepaintRectSize );
2593 0 : aRepaintRect.Pos().Y() -= nRepaintRectSize;
2594 : }
2595 : else
2596 : {
2597 0 : aRepaintRect.Width( 2 * nRepaintRectSize );
2598 0 : aRepaintRect.Pos().X() -= nRepaintRectSize;
2599 : }
2600 :
2601 0 : if (!rRect.IsOver(aRepaintRect))
2602 : {
2603 0 : continue;
2604 : }
2605 :
2606 : // subsidiary lines
2607 0 : const Color* pTmpColor = 0;
2608 0 : if (0 == aStyles[ 0 ].GetWidth())
2609 : {
2610 0 : if (isTableBoundariesEnabled() && pGlobalShell->GetWin())
2611 0 : aStyles[ 0 ].Set( rCol, rCol, rCol, false, 1, 0, 0 );
2612 : else
2613 0 : aStyles[0].SetType(table::BorderLineStyle::NONE);
2614 : }
2615 : else
2616 0 : pTmpColor = pHCColor;
2617 :
2618 : // The (twip) positions will be adjusted to meet these requirements:
2619 : // 1. The y coordinates are located in the middle of the pixel grid
2620 : // 2. The x coordinated are located at the beginning of the pixel grid
2621 : // This is done, because the horizontal lines are painted "at
2622 : // beginning", whereas the vertical lines are painted "centered".
2623 : // By making the line sizes a multiple of one pixel size, we can
2624 : // assure that all lines having the same twip size have the same
2625 : // pixel size, independent of their position on the screen.
2626 0 : Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel(aStart) );
2627 0 : Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel(aEnd) );
2628 :
2629 0 : if (pGlobalShell->GetWin())
2630 : {
2631 : // The table borders do not use SwAlignRect, but all the other frames do.
2632 : // Therefore we tweak the outer borders a bit to achieve that the outer
2633 : // borders match the subsidiary lines of the upper:
2634 0 : if (aStart.X() == aUpper.Left())
2635 0 : aPaintStart.X() = aUpperAligned.Left();
2636 0 : else if (aStart.X() == aUpper._Right())
2637 0 : aPaintStart.X() = aUpperAligned._Right();
2638 0 : if (aStart.Y() == aUpper.Top())
2639 0 : aPaintStart.Y() = aUpperAligned.Top();
2640 0 : else if (aStart.Y() == aUpper._Bottom())
2641 0 : aPaintStart.Y() = aUpperAligned._Bottom();
2642 :
2643 0 : if (aEnd.X() == aUpper.Left())
2644 0 : aPaintEnd.X() = aUpperAligned.Left();
2645 0 : else if (aEnd.X() == aUpper._Right())
2646 0 : aPaintEnd.X() = aUpperAligned._Right();
2647 0 : if (aEnd.Y() == aUpper.Top())
2648 0 : aPaintEnd.Y() = aUpperAligned.Top();
2649 0 : else if (aEnd.Y() == aUpper._Bottom())
2650 0 : aPaintEnd.Y() = aUpperAligned._Bottom();
2651 : }
2652 :
2653 : // logically vertical lines are painted centered on the line,
2654 : // logically horizontal lines are painted "below" the line
2655 0 : bool const isBelow((mrTabFrm.IsVertical()) ? !bHori : bHori);
2656 : double const offsetStart = (isBelow)
2657 0 : ? aStyles[0].GetWidth() / 2.0
2658 0 : : std::max<double>(aStyles[1].GetWidth(),
2659 0 : aStyles[3].GetWidth()) / 2.0;
2660 : double const offsetEnd = (isBelow)
2661 0 : ? aStyles[0].GetWidth() / 2.0
2662 0 : : std::max<double>(aStyles[4].GetWidth(),
2663 0 : aStyles[6].GetWidth()) / 2.0;
2664 0 : if (mrTabFrm.IsVertical())
2665 : {
2666 0 : aPaintStart.X() -= static_cast<long>(offsetStart + 0.5);
2667 0 : aPaintEnd.X() -= static_cast<long>(offsetEnd + 0.5);
2668 : }
2669 : else
2670 : {
2671 0 : aPaintStart.Y() += static_cast<long>(offsetStart + 0.5);
2672 0 : aPaintEnd.Y() += static_cast<long>(offsetEnd + 0.5);
2673 : }
2674 :
2675 0 : if (bHori)
2676 : {
2677 : mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
2678 : aPaintStart,
2679 : aPaintEnd,
2680 : aStyles[ 0 ], // current style
2681 : aStyles[ 1 ], // aLFromT
2682 : aStyles[ 2 ], // aLFromL
2683 : aStyles[ 3 ], // aLFromB
2684 : aStyles[ 4 ], // aRFromT
2685 : aStyles[ 5 ], // aRFromR
2686 : aStyles[ 6 ], // aRFromB
2687 : pTmpColor)
2688 0 : );
2689 : }
2690 : else
2691 : {
2692 : mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
2693 : aPaintEnd,
2694 : aPaintStart,
2695 : aStyles[ 0 ], // current style
2696 : aStyles[ 4 ], // aBFromL
2697 : aStyles[ 5 ], // aBFromB
2698 : aStyles[ 6 ], // aBFromR
2699 : aStyles[ 1 ], // aTFromL
2700 : aStyles[ 2 ], // aTFromT
2701 : aStyles[ 3 ], // aTFromR
2702 : pTmpColor)
2703 0 : );
2704 : }
2705 : }
2706 :
2707 0 : ++aIter;
2708 : }
2709 :
2710 : // restore output device:
2711 0 : rDev.SetDrawMode( nOldDrawMode );
2712 0 : }
2713 :
2714 : // Finds the lines that join the line defined by (StartPoint, EndPoint) in either
2715 : // StartPoint or Endpoint. The styles of these lines are required for DR's magic
2716 : // line painting functions.
2717 0 : void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint,
2718 : const Point& rEndPoint,
2719 : svx::frame::Style* pStyles,
2720 : bool bHori ) const
2721 : {
2722 : // pStyles[ 1 ] = bHori ? aLFromT : TFromL
2723 : // pStyles[ 2 ] = bHori ? aLFromL : TFromT,
2724 : // pStyles[ 3 ] = bHori ? aLFromB : TFromR,
2725 : // pStyles[ 4 ] = bHori ? aRFromT : BFromL,
2726 : // pStyles[ 5 ] = bHori ? aRFromR : BFromB,
2727 : // pStyles[ 6 ] = bHori ? aRFromB : BFromR,
2728 :
2729 0 : SwLineEntryMapConstIter aMapIter = maVertLines.find( rStartPoint.X() );
2730 : OSL_ENSURE( aMapIter != maVertLines.end(), "FindStylesForLine: Error" );
2731 0 : const SwLineEntrySet& rVertSet = (*aMapIter).second;
2732 0 : SwLineEntrySetConstIter aIter = rVertSet.begin();
2733 :
2734 0 : while ( aIter != rVertSet.end() )
2735 : {
2736 0 : const SwLineEntry& rEntry = *aIter;
2737 0 : if ( bHori )
2738 : {
2739 0 : if ( rStartPoint.Y() == rEntry.mnStartPos )
2740 0 : pStyles[ 3 ] = rEntry.maAttribute;
2741 0 : else if ( rStartPoint.Y() == rEntry.mnEndPos )
2742 0 : pStyles[ 1 ] = rEntry.maAttribute;
2743 : }
2744 : else
2745 : {
2746 0 : if ( rStartPoint.Y() == rEntry.mnEndPos )
2747 0 : pStyles[ 2 ] = rEntry.maAttribute;
2748 0 : else if ( rEndPoint.Y() == rEntry.mnStartPos )
2749 0 : pStyles[ 5 ] = rEntry.maAttribute;
2750 : }
2751 0 : ++aIter;
2752 : }
2753 :
2754 0 : aMapIter = maHoriLines.find( rStartPoint.Y() );
2755 : OSL_ENSURE( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" );
2756 0 : const SwLineEntrySet& rHoriSet = (*aMapIter).second;
2757 0 : aIter = rHoriSet.begin();
2758 :
2759 0 : while ( aIter != rHoriSet.end() )
2760 : {
2761 0 : const SwLineEntry& rEntry = *aIter;
2762 0 : if ( bHori )
2763 : {
2764 0 : if ( rStartPoint.X() == rEntry.mnEndPos )
2765 0 : pStyles[ 2 ] = rEntry.maAttribute;
2766 0 : else if ( rEndPoint.X() == rEntry.mnStartPos )
2767 0 : pStyles[ 5 ] = rEntry.maAttribute;
2768 : }
2769 : else
2770 : {
2771 0 : if ( rStartPoint.X() == rEntry.mnEndPos )
2772 0 : pStyles[ 1 ] = rEntry.maAttribute;
2773 0 : else if ( rStartPoint.X() == rEntry.mnStartPos )
2774 0 : pStyles[ 3 ] = rEntry.maAttribute;
2775 : }
2776 0 : ++aIter;
2777 : }
2778 :
2779 0 : if ( bHori )
2780 : {
2781 0 : aMapIter = maVertLines.find( rEndPoint.X() );
2782 : OSL_ENSURE( aMapIter != maVertLines.end(), "FindStylesForLine: Error" );
2783 0 : const SwLineEntrySet& rVertSet2 = (*aMapIter).second;
2784 0 : aIter = rVertSet2.begin();
2785 :
2786 0 : while ( aIter != rVertSet2.end() )
2787 : {
2788 0 : const SwLineEntry& rEntry = *aIter;
2789 0 : if ( rEndPoint.Y() == rEntry.mnStartPos )
2790 0 : pStyles[ 6 ] = rEntry.maAttribute;
2791 0 : else if ( rEndPoint.Y() == rEntry.mnEndPos )
2792 0 : pStyles[ 4 ] = rEntry.maAttribute;
2793 0 : ++aIter;
2794 : }
2795 : }
2796 : else
2797 : {
2798 0 : aMapIter = maHoriLines.find( rEndPoint.Y() );
2799 : OSL_ENSURE( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" );
2800 0 : const SwLineEntrySet& rHoriSet2 = (*aMapIter).second;
2801 0 : aIter = rHoriSet2.begin();
2802 :
2803 0 : while ( aIter != rHoriSet2.end() )
2804 : {
2805 0 : const SwLineEntry& rEntry = *aIter;
2806 0 : if ( rEndPoint.X() == rEntry.mnEndPos )
2807 0 : pStyles[ 4 ] = rEntry.maAttribute;
2808 0 : else if ( rEndPoint.X() == rEntry.mnStartPos )
2809 0 : pStyles[ 6 ] = rEntry.maAttribute;
2810 0 : ++aIter;
2811 : }
2812 : }
2813 0 : }
2814 :
2815 : namespace {
2816 :
2817 0 : void calcOffsetForDoubleLine( SwLineEntryMap& rLines )
2818 : {
2819 0 : SwLineEntryMap aNewLines;
2820 0 : SwLineEntryMap::iterator it = rLines.begin(), itEnd = rLines.end();
2821 0 : bool bFirst = true;
2822 0 : for (; it != itEnd; ++it)
2823 : {
2824 0 : if (bFirst)
2825 : {
2826 : // First line needs to be offset to account for double line thickness.
2827 0 : SwLineEntrySet aNewSet;
2828 0 : const SwLineEntrySet& rSet = it->second;
2829 0 : SwLineEntrySet::iterator itSet = rSet.begin(), itSetEnd = rSet.end();
2830 0 : size_t nEntryCount = rSet.size();
2831 0 : for (size_t i = 0; itSet != itSetEnd; ++itSet, ++i)
2832 : {
2833 0 : SwLineEntry aLine = *itSet;
2834 0 : if (aLine.maAttribute.Secn())
2835 : {
2836 : // Apply offset only for double lines.
2837 0 : aLine.mnOffset = static_cast<SwTwips>(aLine.maAttribute.Dist());
2838 0 : aLine.mbOffsetPerp = true;
2839 :
2840 0 : if (i == 0)
2841 0 : aLine.mbOffsetStart = true;
2842 0 : if (i == nEntryCount - 1)
2843 0 : aLine.mbOffsetEnd = true;
2844 : }
2845 :
2846 0 : aNewSet.insert(aLine);
2847 : }
2848 :
2849 0 : aNewLines.insert(SwLineEntryMap::value_type(it->first, aNewSet));
2850 : }
2851 : else
2852 0 : aNewLines.insert(SwLineEntryMap::value_type(it->first, it->second));
2853 :
2854 0 : bFirst = false;
2855 : }
2856 0 : rLines.swap(aNewLines);
2857 0 : }
2858 :
2859 : }
2860 :
2861 0 : void SwTabFrmPainter::AdjustTopLeftFrames()
2862 : {
2863 0 : calcOffsetForDoubleLine(maHoriLines);
2864 0 : calcOffsetForDoubleLine(maVertLines);
2865 0 : }
2866 :
2867 : // special case: #i9860#
2868 : // first line in follow table without repeated headlines
2869 0 : static bool lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines(
2870 : SwTabFrm const& rTabFrm, SwFrm const& rFrm, SvxBoxItem const& rBoxItem)
2871 : {
2872 : SwRowFrm const*const pThisRowFrm =
2873 0 : dynamic_cast<const SwRowFrm*>(rFrm.GetUpper());
2874 : return (pThisRowFrm
2875 0 : && (pThisRowFrm->GetUpper() == &rTabFrm)
2876 0 : && rTabFrm.IsFollow()
2877 0 : && !rTabFrm.GetTable()->GetRowsToRepeat()
2878 0 : && ( !pThisRowFrm->GetPrev()
2879 0 : || static_cast<const SwRowFrm*>(pThisRowFrm->GetPrev())
2880 0 : ->IsRowSpanLine())
2881 0 : && !rBoxItem.GetTop()
2882 0 : && rBoxItem.GetBottom());
2883 : }
2884 :
2885 0 : void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem )
2886 : {
2887 : // build 4 line entries for the 4 borders:
2888 0 : SwRect aBorderRect = rFrm.Frm();
2889 0 : if ( rFrm.IsTabFrm() )
2890 : {
2891 0 : aBorderRect = rFrm.Prt();
2892 0 : aBorderRect.Pos() += rFrm.Frm().Pos();
2893 : }
2894 :
2895 : bool const bBottomAsTop(lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines(
2896 0 : mrTabFrm, rFrm, rBoxItem));
2897 0 : bool const bVert = mrTabFrm.IsVertical();
2898 0 : bool const bR2L = mrTabFrm.IsRightToLeft();
2899 :
2900 0 : SwViewShell* pViewShell = mrTabFrm.getRootFrm()->GetCurrShell();
2901 0 : OutputDevice* pOutDev = pViewShell->GetOut();
2902 0 : const MapMode& rMapMode = pOutDev->GetMapMode();
2903 0 : const Fraction& rFracX = rMapMode.GetScaleX();
2904 0 : const Fraction& rFracY = rMapMode.GetScaleY();
2905 :
2906 0 : svx::frame::Style aL(rBoxItem.GetLeft());
2907 0 : aL.SetPatternScale(rFracY);
2908 0 : svx::frame::Style aR(rBoxItem.GetRight());
2909 0 : aR.SetPatternScale(rFracY);
2910 0 : svx::frame::Style aT(rBoxItem.GetTop());
2911 0 : aT.SetPatternScale(rFracX);
2912 0 : svx::frame::Style aB(rBoxItem.GetBottom());
2913 0 : aB.SetPatternScale(rFracX);
2914 :
2915 0 : aR.MirrorSelf();
2916 0 : aB.MirrorSelf();
2917 :
2918 0 : const SwTwips nLeft = aBorderRect._Left();
2919 0 : const SwTwips nRight = aBorderRect._Right();
2920 0 : const SwTwips nTop = aBorderRect._Top();
2921 0 : const SwTwips nBottom = aBorderRect._Bottom();
2922 :
2923 0 : aL.SetRefMode( svx::frame::REFMODE_CENTERED );
2924 0 : aR.SetRefMode( svx::frame::REFMODE_CENTERED );
2925 0 : aT.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
2926 0 : aB.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
2927 :
2928 : SwLineEntry aLeft (nLeft, nTop, nBottom,
2929 0 : (bVert) ? aB : ((bR2L) ? aR : aL));
2930 : SwLineEntry aRight (nRight, nTop, nBottom,
2931 0 : (bVert) ? ((bBottomAsTop) ? aB : aT) : ((bR2L) ? aL : aR));
2932 : SwLineEntry aTop (nTop, nLeft, nRight,
2933 0 : (bVert) ? aL : ((bBottomAsTop) ? aB : aT));
2934 : SwLineEntry aBottom(nBottom, nLeft, nRight,
2935 0 : (bVert) ? aR : aB);
2936 :
2937 0 : Insert( aLeft, false );
2938 0 : Insert( aRight, false );
2939 0 : Insert( aTop, true );
2940 0 : Insert( aBottom, true );
2941 0 : }
2942 :
2943 0 : void SwTabFrmPainter::Insert( SwLineEntry& rNew, bool bHori )
2944 : {
2945 : // get all lines from structure, that have key entry of pLE
2946 0 : SwLineEntryMap* pLine2 = bHori ? &maHoriLines : &maVertLines;
2947 0 : const SwTwips nKey = rNew.mnKey;
2948 0 : SwLineEntryMapIter aMapIter = pLine2->find( nKey );
2949 :
2950 0 : SwLineEntrySet* pLineSet = aMapIter != pLine2->end() ? &((*aMapIter).second) : 0;
2951 0 : if ( !pLineSet )
2952 : {
2953 0 : SwLineEntrySet aNewSet;
2954 0 : (*pLine2)[ nKey ] = aNewSet;
2955 0 : pLineSet = &(*pLine2)[ nKey ];
2956 : }
2957 0 : SwLineEntrySetIter aIter = pLineSet->begin();
2958 :
2959 0 : while ( aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos )
2960 : {
2961 0 : const SwLineEntry& rOld = *aIter;
2962 0 : const SwLineEntry::OverlapType nOverlapType = rOld.Overlaps( rNew );
2963 :
2964 0 : const svx::frame::Style& rOldAttr = rOld.maAttribute;
2965 0 : const svx::frame::Style& rNewAttr = rNew.maAttribute;
2966 0 : const svx::frame::Style& rCmpAttr = rNewAttr > rOldAttr ? rNewAttr : rOldAttr;
2967 :
2968 0 : if ( SwLineEntry::OVERLAP1 == nOverlapType )
2969 : {
2970 : OSL_ENSURE( rNew.mnStartPos >= rOld.mnStartPos, "Overlap type 3? How this?" );
2971 :
2972 : // new left segment
2973 0 : const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
2974 :
2975 : // new middle segment
2976 0 : const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rOld.mnEndPos, rCmpAttr );
2977 :
2978 : // new right segment
2979 0 : rNew.mnStartPos = rOld.mnEndPos;
2980 :
2981 : // update current lines set
2982 0 : pLineSet->erase( aIter );
2983 0 : if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
2984 0 : if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2985 :
2986 0 : aIter = pLineSet->begin();
2987 :
2988 0 : continue; // start over
2989 : }
2990 0 : else if ( SwLineEntry::OVERLAP2 == nOverlapType )
2991 : {
2992 : // new left segment
2993 0 : const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
2994 :
2995 : // new middle segment
2996 0 : const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rNew.mnEndPos, rCmpAttr );
2997 :
2998 : // new right segment
2999 0 : const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr );
3000 :
3001 : // update current lines set
3002 0 : pLineSet->erase( aIter );
3003 0 : if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
3004 0 : if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
3005 0 : if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
3006 :
3007 0 : rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
3008 :
3009 0 : break; // we are finished
3010 : }
3011 0 : else if ( SwLineEntry::OVERLAP3 == nOverlapType )
3012 : {
3013 : // new left segment
3014 0 : const SwLineEntry aLeft( nKey, rNew.mnStartPos, rOld.mnStartPos, rNewAttr );
3015 :
3016 : // new middle segment
3017 0 : const SwLineEntry aMiddle( nKey, rOld.mnStartPos, rNew.mnEndPos, rCmpAttr );
3018 :
3019 : // new right segment
3020 0 : const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr );
3021 :
3022 : // update current lines set
3023 0 : pLineSet->erase( aIter );
3024 0 : if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
3025 0 : if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
3026 0 : if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
3027 :
3028 0 : rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
3029 :
3030 0 : break; // we are finished
3031 : }
3032 :
3033 0 : ++aIter;
3034 : }
3035 :
3036 0 : if ( rNew.mnStartPos < rNew.mnEndPos ) // insert rest
3037 0 : pLineSet->insert( rNew );
3038 0 : }
3039 :
3040 : // FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES END
3041 :
3042 : // --> OD #i76669#
3043 : namespace
3044 : {
3045 : class SwViewObjectContactRedirector : public ::sdr::contact::ViewObjectContactRedirector
3046 : {
3047 : private:
3048 : const SwViewShell& mrViewShell;
3049 :
3050 : public:
3051 0 : SwViewObjectContactRedirector( const SwViewShell& rSh )
3052 0 : : mrViewShell( rSh )
3053 0 : {};
3054 :
3055 0 : virtual ~SwViewObjectContactRedirector()
3056 0 : {}
3057 :
3058 0 : virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence(
3059 : const sdr::contact::ViewObjectContact& rOriginal,
3060 : const sdr::contact::DisplayInfo& rDisplayInfo) SAL_OVERRIDE
3061 : {
3062 0 : sal_Bool bPaint( sal_True );
3063 :
3064 0 : SdrObject* pObj = rOriginal.GetViewContact().TryToGetSdrObject();
3065 0 : if ( pObj )
3066 : {
3067 0 : bPaint = SwFlyFrm::IsPaint( pObj, &mrViewShell );
3068 : }
3069 :
3070 0 : if ( !bPaint )
3071 : {
3072 0 : return drawinglayer::primitive2d::Primitive2DSequence();
3073 : }
3074 :
3075 : return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
3076 0 : rOriginal, rDisplayInfo );
3077 : }
3078 : };
3079 :
3080 : } // end of anonymous namespace
3081 : // <--
3082 : /** Paint once for every visible page which is touched by Rect.
3083 : |*
3084 : |* 1. Paint borders and backgrounds.
3085 : |* 2. Paint the draw layer (frames and drawing objects) that is
3086 : |* below the document (hell).
3087 : |* 3. Paint the document content (text)
3088 : |* 4. Paint the draw layer that is above the document.
3089 : |*/
3090 0 : void SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const
3091 : {
3092 : OSL_ENSURE( Lower() && Lower()->IsPageFrm(), "Lower of root is no page." );
3093 :
3094 : PROTOCOL( this, PROT_FILE_INIT, 0, 0)
3095 :
3096 0 : bool bResetRootPaint = false;
3097 0 : SwViewShell *pSh = pCurrShell;
3098 :
3099 0 : if ( pSh->GetWin() )
3100 : {
3101 0 : if ( pSh->GetOut() == pSh->GetWin() && !pSh->GetWin()->IsVisible() )
3102 : {
3103 0 : return;
3104 : }
3105 0 : if ( SwRootFrm::bInPaint )
3106 : {
3107 0 : SwPaintQueue::Add( pSh, rRect );
3108 0 : return;
3109 : }
3110 : }
3111 : else
3112 0 : SwRootFrm::bInPaint = bResetRootPaint = true;
3113 :
3114 0 : SwSavePaintStatics *pStatics = 0;
3115 0 : if ( pGlobalShell )
3116 0 : pStatics = new SwSavePaintStatics();
3117 0 : pGlobalShell = pSh;
3118 :
3119 0 : if( !pSh->GetWin() )
3120 0 : pProgress = SfxProgress::GetActiveProgress( (SfxObjectShell*) pSh->GetDoc()->GetDocShell() );
3121 :
3122 0 : ::SwCalcPixStatics( pSh->GetOut() );
3123 0 : aGlobalRetoucheColor = pSh->Imp()->GetRetoucheColor();
3124 :
3125 : //Trigger an action to clear things up if needed.
3126 : //Using this trick we can ensure that all values are valid in all paints -
3127 : //no problems, no special case(s).
3128 : // #i92745#
3129 : // Extend check on certain states of the 'current' <SwViewShell> instance to
3130 : // all existing <SwViewShell> instances.
3131 0 : bool bPerformLayoutAction( true );
3132 : {
3133 0 : SwViewShell* pTmpViewShell = pSh;
3134 0 : do {
3135 0 : if ( pTmpViewShell->IsInEndAction() ||
3136 0 : pTmpViewShell->IsPaintInProgress() ||
3137 0 : ( pTmpViewShell->Imp()->IsAction() &&
3138 0 : pTmpViewShell->Imp()->GetLayAction().IsActionInProgress() ) )
3139 : {
3140 0 : bPerformLayoutAction = false;
3141 : }
3142 :
3143 0 : pTmpViewShell = static_cast<SwViewShell*>(pTmpViewShell->GetNext());
3144 0 : } while ( bPerformLayoutAction && pTmpViewShell != pSh );
3145 : }
3146 0 : if ( bPerformLayoutAction )
3147 : {
3148 0 : ((SwRootFrm*)this)->ResetTurbo();
3149 0 : SwLayAction aAction( (SwRootFrm*)this, pSh->Imp() );
3150 0 : aAction.SetPaint( sal_False );
3151 0 : aAction.SetComplete( sal_False );
3152 0 : aAction.SetReschedule( pProgress ? sal_True : sal_False );
3153 0 : aAction.Action();
3154 0 : ((SwRootFrm*)this)->ResetTurboFlag();
3155 0 : if ( !pSh->ActionPend() )
3156 0 : pSh->Imp()->DelRegion();
3157 : }
3158 :
3159 0 : SwRect aRect( rRect );
3160 0 : aRect.Intersection( pSh->VisArea() );
3161 :
3162 0 : const bool bExtraData = ::IsExtraData( GetFmt()->GetDoc() );
3163 :
3164 0 : pLines = new SwLineRects; //Container for borders.
3165 :
3166 : // #104289#. During painting, something (OLE) can
3167 : // load the linguistic, which in turn can cause a reformat
3168 : // of the document. Dangerous! We better set this flag to
3169 : // avoid the reformat.
3170 0 : const sal_Bool bOldAction = IsCallbackActionEnabled();
3171 0 : ((SwRootFrm*)this)->SetCallbackActionEnabled( sal_False );
3172 :
3173 0 : const SwPageFrm *pPage = pSh->Imp()->GetFirstVisPage();
3174 :
3175 0 : const bool bBookMode = pGlobalShell->GetViewOptions()->IsViewLayoutBookMode();
3176 0 : if ( bBookMode && pPage->GetPrev() && static_cast<const SwPageFrm*>(pPage->GetPrev())->IsEmptyPage() )
3177 0 : pPage = static_cast<const SwPageFrm*>(pPage->GetPrev());
3178 :
3179 : // #i68597#
3180 0 : const bool bGridPainting(pSh->GetWin() && pSh->Imp()->HasDrawView() && pSh->Imp()->GetDrawView()->IsGridVisible());
3181 :
3182 : // Hide all page break controls before showing them again
3183 0 : SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pGlobalShell );
3184 0 : if ( pWrtSh )
3185 : {
3186 0 : SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
3187 0 : SwFrameControlsManager& rMngr = rEditWin.GetFrameControlsManager();
3188 0 : const SwPageFrm* pHiddenPage = pPage;
3189 0 : while ( pHiddenPage->GetPrev() != NULL )
3190 : {
3191 0 : pHiddenPage = static_cast< const SwPageFrm* >( pHiddenPage->GetPrev() );
3192 0 : SwFrameControlPtr pControl = rMngr.GetControl( PageBreak, pHiddenPage );
3193 0 : if ( pControl.get() )
3194 0 : pControl->ShowAll( false );
3195 0 : }
3196 : }
3197 :
3198 : // #i76669#
3199 0 : SwViewObjectContactRedirector aSwRedirector( *pSh );
3200 :
3201 0 : while ( pPage )
3202 : {
3203 0 : const bool bPaintRightShadow = pPage->IsRightShadowNeeded();
3204 0 : const bool bPaintLeftShadow = pPage->IsLeftShadowNeeded();
3205 0 : const bool bRightSidebar = pPage->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT;
3206 :
3207 0 : if ( !pPage->IsEmptyPage() )
3208 : {
3209 0 : SwRect aPaintRect;
3210 0 : SwPageFrm::GetBorderAndShadowBoundRect( pPage->Frm(), pSh, aPaintRect,
3211 0 : bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3212 :
3213 0 : if ( aRect.IsOver( aPaintRect ) )
3214 : {
3215 0 : if ( pSh->GetWin() )
3216 : {
3217 0 : pSubsLines = new SwSubsRects;
3218 0 : pSpecSubsLines = new SwSubsRects;
3219 : }
3220 0 : g_pBorderLines = new BorderLines;
3221 :
3222 0 : aPaintRect._Intersection( aRect );
3223 :
3224 0 : if ( bExtraData &&
3225 0 : pSh->GetWin() && pSh->IsInEndAction() )
3226 : {
3227 : // enlarge paint rectangle to complete page width, subtract
3228 : // current paint area and invalidate the resulting region.
3229 0 : SWRECTFN( pPage )
3230 0 : SwRect aPageRectTemp( aPaintRect );
3231 : (aPageRectTemp.*fnRect->fnSetLeftAndWidth)(
3232 0 : (pPage->Frm().*fnRect->fnGetLeft)(),
3233 0 : (pPage->Frm().*fnRect->fnGetWidth)() );
3234 0 : aPageRectTemp._Intersection( pSh->VisArea() );
3235 0 : Region aPageRectRegion( aPageRectTemp.SVRect() );
3236 0 : aPageRectRegion.Exclude( aPaintRect.SVRect() );
3237 0 : pSh->GetWin()->Invalidate( aPageRectRegion, INVALIDATE_CHILDREN );
3238 : }
3239 :
3240 : // #i80793#
3241 : // enlarge paint rectangle for objects overlapping the same pixel
3242 : // in all cases and before the DrawingLayer overlay is initialized.
3243 0 : lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
3244 :
3245 : // #i68597#
3246 : // moved paint pre-process for DrawingLayer overlay here since the above
3247 : // code dependent from bExtraData may expand the PaintRect
3248 : {
3249 : // #i75172# if called from SwViewShell::ImplEndAction it sould no longer
3250 : // really be used but handled by SwViewShell::ImplEndAction already
3251 0 : const Region aDLRegion(aPaintRect.SVRect());
3252 0 : pSh->DLPrePaint2(aDLRegion);
3253 : }
3254 :
3255 0 : if(OUTDEV_WINDOW == pGlobalShell->GetOut()->GetOutDevType())
3256 : {
3257 : // OD 27.09.2002 #103636# - changed method SwLayVout::Enter(..)
3258 : // 2nd parameter is no longer <const> and will be set to the
3259 : // rectangle the virtual output device is calculated from <aPaintRect>,
3260 : // if the virtual output is used.
3261 0 : pVout->Enter( pSh, aPaintRect, !bNoVirDev );
3262 :
3263 : // OD 27.09.2002 #103636# - adjust paint rectangle to pixel size
3264 : // Thus, all objects overlapping on pixel level with the unadjusted
3265 : // paint rectangle will be considered in the paint.
3266 0 : lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
3267 : }
3268 :
3269 : // maybe this can be put in the above scope. Since we are not sure, just leave it ATM
3270 0 : pVout->SetOrgRect( aPaintRect );
3271 :
3272 : // OD 29.08.2002 #102450#
3273 : // determine background color of page for <PaintLayer> method
3274 : // calls, paint <hell> or <heaven>
3275 0 : const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
3276 :
3277 0 : pPage->PaintBaBo( aPaintRect, pPage, sal_True );
3278 :
3279 0 : if ( pSh->Imp()->HasDrawView() )
3280 : {
3281 0 : pLines->LockLines( sal_True );
3282 0 : const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
3283 0 : pSh->Imp()->PaintLayer( pIDDMA->GetHellId(),
3284 : pPrintData,
3285 0 : pPage->Frm(),
3286 : &aPageBackgrdColor,
3287 : (pPage->IsRightToLeft() ? true : false),
3288 0 : &aSwRedirector );
3289 0 : pLines->PaintLines( pSh->GetOut() );
3290 0 : pLines->LockLines( sal_False );
3291 : }
3292 :
3293 0 : if ( pSh->GetDoc()->get( IDocumentSettingAccess::BACKGROUND_PARA_OVER_DRAWINGS ) )
3294 0 : pPage->PaintBaBo( aPaintRect, pPage, sal_True, /*bOnlyTxtBackground=*/true );
3295 :
3296 0 : if( pSh->GetWin() )
3297 : {
3298 : // collect sub-lines
3299 0 : pPage->RefreshSubsidiary( aPaintRect );
3300 : // paint special sub-lines
3301 0 : pSpecSubsLines->PaintSubsidiary( pSh->GetOut(), NULL );
3302 : }
3303 :
3304 0 : pPage->Paint( aPaintRect );
3305 :
3306 : // no paint of page border and shadow, if writer is in place mode.
3307 0 : if( pSh->GetWin() && pSh->GetDoc()->GetDocShell() &&
3308 0 : !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
3309 : {
3310 0 : SwPageFrm::PaintBorderAndShadow( pPage->Frm(), pSh, bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3311 0 : SwPageFrm::PaintNotesSidebar( pPage->Frm(), pSh, pPage->GetPhyPageNum(), bRightSidebar);
3312 : }
3313 :
3314 0 : pLines->PaintLines( pSh->GetOut() );
3315 0 : if ( pSh->GetWin() )
3316 : {
3317 0 : pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines );
3318 0 : DELETEZ( pSubsLines );
3319 0 : DELETEZ( pSpecSubsLines );
3320 : }
3321 : // fdo#42750: delay painting these until after subsidiary lines
3322 : // fdo#45562: delay painting these until after hell layer
3323 : // fdo#47717: but do it before heaven layer
3324 0 : ProcessPrimitives(g_pBorderLines->GetBorderLines_Clear());
3325 :
3326 0 : if ( pSh->Imp()->HasDrawView() )
3327 : {
3328 : // OD 29.08.2002 #102450# - add 3rd parameter
3329 : // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
3330 0 : pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(),
3331 : pPrintData,
3332 0 : pPage->Frm(),
3333 : &aPageBackgrdColor,
3334 : (pPage->IsRightToLeft() ? true : false),
3335 0 : &aSwRedirector );
3336 : }
3337 :
3338 0 : if ( bExtraData )
3339 0 : pPage->RefreshExtraData( aPaintRect );
3340 :
3341 0 : DELETEZ(g_pBorderLines);
3342 0 : pVout->Leave();
3343 :
3344 : // #i68597#
3345 : // needed to move grid painting inside Begin/EndDrawLayer bounds and to change
3346 : // output rect for it accordingly
3347 0 : if(bGridPainting)
3348 : {
3349 0 : SdrPaintView* pPaintView = pSh->Imp()->GetDrawView();
3350 0 : SdrPageView* pPageView = pPaintView->GetSdrPageView();
3351 0 : pPageView->DrawPageViewGrid(*pSh->GetOut(), aPaintRect.SVRect(), SwViewOption::GetTextGridColor() );
3352 : }
3353 :
3354 : // #i68597#
3355 : // moved paint post-process for DrawingLayer overlay here, see above
3356 : {
3357 0 : pSh->DLPostPaint2(true);
3358 : }
3359 : }
3360 :
3361 0 : pPage->PaintDecorators( );
3362 0 : pPage->PaintBreak();
3363 : }
3364 0 : else if ( bBookMode && pSh->GetWin() && !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
3365 : {
3366 : // paint empty page
3367 0 : SwRect aPaintRect;
3368 0 : SwRect aEmptyPageRect( pPage->Frm() );
3369 :
3370 : // code from vprint.cxx
3371 0 : const SwPageFrm& rFormatPage = pPage->GetFormatPage();
3372 0 : aEmptyPageRect.SSize() = rFormatPage.Frm().SSize();
3373 :
3374 : SwPageFrm::GetBorderAndShadowBoundRect( aEmptyPageRect, pSh, aPaintRect,
3375 0 : bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3376 0 : aPaintRect._Intersection( aRect );
3377 :
3378 0 : if ( aRect.IsOver( aEmptyPageRect ) )
3379 : {
3380 : // #i75172# if called from SwViewShell::ImplEndAction it sould no longer
3381 : // really be used but handled by SwViewShell::ImplEndAction already
3382 : {
3383 0 : const Region aDLRegion(aPaintRect.SVRect());
3384 0 : pSh->DLPrePaint2(aDLRegion);
3385 : }
3386 :
3387 0 : if( pSh->GetOut()->GetFillColor() != aGlobalRetoucheColor )
3388 0 : pSh->GetOut()->SetFillColor( aGlobalRetoucheColor );
3389 :
3390 0 : pSh->GetOut()->SetLineColor(); // OD 20.02.2003 #107369# - no line color
3391 : // OD 20.02.2003 #107369# - use aligned page rectangle
3392 : {
3393 0 : SwRect aTmpPageRect( aEmptyPageRect );
3394 0 : ::SwAlignRect( aTmpPageRect, pSh );
3395 0 : aEmptyPageRect = aTmpPageRect;
3396 : }
3397 :
3398 0 : pSh->GetOut()->DrawRect( aEmptyPageRect.SVRect() );
3399 :
3400 : // paint empty page text
3401 0 : const Font& rEmptyPageFont = SwPageFrm::GetEmptyPageFont();
3402 0 : const Font aOldFont( pSh->GetOut()->GetFont() );
3403 :
3404 0 : pSh->GetOut()->SetFont( rEmptyPageFont );
3405 : pSh->GetOut()->DrawText( aEmptyPageRect.SVRect(), SW_RESSTR( STR_EMPTYPAGE ),
3406 : TEXT_DRAW_VCENTER |
3407 : TEXT_DRAW_CENTER |
3408 0 : TEXT_DRAW_CLIP );
3409 :
3410 0 : pSh->GetOut()->SetFont( aOldFont );
3411 : // paint shadow and border for empty page
3412 : // OD 19.02.2003 #107369# - use new method to paint page border and
3413 : // shadow
3414 0 : SwPageFrm::PaintBorderAndShadow( aEmptyPageRect, pSh, bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3415 0 : SwPageFrm::PaintNotesSidebar( aEmptyPageRect, pSh, pPage->GetPhyPageNum(), bRightSidebar);
3416 :
3417 : {
3418 0 : pSh->DLPostPaint2(true);
3419 0 : }
3420 : }
3421 : }
3422 :
3423 : OSL_ENSURE( !pPage->GetNext() || pPage->GetNext()->IsPageFrm(),
3424 : "Neighbour of page is not a page." );
3425 0 : pPage = (SwPageFrm*)pPage->GetNext();
3426 : }
3427 :
3428 0 : DELETEZ( pLines );
3429 :
3430 0 : if ( bResetRootPaint )
3431 0 : SwRootFrm::bInPaint = false;
3432 0 : if ( pStatics )
3433 0 : delete pStatics;
3434 : else
3435 : {
3436 0 : pProgress = 0;
3437 0 : pGlobalShell = 0;
3438 : }
3439 :
3440 0 : ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction );
3441 : }
3442 :
3443 0 : static void lcl_EmergencyFormatFtnCont( SwFtnContFrm *pCont )
3444 : {
3445 : //It's possible that the Cont will get destroyed.
3446 0 : SwCntntFrm *pCnt = pCont->ContainsCntnt();
3447 0 : while ( pCnt && pCnt->IsInFtn() )
3448 : {
3449 0 : pCnt->Calc();
3450 0 : pCnt = pCnt->GetNextCntntFrm();
3451 : }
3452 0 : }
3453 :
3454 : class SwShortCut
3455 : {
3456 : SwRectDist fnCheck;
3457 : long nLimit;
3458 : public:
3459 : SwShortCut( const SwFrm& rFrm, const SwRect& rRect );
3460 0 : bool Stop( const SwRect& rRect ) const
3461 0 : { return (rRect.*fnCheck)( nLimit ) > 0; }
3462 : };
3463 :
3464 0 : SwShortCut::SwShortCut( const SwFrm& rFrm, const SwRect& rRect )
3465 : {
3466 0 : bool bVert = rFrm.IsVertical();
3467 0 : bool bR2L = rFrm.IsRightToLeft();
3468 0 : if( rFrm.IsNeighbourFrm() && bVert == bR2L )
3469 : {
3470 0 : if( bVert )
3471 : {
3472 0 : fnCheck = &SwRect::GetBottomDistance;
3473 0 : nLimit = rRect.Top();
3474 : }
3475 : else
3476 : {
3477 0 : fnCheck = &SwRect::GetLeftDistance;
3478 0 : nLimit = rRect.Left() + rRect.Width();
3479 : }
3480 : }
3481 0 : else if( bVert == rFrm.IsNeighbourFrm() )
3482 : {
3483 0 : fnCheck = &SwRect::GetTopDistance;
3484 0 : nLimit = rRect.Top() + rRect.Height();
3485 : }
3486 : else
3487 : {
3488 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
3489 0 : if ( rFrm.IsVertLR() )
3490 : {
3491 0 : fnCheck = &SwRect::GetLeftDistance;
3492 0 : nLimit = rRect.Right();
3493 : }
3494 : else
3495 : {
3496 0 : fnCheck = &SwRect::GetRightDistance;
3497 0 : nLimit = rRect.Left();
3498 : }
3499 : }
3500 0 : }
3501 :
3502 0 : void SwLayoutFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
3503 : {
3504 0 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
3505 :
3506 : // #i16816# tagged pdf support
3507 0 : Frm_Info aFrmInfo( *this );
3508 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, &aFrmInfo, 0, *pSh->GetOut() );
3509 :
3510 0 : const SwFrm *pFrm = Lower();
3511 0 : if ( !pFrm )
3512 0 : return;
3513 :
3514 0 : SwShortCut aShortCut( *pFrm, rRect );
3515 : sal_Bool bCnt;
3516 0 : if ( sal_True == (bCnt = pFrm->IsCntntFrm()) )
3517 0 : pFrm->Calc();
3518 :
3519 0 : if ( pFrm->IsFtnContFrm() )
3520 : {
3521 0 : ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm );
3522 0 : pFrm = Lower();
3523 : }
3524 :
3525 0 : const SwPageFrm *pPage = 0;
3526 0 : const bool bWin = pGlobalShell->GetWin() ? true : false;
3527 :
3528 0 : while ( IsAnLower( pFrm ) )
3529 : {
3530 0 : SwRect aPaintRect( pFrm->PaintArea() );
3531 0 : if( aShortCut.Stop( aPaintRect ) )
3532 0 : break;
3533 0 : if ( bCnt && pProgress )
3534 0 : pProgress->Reschedule();
3535 :
3536 : //We need to retouch if a frame explicitly requests it.
3537 : //First do the retouch, because this could flatten the borders.
3538 0 : if ( pFrm->IsRetouche() )
3539 : {
3540 0 : if ( pFrm->IsRetoucheFrm() && bWin && !pFrm->GetNext() )
3541 0 : { if ( !pPage )
3542 0 : pPage = FindPageFrm();
3543 0 : pFrm->Retouche( pPage, rRect );
3544 : }
3545 0 : pFrm->ResetRetouche();
3546 : }
3547 :
3548 0 : if ( rRect.IsOver( aPaintRect ) )
3549 : {
3550 0 : if ( bCnt && pFrm->IsCompletePaint() &&
3551 0 : !rRect.IsInside( aPaintRect ) && GetpApp()->AnyInput( VCL_INPUT_KEYBOARD ) )
3552 : {
3553 : //fix(8104): It may happen, that the processing wasn't complete
3554 : //but some parts of the paragraph were still repainted.
3555 : //This could lead to the situation, that other parts of the
3556 : //paragraph won't be repainted at all. The only solution seems
3557 : //to be an invalidation of the window.
3558 : //To not make it too severe the rectangle is limited by
3559 : //painting the desired part and only invalidating the
3560 : //remaining paragraph parts.
3561 0 : if ( aPaintRect.Left() == rRect.Left() &&
3562 0 : aPaintRect.Right() == rRect.Right() )
3563 : {
3564 0 : aPaintRect.Bottom( rRect.Top() - 1 );
3565 0 : if ( aPaintRect.Height() > 0 )
3566 0 : pGlobalShell->InvalidateWindows(aPaintRect);
3567 0 : aPaintRect.Top( rRect.Bottom() + 1 );
3568 0 : aPaintRect.Bottom( pFrm->Frm().Bottom() );
3569 0 : if ( aPaintRect.Height() > 0 )
3570 0 : pGlobalShell->InvalidateWindows(aPaintRect);
3571 0 : aPaintRect.Top( pFrm->Frm().Top() );
3572 0 : aPaintRect.Bottom( pFrm->Frm().Bottom() );
3573 : }
3574 : else
3575 : {
3576 0 : pGlobalShell->InvalidateWindows( aPaintRect );
3577 0 : pFrm = pFrm->GetNext();
3578 0 : if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) )
3579 0 : pFrm->Calc();
3580 0 : continue;
3581 : }
3582 : }
3583 0 : pFrm->ResetCompletePaint();
3584 0 : aPaintRect._Intersection( rRect );
3585 :
3586 0 : pFrm->Paint( aPaintRect );
3587 :
3588 0 : if ( Lower() && Lower()->IsColumnFrm() )
3589 : {
3590 : //Paint the column separator line if needed. The page is
3591 : //responsible for the page frame - not the upper.
3592 0 : const SwFrmFmt *pFmt = GetUpper() && GetUpper()->IsPageFrm()
3593 0 : ? GetUpper()->GetFmt()
3594 0 : : GetFmt();
3595 0 : const SwFmtCol &rCol = pFmt->GetCol();
3596 0 : if ( rCol.GetLineAdj() != COLADJ_NONE )
3597 : {
3598 0 : if ( !pPage )
3599 0 : pPage = pFrm->FindPageFrm();
3600 :
3601 0 : PaintColLines( aPaintRect, rCol, pPage );
3602 : }
3603 : }
3604 : }
3605 0 : if ( !bCnt && pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() )
3606 0 : ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm->GetNext() );
3607 :
3608 0 : pFrm = pFrm->GetNext();
3609 :
3610 0 : if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) )
3611 0 : pFrm->Calc();
3612 0 : }
3613 : }
3614 :
3615 0 : static drawinglayer::primitive2d::Primitive2DSequence lcl_CreateDashedIndicatorPrimitive(
3616 : basegfx::B2DPoint aStart, basegfx::B2DPoint aEnd,
3617 : basegfx::BColor aColor )
3618 : {
3619 0 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 1 );
3620 :
3621 0 : std::vector< double > aStrokePattern;
3622 0 : basegfx::B2DPolygon aLinePolygon;
3623 0 : aLinePolygon.append( aStart );
3624 0 : aLinePolygon.append( aEnd );
3625 :
3626 0 : const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
3627 0 : if ( rSettings.GetHighContrastMode( ) )
3628 : {
3629 : // Only a solid line in high contrast mode
3630 0 : aColor = rSettings.GetDialogTextColor().getBColor();
3631 : }
3632 : else
3633 : {
3634 : // Get a color for the contrast
3635 0 : basegfx::BColor aHslLine = basegfx::tools::rgb2hsl( aColor );
3636 0 : double nLuminance = aHslLine.getZ() * 2.5;
3637 0 : if ( nLuminance == 0 )
3638 0 : nLuminance = 0.5;
3639 0 : else if ( nLuminance >= 1.0 )
3640 0 : nLuminance = aHslLine.getZ() * 0.4;
3641 0 : aHslLine.setZ( nLuminance );
3642 0 : const basegfx::BColor aOtherColor = basegfx::tools::hsl2rgb( aHslLine );
3643 :
3644 : // Compute the plain line
3645 : drawinglayer::primitive2d::PolygonHairlinePrimitive2D * pPlainLine =
3646 : new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
3647 0 : aLinePolygon, aOtherColor );
3648 :
3649 0 : aSeq[0] = drawinglayer::primitive2d::Primitive2DReference( pPlainLine );
3650 :
3651 : // Dashed line in twips
3652 0 : aStrokePattern.push_back( 40 );
3653 0 : aStrokePattern.push_back( 40 );
3654 :
3655 0 : aSeq.realloc( 2 );
3656 : }
3657 :
3658 : // Compute the dashed line primitive
3659 : drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pLine =
3660 : new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D (
3661 : basegfx::B2DPolyPolygon( aLinePolygon ),
3662 : drawinglayer::attribute::LineAttribute( aColor ),
3663 0 : drawinglayer::attribute::StrokeAttribute( aStrokePattern ) );
3664 :
3665 0 : aSeq[ aSeq.getLength( ) - 1 ] = drawinglayer::primitive2d::Primitive2DReference( pLine );
3666 :
3667 0 : return aSeq;
3668 : }
3669 :
3670 0 : void SwPageFrm::PaintBreak( ) const
3671 : {
3672 0 : if ( pGlobalShell->GetOut()->GetOutDevType() != OUTDEV_PRINTER &&
3673 0 : !pGlobalShell->GetViewOptions()->IsPDFExport() &&
3674 0 : !pGlobalShell->GetViewOptions()->IsReadonly() &&
3675 0 : !pGlobalShell->IsPreview() )
3676 : {
3677 0 : const SwFrm* pBodyFrm = Lower();
3678 0 : while ( pBodyFrm && !pBodyFrm->IsBodyFrm() )
3679 0 : pBodyFrm = pBodyFrm->GetNext();
3680 :
3681 0 : if ( pBodyFrm )
3682 : {
3683 0 : const SwLayoutFrm* pLayBody = static_cast< const SwLayoutFrm* >( pBodyFrm );
3684 0 : const SwFlowFrm *pFlowFrm = pLayBody->ContainsCntnt();
3685 :
3686 : // Test if the first node is a table
3687 0 : const SwFrm* pFirstFrm = pLayBody->Lower();
3688 0 : if ( pFirstFrm && pFirstFrm->IsTabFrm() )
3689 0 : pFlowFrm = static_cast< const SwTabFrm* >( pFirstFrm );
3690 :
3691 0 : SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pGlobalShell );
3692 0 : if ( pWrtSh )
3693 : {
3694 0 : SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
3695 0 : SwFrameControlsManager& rMngr = rEditWin.GetFrameControlsManager();
3696 :
3697 0 : if ( pFlowFrm && pFlowFrm->IsPageBreak( sal_True ) )
3698 0 : rMngr.SetPageBreakControl( this );
3699 : else
3700 0 : rMngr.RemoveControlsByType( PageBreak, this );
3701 : }
3702 : }
3703 0 : SwLayoutFrm::PaintBreak( );
3704 : }
3705 0 : }
3706 :
3707 0 : void SwColumnFrm::PaintBreak( ) const
3708 : {
3709 0 : if ( pGlobalShell->GetOut()->GetOutDevType() != OUTDEV_PRINTER &&
3710 0 : !pGlobalShell->GetViewOptions()->IsPDFExport() &&
3711 0 : !pGlobalShell->GetViewOptions()->IsReadonly() &&
3712 0 : !pGlobalShell->IsPreview() )
3713 : {
3714 0 : const SwFrm* pBodyFrm = Lower();
3715 0 : while ( pBodyFrm && !pBodyFrm->IsBodyFrm() )
3716 0 : pBodyFrm = pBodyFrm->GetNext();
3717 :
3718 0 : if ( pBodyFrm )
3719 : {
3720 0 : const SwCntntFrm *pCnt = static_cast< const SwLayoutFrm* >( pBodyFrm )->ContainsCntnt();
3721 0 : if ( pCnt && pCnt->IsColBreak( sal_True ) )
3722 : {
3723 : // Paint the break only if:
3724 : // * Not in header footer edition, to avoid conflicts with the
3725 : // header/footer marker
3726 : // * Non-printing characters are shown, as this is more consistent
3727 : // with other formatting marks
3728 0 : if ( !pGlobalShell->IsShowHeaderFooterSeparator( Header ) &&
3729 0 : !pGlobalShell->IsShowHeaderFooterSeparator( Footer ) )
3730 : {
3731 0 : SwRect aRect( pCnt->Prt() );
3732 0 : aRect.Pos() += pCnt->Frm().Pos();
3733 :
3734 : // Draw the line
3735 0 : basegfx::B2DPoint aStart( double( aRect.Left() ), aRect.Top() );
3736 0 : basegfx::B2DPoint aEnd( double( aRect.Right() ), aRect.Top() );
3737 0 : double nWidth = aRect.Width();
3738 0 : if ( IsVertical( ) )
3739 : {
3740 0 : aStart = basegfx::B2DPoint( double( aRect.Right() ), double( aRect.Top() ) );
3741 0 : aEnd = basegfx::B2DPoint( double( aRect.Right() ), double( aRect.Bottom() ) );
3742 0 : nWidth = aRect.Height();
3743 : }
3744 :
3745 0 : basegfx::BColor aLineColor = SwViewOption::GetPageBreakColor().getBColor();
3746 :
3747 : drawinglayer::primitive2d::Primitive2DSequence aSeq =
3748 0 : lcl_CreateDashedIndicatorPrimitive( aStart, aEnd, aLineColor );
3749 0 : aSeq.realloc( aSeq.getLength( ) + 1 );
3750 :
3751 : // Add the text above
3752 0 : OUString aBreakText = SW_RESSTR(STR_COLUMN_BREAK);
3753 :
3754 0 : basegfx::B2DVector aFontSize;
3755 0 : OutputDevice* pOut = pGlobalShell->GetOut();
3756 0 : Font aFont = pOut->GetSettings().GetStyleSettings().GetToolFont();
3757 0 : aFont.SetHeight( 8 * 20 );
3758 0 : pOut->SetFont( aFont );
3759 : drawinglayer::attribute::FontAttribute aFontAttr = drawinglayer::primitive2d::getFontAttributeFromVclFont(
3760 0 : aFontSize, aFont, false, false );
3761 :
3762 0 : Rectangle aTextRect;
3763 0 : pOut->GetTextBoundRect( aTextRect, aBreakText );
3764 0 : long nTextOff = ( nWidth - aTextRect.GetWidth() ) / 2;
3765 :
3766 : basegfx::B2DHomMatrix aTextMatrix( basegfx::tools::createScaleTranslateB2DHomMatrix(
3767 : aFontSize.getX(), aFontSize.getY(),
3768 0 : aRect.Left() + nTextOff, aRect.Top() ) );
3769 0 : if ( IsVertical() )
3770 : {
3771 0 : aTextMatrix = basegfx::B2DHomMatrix( basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix (
3772 : aFontSize.getX(), aFontSize.getY(), 0.0, M_PI_2,
3773 0 : aRect.Right(), aRect.Top() + nTextOff ) );
3774 : }
3775 :
3776 : drawinglayer::primitive2d::TextSimplePortionPrimitive2D * pText =
3777 : new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
3778 : aTextMatrix,
3779 : aBreakText, 0, aBreakText.getLength(),
3780 : std::vector< double >(),
3781 : aFontAttr,
3782 : lang::Locale(),
3783 0 : aLineColor );
3784 0 : aSeq[ aSeq.getLength() - 1 ] = drawinglayer::primitive2d::Primitive2DReference( pText );
3785 :
3786 0 : ProcessPrimitives( aSeq );
3787 : }
3788 : }
3789 : }
3790 : }
3791 0 : }
3792 :
3793 0 : void SwLayoutFrm::PaintBreak( ) const
3794 : {
3795 0 : const SwFrm* pFrm = Lower();
3796 0 : while ( pFrm )
3797 : {
3798 0 : if ( pFrm->IsLayoutFrm() )
3799 0 : static_cast< const SwLayoutFrm*>( pFrm )->PaintBreak( );
3800 0 : pFrm = pFrm->GetNext();
3801 : }
3802 0 : }
3803 :
3804 0 : void SwPageFrm::PaintDecorators( ) const
3805 : {
3806 0 : SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pGlobalShell );
3807 0 : if ( pWrtSh )
3808 : {
3809 0 : SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
3810 :
3811 0 : const SwLayoutFrm* pBody = FindBodyCont();
3812 0 : if ( pBody )
3813 : {
3814 0 : SwRect aBodyRect( pBody->Frm() );
3815 :
3816 0 : if ( pGlobalShell->GetOut()->GetOutDevType() != OUTDEV_PRINTER &&
3817 0 : !pGlobalShell->GetViewOptions()->IsPDFExport() &&
3818 0 : !pGlobalShell->IsPreview() &&
3819 0 : !pGlobalShell->GetViewOptions()->IsReadonly() &&
3820 0 : !pGlobalShell->GetViewOptions()->getBrowseMode() &&
3821 0 : ( pGlobalShell->IsShowHeaderFooterSeparator( Header ) ||
3822 0 : pGlobalShell->IsShowHeaderFooterSeparator( Footer ) ) )
3823 : {
3824 0 : bool bRtl = Application::GetSettings().GetLayoutRTL();
3825 0 : const SwRect& rVisArea = pGlobalShell->VisArea();
3826 0 : long nXOff = std::min( aBodyRect.Right(), rVisArea.Right() );
3827 0 : if ( bRtl )
3828 0 : nXOff = std::max( aBodyRect.Left(), rVisArea.Left() );
3829 :
3830 : // Header
3831 0 : if ( pGlobalShell->IsShowHeaderFooterSeparator( Header ) )
3832 : {
3833 0 : const SwFrm* pHeaderFrm = Lower();
3834 0 : if ( !pHeaderFrm->IsHeaderFrm() )
3835 0 : pHeaderFrm = NULL;
3836 :
3837 0 : long nHeaderYOff = aBodyRect.Top();
3838 0 : Point nOutputOff = rEditWin.LogicToPixel( Point( nXOff, nHeaderYOff ) );
3839 0 : rEditWin.GetFrameControlsManager().SetHeaderFooterControl( this, Header, nOutputOff );
3840 : }
3841 :
3842 : // Footer
3843 0 : if ( pGlobalShell->IsShowHeaderFooterSeparator( Footer ) )
3844 : {
3845 0 : const SwFrm* pFtnContFrm = Lower();
3846 0 : while ( pFtnContFrm )
3847 : {
3848 0 : if ( pFtnContFrm->IsFtnContFrm() )
3849 0 : aBodyRect.AddBottom( pFtnContFrm->Frm().Bottom() - aBodyRect.Bottom() );
3850 0 : pFtnContFrm = pFtnContFrm->GetNext();
3851 : }
3852 :
3853 0 : long nFooterYOff = aBodyRect.Bottom();
3854 0 : Point nOutputOff = rEditWin.LogicToPixel( Point( nXOff, nFooterYOff ) );
3855 0 : rEditWin.GetFrameControlsManager().SetHeaderFooterControl( this, Footer, nOutputOff );
3856 : }
3857 : }
3858 : }
3859 : }
3860 0 : }
3861 :
3862 : /** FlyFrm::IsBackgroundTransparent - for feature #99657#
3863 :
3864 : OD 12.08.2002
3865 : determines, if background of fly frame has to be drawn transparent
3866 : declaration found in /core/inc/flyfrm.cxx
3867 : OD 08.10.2002 #103898# - If the background of the fly frame itself is not
3868 : transparent and the background is inherited from its parent/grandparent,
3869 : the background brush, used for drawing, has to be investigated for transparency.
3870 :
3871 : @return true, if background is transparent drawn.
3872 : */
3873 0 : bool SwFlyFrm::IsBackgroundTransparent() const
3874 : {
3875 0 : bool bBackgroundTransparent = GetFmt()->IsBackgroundTransparent();
3876 0 : if ( !bBackgroundTransparent &&
3877 0 : static_cast<const SwFlyFrmFmt*>(GetFmt())->IsBackgroundBrushInherited() )
3878 : {
3879 0 : const SvxBrushItem* pBackgrdBrush = 0;
3880 0 : const Color* pSectionTOXColor = 0;
3881 0 : SwRect aDummyRect;
3882 : //UUUU
3883 0 : FillAttributesPtr aFillAttributes;
3884 :
3885 0 : if ( GetBackgroundBrush( aFillAttributes, pBackgrdBrush, pSectionTOXColor, aDummyRect, false) )
3886 : {
3887 0 : if ( pSectionTOXColor &&
3888 0 : (pSectionTOXColor->GetTransparency() != 0) &&
3889 0 : (pSectionTOXColor->GetColor() != COL_TRANSPARENT) )
3890 : {
3891 0 : bBackgroundTransparent = true;
3892 : }
3893 0 : else if(aFillAttributes.get() && aFillAttributes->isUsed()) //UUUU
3894 : {
3895 0 : bBackgroundTransparent = aFillAttributes->isTransparent();
3896 : }
3897 0 : else if ( pBackgrdBrush )
3898 : {
3899 0 : if ( (pBackgrdBrush->GetColor().GetTransparency() != 0) &&
3900 0 : (pBackgrdBrush->GetColor() != COL_TRANSPARENT) )
3901 : {
3902 0 : bBackgroundTransparent = true;
3903 : }
3904 : else
3905 : {
3906 : const GraphicObject *pTmpGrf =
3907 0 : static_cast<const GraphicObject*>(pBackgrdBrush->GetGraphicObject());
3908 0 : if ( (pTmpGrf) &&
3909 0 : (pTmpGrf->GetAttr().GetTransparency() != 0)
3910 : )
3911 : {
3912 0 : bBackgroundTransparent = true;
3913 : }
3914 : }
3915 : }
3916 0 : }
3917 : }
3918 :
3919 0 : return bBackgroundTransparent;
3920 : };
3921 :
3922 : /** FlyFrm::IsShadowTransparent - for feature #99657#
3923 :
3924 : OD 13.08.2002
3925 : determine, if shadow color of fly frame has to be drawn transparent
3926 : declaration found in /core/inc/flyfrm.cxx
3927 :
3928 : @return true, if shadow color is transparent.
3929 : */
3930 0 : bool SwFlyFrm::IsShadowTransparent() const
3931 : {
3932 0 : return GetFmt()->IsShadowTransparent();
3933 : };
3934 :
3935 0 : sal_Bool SwFlyFrm::IsPaint( SdrObject *pObj, const SwViewShell *pSh )
3936 : {
3937 : SdrObjUserCall *pUserCall;
3938 :
3939 0 : if ( 0 == ( pUserCall = GetUserCall(pObj) ) )
3940 0 : return sal_True;
3941 :
3942 : //Attribute dependent, don't paint for printer or Preview
3943 0 : sal_Bool bPaint = pFlyOnlyDraw ||
3944 0 : ((SwContact*)pUserCall)->GetFmt()->GetPrint().GetValue();
3945 0 : if ( !bPaint )
3946 0 : bPaint = pSh->GetWin() && !pSh->IsPreview();
3947 :
3948 0 : if ( bPaint )
3949 : {
3950 : //The paint may be prevented by the superior Flys.
3951 0 : SwFrm *pAnch = 0;
3952 0 : if ( pObj->ISA(SwFlyDrawObj) ) // i#117962#
3953 : {
3954 0 : bPaint = false;
3955 : }
3956 0 : if ( pObj->ISA(SwVirtFlyDrawObj) )
3957 : {
3958 0 : SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
3959 0 : if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly )
3960 0 : return sal_True;
3961 :
3962 : //Try to avoid displaying the intermediate stage, Flys which don't
3963 : //overlap with the page on which they are anchored won't be
3964 : //painted.
3965 : //HACK: exception: printing of frames in tables, those can overlap
3966 : //a page once in a while when dealing with oversized tables (HTML).
3967 0 : SwPageFrm *pPage = pFly->FindPageFrm();
3968 0 : if ( pPage )
3969 : {
3970 0 : if ( pPage->Frm().IsOver( pFly->Frm() ) )
3971 0 : pAnch = pFly->AnchorFrm();
3972 0 : else if ( bTableHack &&
3973 0 : pFly->Frm().Top() >= pFly->GetAnchorFrm()->Frm().Top() &&
3974 0 : pFly->Frm().Top() < pFly->GetAnchorFrm()->Frm().Bottom() &&
3975 0 : sal_IntPtr(pSh->GetOut()) ==
3976 0 : sal_IntPtr(pSh->getIDocumentDeviceAccess()->getPrinter( false ) ) )
3977 : {
3978 0 : pAnch = pFly->AnchorFrm();
3979 : }
3980 : }
3981 :
3982 : }
3983 : else
3984 : {
3985 : // OD 13.10.2003 #i19919# - consider 'virtual' drawing objects
3986 : // OD 2004-03-29 #i26791#
3987 0 : SwDrawContact* pDrawContact = dynamic_cast<SwDrawContact*>(pUserCall);
3988 0 : pAnch = pDrawContact ? pDrawContact->GetAnchorFrm(pObj) : NULL;
3989 0 : if ( pAnch )
3990 : {
3991 0 : if ( !pAnch->GetValidPosFlag() )
3992 0 : pAnch = 0;
3993 0 : else if ( sal_IntPtr(pSh->GetOut()) == sal_IntPtr(pSh->getIDocumentDeviceAccess()->getPrinter( false )))
3994 : {
3995 : //HACK: we have to omit some of the objects for printing,
3996 : //otherwise they would be printed twice.
3997 : //The objects should get printed if the TableHack is active
3998 : //right now. Afterwards they must not be printed if the
3999 : //page over which they float position wise gets printed.
4000 0 : const SwPageFrm *pPage = pAnch->FindPageFrm();
4001 0 : if ( !bTableHack &&
4002 0 : !pPage->Frm().IsOver( pObj->GetCurrentBoundRect() ) )
4003 0 : pAnch = 0;
4004 : }
4005 : }
4006 : else
4007 : {
4008 : // OD 02.07.2003 #108784# - debug assert
4009 0 : if ( !pObj->ISA(SdrObjGroup) )
4010 : {
4011 : OSL_FAIL( "<SwFlyFrm::IsPaint(..)> - paint of drawing object without anchor frame!?" );
4012 : }
4013 : }
4014 : }
4015 0 : if ( pAnch )
4016 : {
4017 0 : if ( pAnch->IsInFly() )
4018 0 : bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(),
4019 0 : pSh );
4020 0 : else if ( pFlyOnlyDraw )
4021 0 : bPaint = sal_False;
4022 : }
4023 : else
4024 0 : bPaint = sal_False;
4025 : }
4026 0 : return bPaint;
4027 : }
4028 :
4029 0 : void SwCellFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
4030 : {
4031 0 : if ( GetLayoutRowSpan() >= 1 )
4032 0 : SwLayoutFrm::Paint( rRect );
4033 0 : }
4034 :
4035 : struct BorderLinesGuard
4036 : {
4037 0 : explicit BorderLinesGuard() : m_pBorderLines(g_pBorderLines)
4038 : {
4039 0 : g_pBorderLines = new BorderLines;
4040 0 : }
4041 0 : ~BorderLinesGuard()
4042 : {
4043 0 : delete g_pBorderLines;
4044 0 : g_pBorderLines = m_pBorderLines;
4045 0 : }
4046 : private:
4047 : BorderLines *const m_pBorderLines;
4048 : };
4049 :
4050 0 : void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
4051 : {
4052 : //optimize thumbnail generation and store procedure to improve odt saving performance, #i120030#
4053 0 : SwViewShell *pShell = getRootFrm()->GetCurrShell();
4054 0 : if (pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocShell())
4055 : {
4056 0 : sal_Bool bInGenerateThumbnail = pShell->GetDoc()->GetDocShell()->IsInGenerateAndStoreThumbnail();
4057 0 : if (bInGenerateThumbnail)
4058 : {
4059 0 : SwRect aVisRect = pShell->VisArea();
4060 0 : if (!aVisRect.IsOver(Frm()))
4061 0 : return;
4062 : }
4063 : }
4064 :
4065 : //because of the overlapping of frames and drawing objects the flys have to
4066 : //paint their borders (and those of the internal ones) directly.
4067 : //e.g. #33066#
4068 0 : pLines->LockLines(sal_True);
4069 0 : BorderLinesGuard blg; // this should not paint borders added from PaintBaBo
4070 :
4071 0 : SwRect aRect( rRect );
4072 0 : aRect._Intersection( Frm() );
4073 :
4074 0 : OutputDevice* pOut = pGlobalShell->GetOut();
4075 0 : pOut->Push( PUSH_CLIPREGION );
4076 0 : pOut->SetClipRegion();
4077 0 : const SwPageFrm* pPage = FindPageFrm();
4078 :
4079 0 : const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm()
4080 0 : ? (SwNoTxtFrm*)Lower() : 0;
4081 :
4082 0 : bool bIsChart = false; //#i102950# don't paint additional borders for charts
4083 : //check whether we have a chart
4084 0 : if(pNoTxt)
4085 : {
4086 0 : const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode());
4087 0 : if( pNoTNd )
4088 : {
4089 0 : SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode());
4090 0 : if( pOLENd && ChartHelper::IsChart( pOLENd->GetOLEObj().GetObject() ) )
4091 0 : bIsChart = true;
4092 : }
4093 : }
4094 :
4095 : {
4096 0 : bool bContour = GetFmt()->GetSurround().IsContour();
4097 0 : PolyPolygon aPoly;
4098 0 : if ( bContour )
4099 : {
4100 : // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True>
4101 : // to indicate that method is called for paint in order to avoid
4102 : // load of the intrinsic graphic.
4103 0 : bContour = GetContour( aPoly, sal_True );
4104 : }
4105 :
4106 : // #i47804# - distinguish complete background paint
4107 : // and margin paint.
4108 : // paint complete background for Writer text fly frames
4109 0 : bool bPaintCompleteBack( !pNoTxt );
4110 : // paint complete background for transparent graphic and contour,
4111 : // if own background color exists.
4112 0 : const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false;
4113 0 : if ( !bPaintCompleteBack &&
4114 0 : ( bIsGraphicTransparent|| bContour ) )
4115 : {
4116 0 : const SwFrmFmt* pSwFrmFmt = dynamic_cast< const SwFrmFmt* >(GetFmt());
4117 :
4118 0 : if(pSwFrmFmt && RES_FLYFRMFMT == pSwFrmFmt->Which())
4119 : {
4120 : //UUUU check for transparency
4121 0 : const FillAttributesPtr aFillAttributes(pSwFrmFmt->getFillAttributes());
4122 :
4123 0 : if(aFillAttributes.get())
4124 : {
4125 0 : bPaintCompleteBack = aFillAttributes->isTransparent();
4126 0 : }
4127 : }
4128 : else
4129 : {
4130 0 : const SvxBrushItem &rBack = GetFmt()->GetBackground();
4131 : // OD 07.08.2002 #99657# #GetTransChg#
4132 : // to determine, if background has to be painted, by checking, if
4133 : // background color is not COL_TRANSPARENT ("no fill"/"auto fill")
4134 : // or a background graphic exists.
4135 0 : bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) ||
4136 0 : rBack.GetGraphicPos() != GPOS_NONE;
4137 : }
4138 : }
4139 : // paint of margin needed.
4140 0 : const bool bPaintMarginOnly( !bPaintCompleteBack &&
4141 0 : Prt().SSize() != Frm().SSize() );
4142 :
4143 : // #i47804# - paint background of parent fly frame
4144 : // for transparent graphics in layer Hell, if parent fly frame isn't
4145 : // in layer Hell. It's only painted the intersection between the
4146 : // parent fly frame area and the paint area <aRect>
4147 0 : const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
4148 :
4149 0 : if ( bIsGraphicTransparent &&
4150 0 : GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() &&
4151 0 : GetAnchorFrm()->FindFlyFrm() )
4152 : {
4153 0 : const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm();
4154 0 : if ( pParentFlyFrm->GetDrawObj()->GetLayer() !=
4155 0 : pIDDMA->GetHellId() )
4156 : {
4157 0 : SwFlyFrm* pOldRet = pRetoucheFly2;
4158 0 : pRetoucheFly2 = const_cast<SwFlyFrm*>(this);
4159 :
4160 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm );
4161 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
4162 0 : SwRect aPaintRect( aRect );
4163 0 : aPaintRect._Intersection( pParentFlyFrm->Frm() );
4164 0 : pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False );
4165 :
4166 0 : pRetoucheFly2 = pOldRet;
4167 : }
4168 : }
4169 :
4170 0 : if ( bPaintCompleteBack || bPaintMarginOnly )
4171 : {
4172 : //#24926# JP 01.02.96, PaintBaBo is here partially so PaintBorder
4173 : //receives the original Rect but PaintBackground only the limited
4174 : //one.
4175 :
4176 : // OD 2004-04-23 #116347#
4177 0 : pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
4178 0 : pOut->SetLineColor();
4179 :
4180 0 : pPage = FindPageFrm();
4181 :
4182 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
4183 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
4184 :
4185 : // paint background
4186 : {
4187 0 : SwRegionRects aRegion( aRect );
4188 : // #i80822#
4189 : // suppress painting of background in printing area for
4190 : // non-transparent graphics.
4191 0 : if ( bPaintMarginOnly ||
4192 0 : ( pNoTxt && !bIsGraphicTransparent ) )
4193 : {
4194 : //What we actually want to paint is the small stripe between
4195 : //PrtArea and outer border.
4196 0 : SwRect aTmp( Prt() ); aTmp += Frm().Pos();
4197 0 : aRegion -= aTmp;
4198 : }
4199 0 : if ( bContour )
4200 : {
4201 0 : pOut->Push();
4202 : // #i80822#
4203 : // apply clip region under the same conditions, which are
4204 : // used in <SwNoTxtFrm::Paint(..)> to set the clip region
4205 : // for painting the graphic/OLE. Thus, the clip region is
4206 : // also applied for the PDF export.
4207 0 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
4208 0 : if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() )
4209 : {
4210 0 : pOut->SetClipRegion(Region(aPoly));
4211 : }
4212 0 : for ( sal_uInt16 i = 0; i < aRegion.size(); ++i )
4213 0 : PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
4214 0 : pOut->Pop();
4215 : }
4216 : else
4217 0 : for ( sal_uInt16 i = 0; i < aRegion.size(); ++i )
4218 0 : PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
4219 : }
4220 :
4221 : // OD 06.08.2002 #99657# - paint border before painting background
4222 : // paint border
4223 : {
4224 0 : SwRect aTmp( rRect );
4225 0 : PaintBorder( aTmp, pPage, rAttrs );
4226 : }
4227 :
4228 0 : pOut->Pop();
4229 0 : }
4230 : }
4231 :
4232 : // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and
4233 : // the subsidiary lines of its lowers on its own, due to overlapping with
4234 : // other fly frames or other objects.
4235 0 : if( pGlobalShell->GetWin()
4236 0 : && !bIsChart ) //#i102950# don't paint additional borders for charts
4237 : {
4238 : bool bSubsLineRectsCreated;
4239 0 : if ( pSubsLines )
4240 : {
4241 : // Lock already existing subsidiary lines
4242 0 : pSubsLines->LockLines( sal_True );
4243 0 : bSubsLineRectsCreated = false;
4244 : }
4245 : else
4246 : {
4247 : // create new subsidiardy lines
4248 0 : pSubsLines = new SwSubsRects;
4249 0 : bSubsLineRectsCreated = true;
4250 : }
4251 :
4252 : bool bSpecSubsLineRectsCreated;
4253 0 : if ( pSpecSubsLines )
4254 : {
4255 : // Lock already existing special subsidiary lines
4256 0 : pSpecSubsLines->LockLines( sal_True );
4257 0 : bSpecSubsLineRectsCreated = false;
4258 : }
4259 : else
4260 : {
4261 : // create new special subsidiardy lines
4262 0 : pSpecSubsLines = new SwSubsRects;
4263 0 : bSpecSubsLineRectsCreated = true;
4264 : }
4265 : // Add subsidiary lines of fly frame and its lowers
4266 0 : RefreshLaySubsidiary( pPage, aRect );
4267 : // paint subsidiary lines of fly frame and its lowers
4268 0 : pSpecSubsLines->PaintSubsidiary( pOut, NULL );
4269 0 : pSubsLines->PaintSubsidiary( pOut, pLines );
4270 0 : if ( !bSubsLineRectsCreated )
4271 : // unlock subsidiary lines
4272 0 : pSubsLines->LockLines( sal_False );
4273 : else
4274 : // delete created subsidiary lines container
4275 0 : DELETEZ( pSubsLines );
4276 :
4277 0 : if ( !bSpecSubsLineRectsCreated )
4278 : // unlock special subsidiary lines
4279 0 : pSpecSubsLines->LockLines( sal_False );
4280 : else
4281 : {
4282 : // delete created special subsidiary lines container
4283 0 : DELETEZ( pSpecSubsLines );
4284 : }
4285 : }
4286 :
4287 0 : SwLayoutFrm::Paint( aRect );
4288 :
4289 0 : Validate();
4290 :
4291 : // OD 19.12.2002 #106318# - first paint lines added by fly frame paint
4292 : // and then unlock other lines.
4293 0 : pLines->PaintLines( pOut );
4294 0 : pLines->LockLines( sal_False );
4295 : // have to paint frame borders added in heaven layer here...
4296 0 : ProcessPrimitives(g_pBorderLines->GetBorderLines_Clear());
4297 :
4298 0 : pOut->Pop();
4299 :
4300 0 : if ( pProgress && pNoTxt )
4301 0 : pProgress->Reschedule();
4302 : }
4303 :
4304 0 : void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
4305 : {
4306 0 : const SwViewOption* pViewOption = pGlobalShell->GetViewOptions();
4307 0 : if (pViewOption->IsTable())
4308 : {
4309 : // #i29550#
4310 0 : if ( IsCollapsingBorders() )
4311 : {
4312 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
4313 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
4314 :
4315 : // paint shadow
4316 0 : if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
4317 : {
4318 0 : SwRect aRect;
4319 0 : ::lcl_CalcBorderRect( aRect, this, rAttrs, true );
4320 0 : PaintShadow( rRect, aRect, rAttrs );
4321 : }
4322 :
4323 0 : SwTabFrmPainter aHelper(*this);
4324 0 : aHelper.PaintLines(*pGlobalShell->GetOut(), rRect);
4325 : }
4326 :
4327 0 : SwLayoutFrm::Paint( rRect );
4328 : }
4329 : // OD 10.01.2003 #i6467# - no light grey rectangle for page preview
4330 0 : else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreview() )
4331 : {
4332 : // OD 10.01.2003 #i6467# - intersect output rectangle with table frame
4333 0 : SwRect aTabRect( Prt() );
4334 0 : aTabRect.Pos() += Frm().Pos();
4335 0 : SwRect aTabOutRect( rRect );
4336 0 : aTabOutRect.Intersection( aTabRect );
4337 0 : pViewOption->DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY );
4338 : }
4339 0 : ((SwTabFrm*)this)->ResetComplete();
4340 0 : }
4341 :
4342 : /**
4343 : * Paint border shadow.
4344 : *
4345 : * @param[in] rRect aligned rect to clip the result
4346 : * @param[in,out] rOutRect full painting area as input
4347 : * painting area reduced by shadow space for border and background as output
4348 : * @param[in] rShadow includes shadow attributes
4349 : * @param[in] bDrawFullShadowRectangle paint full rect of shadow
4350 : * @param[in] bTop paint top part of the shadow
4351 : * @param[in] bBottom paint bottom part of the shadow
4352 : * @param[in] bLeft paint left part of the shadow
4353 : * @param[in] bRight paint right part of the shadow
4354 : **/
4355 0 : static void lcl_PaintShadow( const SwRect& rRect, SwRect& rOutRect,
4356 : const SvxShadowItem& rShadow, const bool bDrawFullShadowRectangle,
4357 : const bool bTop, const bool bBottom,
4358 : const bool bLeft, const bool bRight )
4359 : {
4360 0 : const long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth() );
4361 0 : const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() );
4362 :
4363 0 : SwRects aRegion( 2 );
4364 0 : SwRect aOut( rOutRect );
4365 :
4366 0 : switch ( rShadow.GetLocation() )
4367 : {
4368 : case SVX_SHADOW_BOTTOMRIGHT:
4369 : {
4370 0 : if ( bDrawFullShadowRectangle )
4371 : {
4372 : // OD 06.08.2002 #99657# - draw full shadow rectangle
4373 0 : aOut.Top( rOutRect.Top() + nHeight );
4374 0 : aOut.Left( rOutRect.Left() + nWidth );
4375 0 : aRegion.push_back( aOut );
4376 : }
4377 : else
4378 : {
4379 0 : if( bBottom )
4380 : {
4381 0 : aOut.Top( rOutRect.Bottom() - nHeight );
4382 0 : if( bLeft )
4383 0 : aOut.Left( rOutRect.Left() + nWidth );
4384 0 : aRegion.push_back( aOut );
4385 : }
4386 0 : if( bRight )
4387 : {
4388 0 : aOut.Left( rOutRect.Right() - nWidth );
4389 0 : if( bTop )
4390 0 : aOut.Top( rOutRect.Top() + nHeight );
4391 : else
4392 0 : aOut.Top( rOutRect.Top() );
4393 0 : if( bBottom )
4394 0 : aOut.Bottom( rOutRect.Bottom() - nHeight );
4395 0 : aRegion.push_back( aOut );
4396 : }
4397 : }
4398 :
4399 0 : if( bRight )
4400 0 : rOutRect.Right( rOutRect.Right() - nWidth );
4401 0 : if( bBottom )
4402 0 : rOutRect.Bottom( rOutRect.Bottom()- nHeight );
4403 : }
4404 0 : break;
4405 : case SVX_SHADOW_TOPLEFT:
4406 : {
4407 0 : if ( bDrawFullShadowRectangle )
4408 : {
4409 : // OD 06.08.2002 #99657# - draw full shadow rectangle
4410 0 : aOut.Bottom( rOutRect.Bottom() - nHeight );
4411 0 : aOut.Right( rOutRect.Right() - nWidth );
4412 0 : aRegion.push_back( aOut );
4413 : }
4414 : else
4415 : {
4416 0 : if( bTop )
4417 : {
4418 0 : aOut.Bottom( rOutRect.Top() + nHeight );
4419 0 : if( bRight )
4420 0 : aOut.Right( rOutRect.Right() - nWidth );
4421 0 : aRegion.push_back( aOut );
4422 : }
4423 0 : if( bLeft )
4424 : {
4425 0 : aOut.Right( rOutRect.Left() + nWidth );
4426 0 : if( bBottom )
4427 0 : aOut.Bottom( rOutRect.Bottom() - nHeight );
4428 : else
4429 0 : aOut.Bottom( rOutRect.Bottom() );
4430 0 : if( bTop )
4431 0 : aOut.Top( rOutRect.Top() + nHeight );
4432 0 : aRegion.push_back( aOut );
4433 : }
4434 : }
4435 :
4436 0 : if( bLeft )
4437 0 : rOutRect.Left( rOutRect.Left() + nWidth );
4438 0 : if( bTop )
4439 0 : rOutRect.Top( rOutRect.Top() + nHeight );
4440 : }
4441 0 : break;
4442 : case SVX_SHADOW_TOPRIGHT:
4443 : {
4444 0 : if ( bDrawFullShadowRectangle )
4445 : {
4446 : // OD 06.08.2002 #99657# - draw full shadow rectangle
4447 0 : aOut.Bottom( rOutRect.Bottom() - nHeight);
4448 0 : aOut.Left( rOutRect.Left() + nWidth );
4449 0 : aRegion.push_back( aOut );
4450 : }
4451 : else
4452 : {
4453 0 : if( bTop )
4454 : {
4455 0 : aOut.Bottom( rOutRect.Top() + nHeight );
4456 0 : if( bLeft )
4457 0 : aOut.Left( rOutRect.Left() + nWidth );
4458 0 : aRegion.push_back( aOut );
4459 : }
4460 0 : if( bRight )
4461 : {
4462 0 : aOut.Left( rOutRect.Right() - nWidth );
4463 0 : if( bBottom )
4464 0 : aOut.Bottom( rOutRect.Bottom() - nHeight );
4465 : else
4466 0 : aOut.Bottom( rOutRect.Bottom() );
4467 0 : if( bTop )
4468 0 : aOut.Top( rOutRect.Top() + nHeight );
4469 0 : aRegion.push_back( aOut );
4470 : }
4471 : }
4472 :
4473 0 : if( bRight )
4474 0 : rOutRect.Right( rOutRect.Right() - nWidth );
4475 0 : if( bTop )
4476 0 : rOutRect.Top( rOutRect.Top() + nHeight );
4477 : }
4478 0 : break;
4479 : case SVX_SHADOW_BOTTOMLEFT:
4480 : {
4481 0 : if ( bDrawFullShadowRectangle )
4482 : {
4483 : // OD 06.08.2002 #99657# - draw full shadow rectangle
4484 0 : aOut.Top( rOutRect.Top() + nHeight );
4485 0 : aOut.Right( rOutRect.Right() - nWidth );
4486 0 : aRegion.push_back( aOut );
4487 : }
4488 : else
4489 : {
4490 0 : if( bBottom )
4491 : {
4492 0 : aOut.Top( rOutRect.Bottom()- nHeight );
4493 0 : if( bRight )
4494 0 : aOut.Right( rOutRect.Right() - nWidth );
4495 0 : aRegion.push_back( aOut );
4496 : }
4497 0 : if( bLeft )
4498 : {
4499 0 : aOut.Right( rOutRect.Left() + nWidth );
4500 0 : if( bTop )
4501 0 : aOut.Top( rOutRect.Top() + nHeight );
4502 : else
4503 0 : aOut.Top( rOutRect.Top() );
4504 0 : if( bBottom )
4505 0 : aOut.Bottom( rOutRect.Bottom() - nHeight );
4506 0 : aRegion.push_back( aOut );
4507 : }
4508 : }
4509 :
4510 0 : if( bLeft )
4511 0 : rOutRect.Left( rOutRect.Left() + nWidth );
4512 0 : if( bBottom )
4513 0 : rOutRect.Bottom( rOutRect.Bottom() - nHeight );
4514 : }
4515 0 : break;
4516 : default:
4517 : assert(false);
4518 0 : break;
4519 : }
4520 :
4521 0 : OutputDevice *pOut = pGlobalShell->GetOut();
4522 :
4523 0 : sal_uLong nOldDrawMode = pOut->GetDrawMode();
4524 0 : Color aShadowColor( rShadow.GetColor().GetRGBColor() );
4525 0 : if( !aRegion.empty() && pGlobalShell->GetWin() &&
4526 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4527 : {
4528 : // In high contrast mode, the output device has already set the
4529 : // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function
4530 : // to ignore the setting of a new color. Therefore we have to reset
4531 : // the drawing mode
4532 0 : pOut->SetDrawMode( 0 );
4533 0 : aShadowColor = SwViewOption::GetFontColor();
4534 : }
4535 :
4536 0 : if ( pOut->GetFillColor() != aShadowColor )
4537 0 : pOut->SetFillColor( aShadowColor );
4538 :
4539 0 : pOut->SetLineColor();
4540 :
4541 0 : pOut->SetDrawMode( nOldDrawMode );
4542 :
4543 0 : for ( sal_uInt16 i = 0; i < aRegion.size(); ++i )
4544 : {
4545 0 : SwRect &rOut = aRegion[i];
4546 0 : aOut = rOut;
4547 0 : if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
4548 : {
4549 0 : aOut._Intersection( rRect );
4550 0 : pOut->DrawRect( aOut.SVRect() );
4551 : }
4552 0 : }
4553 0 : }
4554 :
4555 : /** Paints a shadow if the format requests so.
4556 : |*
4557 : |* The shadow is always painted on the outer edge of the OutRect.
4558 : |* If needed, the OutRect is shrunk so the painting of the border can be
4559 : |* done on it.
4560 : |*
4561 : |* @note: draw full shadow rectangle for frames with transparent drawn backgrounds (OD 23.08.2002 #99657#)
4562 : */
4563 0 : void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
4564 : const SwBorderAttrs &rAttrs ) const
4565 : {
4566 0 : SvxShadowItem rShadow = rAttrs.GetShadow();
4567 :
4568 0 : const sal_Bool bCnt = IsCntntFrm();
4569 0 : const bool bTop = !bCnt || rAttrs.GetTopLine ( *(this) );
4570 0 : const bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) );
4571 :
4572 0 : if( IsVertical() )
4573 : {
4574 0 : switch( rShadow.GetLocation() )
4575 : {
4576 0 : case SVX_SHADOW_BOTTOMRIGHT: rShadow.SetLocation(SVX_SHADOW_BOTTOMLEFT); break;
4577 0 : case SVX_SHADOW_TOPLEFT: rShadow.SetLocation(SVX_SHADOW_TOPRIGHT); break;
4578 0 : case SVX_SHADOW_TOPRIGHT: rShadow.SetLocation(SVX_SHADOW_BOTTOMRIGHT); break;
4579 0 : case SVX_SHADOW_BOTTOMLEFT: rShadow.SetLocation(SVX_SHADOW_TOPLEFT); break;
4580 0 : default: break;
4581 : }
4582 : }
4583 :
4584 : // OD 23.08.2002 #99657# - determine, if full shadow rectangle have to
4585 : // be drawn or only two shadow rectangles beside the frame.
4586 : // draw full shadow rectangle, if frame background is drawn transparent.
4587 : // Status Quo:
4588 : // SwLayoutFrm can have transparent drawn backgrounds. Thus,
4589 : // "asked" their frame format.
4590 : const bool bDrawFullShadowRectangle =
4591 0 : ( IsLayoutFrm() &&
4592 0 : (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent()
4593 0 : );
4594 :
4595 0 : SWRECTFN( this );
4596 0 : ::lcl_ExtendLeftAndRight( rOutRect, *(this), rAttrs, fnRect );
4597 :
4598 0 : lcl_PaintShadow(rRect, rOutRect, rShadow, bDrawFullShadowRectangle, bTop, bBottom, true, true);
4599 0 : }
4600 :
4601 0 : void SwFrm::PaintBorderLine( const SwRect& rRect,
4602 : const SwRect& rOutRect,
4603 : const SwPageFrm * /*pPage*/,
4604 : const Color *pColor,
4605 : const SvxBorderStyle nStyle ) const
4606 : {
4607 0 : if ( !rOutRect.IsOver( rRect ) )
4608 0 : return;
4609 :
4610 0 : SwRect aOut( rOutRect );
4611 0 : aOut._Intersection( rRect );
4612 :
4613 0 : const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0;
4614 0 : sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB :
4615 0 : ( IsInSct() ? SUBCOL_SECT :
4616 0 : ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
4617 0 : if( pColor && pGlobalShell->GetWin() &&
4618 0 : Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
4619 : {
4620 0 : pColor = &SwViewOption::GetFontColor();
4621 : }
4622 :
4623 : //if ( pPage->GetSortedObjs() )
4624 : //{
4625 : // SwRegionRects aRegion( aOut, 4 );
4626 : // ::lcl_SubtractFlys( this, pPage, aOut, aRegion );
4627 : // for ( sal_uInt16 i = 0; i < aRegion.size(); ++i )
4628 : // pLines->AddLineRect( aRegion[i], pColor, nStyle, pTab, nSubCol );
4629 : //}
4630 : //else
4631 0 : pLines->AddLineRect( aOut, pColor, nStyle, pTab, nSubCol );
4632 : }
4633 :
4634 : /// @note Only all lines once or all lines twice!
4635 : // OD 29.04.2003 #107169# - method called for left and right border rectangles.
4636 : // For a printer output device perform adjustment for non-overlapping top and
4637 : // bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate
4638 : // printer output device.
4639 : // NOTE: For printer output device left/right border rectangle <_iorRect>
4640 : // has to be already non-overlapping the outer top/bottom border rectangle.
4641 0 : static void lcl_SubTopBottom( SwRect& _iorRect,
4642 : const SvxBoxItem& _rBox,
4643 : const SwBorderAttrs& _rAttrs,
4644 : const SwFrm& _rFrm,
4645 : const SwRectFn& _rRectFn,
4646 : const bool _bPrtOutputDev )
4647 : {
4648 0 : const sal_Bool bCnt = _rFrm.IsCntntFrm();
4649 0 : if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() &&
4650 0 : ( !bCnt || _rAttrs.GetTopLine( _rFrm ) )
4651 : )
4652 : {
4653 : // substract distance between outer and inner line.
4654 0 : SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() );
4655 : // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4656 : // adjust x-/y-position, if inner top line is a hair line (width = 1)
4657 0 : bool bIsInnerTopLineHairline = false;
4658 0 : if ( !_bPrtOutputDev )
4659 : {
4660 : // additionally substract width of top outer line
4661 : // --> left/right inner/outer line doesn't overlap top outer line.
4662 0 : nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() );
4663 : }
4664 : else
4665 : {
4666 : // OD 29.04.2003 #107169# - additionally substract width of top inner line
4667 : // --> left/right inner/outer line doesn't overlap top inner line.
4668 0 : nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() );
4669 0 : bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1;
4670 : }
4671 0 : (_iorRect.*_rRectFn->fnSubTop)( -nDist );
4672 : // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line
4673 : // is a hair line
4674 0 : if ( bIsInnerTopLineHairline )
4675 : {
4676 0 : if ( _rFrm.IsVertical() )
4677 : {
4678 : // right of border rectangle has to be checked and adjusted
4679 0 : Point aCompPt( _iorRect.Right(), 0 );
4680 0 : Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
4681 0 : lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4682 : aRefPt, aCompPt,
4683 0 : true, -1 );
4684 0 : _iorRect.Right( aCompPt.X() );
4685 : }
4686 : else
4687 : {
4688 : // top of border rectangle has to be checked and adjusted
4689 0 : Point aCompPt( 0, _iorRect.Top() );
4690 0 : Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
4691 0 : lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4692 : aRefPt, aCompPt,
4693 0 : false, +1 );
4694 0 : _iorRect.Top( aCompPt.Y() );
4695 : }
4696 : }
4697 : }
4698 :
4699 0 : if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() &&
4700 0 : ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) )
4701 : )
4702 : {
4703 : // substract distance between outer and inner line.
4704 0 : SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() );
4705 : // OD 19.05.2003 #109667# - non-overlapping border rectangles:
4706 : // adjust x-/y-position, if inner bottom line is a hair line (width = 1)
4707 0 : bool bIsInnerBottomLineHairline = false;
4708 0 : if ( !_bPrtOutputDev )
4709 : {
4710 : // additionally substract width of bottom outer line
4711 : // --> left/right inner/outer line doesn't overlap bottom outer line.
4712 0 : nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() );
4713 : }
4714 : else
4715 : {
4716 : // OD 29.04.2003 #107169# - additionally substract width of bottom inner line
4717 : // --> left/right inner/outer line doesn't overlap bottom inner line.
4718 0 : nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() );
4719 0 : bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1;
4720 : }
4721 0 : (_iorRect.*_rRectFn->fnAddBottom)( -nDist );
4722 : // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner
4723 : // bottom line is a hair line.
4724 0 : if ( bIsInnerBottomLineHairline )
4725 : {
4726 0 : if ( _rFrm.IsVertical() )
4727 : {
4728 : // left of border rectangle has to be checked and adjusted
4729 0 : Point aCompPt( _iorRect.Left(), 0 );
4730 0 : Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
4731 0 : lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4732 : aRefPt, aCompPt,
4733 0 : true, +1 );
4734 0 : _iorRect.Left( aCompPt.X() );
4735 : }
4736 : else
4737 : {
4738 : // bottom of border rectangle has to be checked and adjusted
4739 0 : Point aCompPt( 0, _iorRect.Bottom() );
4740 0 : Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
4741 0 : lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
4742 : aRefPt, aCompPt,
4743 0 : false, -1 );
4744 0 : _iorRect.Bottom( aCompPt.Y() );
4745 : }
4746 : }
4747 : }
4748 0 : }
4749 :
4750 0 : static sal_uInt16 lcl_GetLineWidth( const SvxBorderLine* pLine )
4751 : {
4752 0 : sal_uInt16 result = 0;
4753 :
4754 0 : if ( pLine != NULL )
4755 0 : result = pLine->GetScaledWidth();
4756 :
4757 0 : return result;
4758 : }
4759 :
4760 0 : static double lcl_GetExtent( const SvxBorderLine* pSideLine, const SvxBorderLine* pOppositeLine )
4761 : {
4762 0 : double nExtent = 0.0;
4763 :
4764 0 : if ( pSideLine && !pSideLine->isEmpty() )
4765 0 : nExtent = -lcl_GetLineWidth( pSideLine ) / 2.0;
4766 0 : else if ( pOppositeLine )
4767 0 : nExtent = lcl_GetLineWidth( pOppositeLine ) / 2.0;
4768 :
4769 0 : return nExtent;
4770 : }
4771 :
4772 0 : static void lcl_MakeBorderLine(SwRect const& rRect,
4773 : bool const isVerticalInModel,
4774 : bool const isLeftOrTopBorderInModel,
4775 : bool const isVertical,
4776 : SvxBorderLine const& rBorder,
4777 : SvxBorderLine const*const pLeftOrTopNeighbour,
4778 : SvxBorderLine const*const pRightOrBottomNeighbour)
4779 : {
4780 : bool const isLeftOrTopBorder((isVerticalInModel == isVertical)
4781 : ? isLeftOrTopBorderInModel
4782 0 : : (isLeftOrTopBorderInModel != isVertical));
4783 : SvxBorderLine const*const pStartNeighbour(
4784 0 : (!isVertical && isVerticalInModel)
4785 0 : ? pRightOrBottomNeighbour : pLeftOrTopNeighbour);
4786 : SvxBorderLine const*const pEndNeighbour(
4787 : (pStartNeighbour == pLeftOrTopNeighbour)
4788 0 : ? pRightOrBottomNeighbour : pLeftOrTopNeighbour);
4789 :
4790 0 : basegfx::B2DPoint aStart;
4791 0 : basegfx::B2DPoint aEnd;
4792 0 : if (isVertical)
4793 : { // fdo#38635: always from outer edge
4794 : double const fStartX( (isLeftOrTopBorder)
4795 0 : ? rRect.Left() + (rRect.Width() / 2.0)
4796 0 : : rRect.Right() - (rRect.Width() / 2.0));
4797 0 : aStart.setX(fStartX);
4798 0 : aStart.setY(rRect.Top() +
4799 0 : lcl_AlignHeight(lcl_GetLineWidth(pStartNeighbour))/2.0);
4800 0 : aEnd.setX(fStartX);
4801 0 : aEnd.setY(rRect.Bottom() -
4802 0 : lcl_AlignHeight(lcl_GetLineWidth(pEndNeighbour))/2.0);
4803 : }
4804 : else
4805 : { // fdo#38635: always from outer edge
4806 : double const fStartY( (isLeftOrTopBorder)
4807 0 : ? rRect.Top() + (rRect.Height() / 2.0)
4808 0 : : rRect.Bottom() - (rRect.Height() / 2.0));
4809 0 : aStart.setX(rRect.Left() +
4810 0 : lcl_AlignWidth(lcl_GetLineWidth(pStartNeighbour))/2.0);
4811 0 : aStart.setY(fStartY);
4812 0 : aEnd.setX(rRect.Right() -
4813 0 : lcl_AlignWidth(lcl_GetLineWidth(pEndNeighbour))/2.0);
4814 0 : aEnd.setY(fStartY);
4815 : }
4816 :
4817 : // When rendering to very small (virtual) devices, like when producing
4818 : // page thumbnails in a mobile device app, the line geometry can end up
4819 : // bogus (negative width or height), so just ignore such border lines.
4820 : // Otherwise we will run into assertions later in lcl_TryMergeBorderLine()
4821 : // at least.
4822 0 : if (aEnd.getX() < aStart.getX() ||
4823 0 : aEnd.getY() < aStart.getY())
4824 0 : return;
4825 :
4826 : double const nExtentLeftStart = (isLeftOrTopBorder == isVertical)
4827 : ? lcl_GetExtent(pStartNeighbour, 0)
4828 0 : : lcl_GetExtent(0, pStartNeighbour);
4829 : double const nExtentLeftEnd = (isLeftOrTopBorder == isVertical)
4830 : ? lcl_GetExtent(pEndNeighbour, 0)
4831 0 : : lcl_GetExtent(0, pEndNeighbour);
4832 : double const nExtentRightStart = (isLeftOrTopBorder == isVertical)
4833 : ? lcl_GetExtent(0, pStartNeighbour)
4834 0 : : lcl_GetExtent(pStartNeighbour, 0);
4835 : double const nExtentRightEnd = (isLeftOrTopBorder == isVertical)
4836 : ? lcl_GetExtent(0, pEndNeighbour)
4837 0 : : lcl_GetExtent(pEndNeighbour, 0);
4838 :
4839 0 : double const nLeftWidth = rBorder.GetOutWidth();
4840 0 : double const nRightWidth = rBorder.GetInWidth();
4841 0 : Color const aLeftColor = rBorder.GetColorOut(isLeftOrTopBorder);
4842 0 : Color const aRightColor = rBorder.GetColorIn(isLeftOrTopBorder);
4843 :
4844 : ::rtl::Reference<BorderLinePrimitive2D> const xLine =
4845 : new BorderLinePrimitive2D(
4846 0 : aStart, aEnd, nLeftWidth, rBorder.GetDistance(), nRightWidth,
4847 : nExtentLeftStart, nExtentLeftEnd,
4848 : nExtentRightStart, nExtentRightEnd,
4849 : aLeftColor.getBColor(), aRightColor.getBColor(),
4850 0 : rBorder.GetColorGap().getBColor(), rBorder.HasGapColor(),
4851 0 : rBorder.GetBorderLineStyle() );
4852 0 : g_pBorderLines->AddBorderLine(xLine);
4853 : }
4854 :
4855 : // OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine>
4856 : // into new method <lcl_PaintLeftRightLine(..)>
4857 0 : static void lcl_PaintLeftRightLine( const bool _bLeft,
4858 : const SwFrm& _rFrm,
4859 : const SwPageFrm& /*_rPage*/,
4860 : const SwRect& _rOutRect,
4861 : const SwRect& /*_rRect*/,
4862 : const SwBorderAttrs& _rAttrs,
4863 : const SwRectFn& _rRectFn )
4864 : {
4865 0 : const SvxBoxItem& rBox = _rAttrs.GetBox();
4866 0 : const bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft();
4867 0 : const SvxBorderLine* pLeftRightBorder = 0;
4868 0 : const SvxBorderLine* pTopBorder = rBox.GetTop();
4869 0 : const SvxBorderLine* pBottomBorder = rBox.GetBottom();
4870 :
4871 0 : if ( _bLeft )
4872 : {
4873 0 : pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft();
4874 : }
4875 : else
4876 : {
4877 0 : pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight();
4878 : }
4879 :
4880 0 : if ( !pLeftRightBorder )
4881 : {
4882 0 : return;
4883 : }
4884 :
4885 0 : SwRect aRect( _rOutRect );
4886 0 : if ( _bLeft )
4887 : {
4888 0 : (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( lcl_GetLineWidth( pLeftRightBorder ) ) -
4889 0 : (aRect.*_rRectFn->fnGetWidth)() );
4890 :
4891 : // Shift the left border to the left.
4892 0 : Point aCurPos = aRect.Pos();
4893 0 : sal_uInt16 nOffset = pLeftRightBorder->GetDistance();
4894 0 : aCurPos.X() -= nOffset;
4895 0 : aCurPos.Y() -= nOffset;
4896 0 : aRect.Pos(aCurPos);
4897 0 : Size aCurSize = aRect.SSize();
4898 0 : aCurSize.Height() += nOffset * 2;
4899 0 : aRect.SSize(aCurSize);
4900 : }
4901 : else
4902 : {
4903 0 : (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( lcl_GetLineWidth( pLeftRightBorder ) ) -
4904 0 : (aRect.*_rRectFn->fnGetWidth)() );
4905 : }
4906 :
4907 0 : if ( _rFrm.IsCntntFrm() )
4908 : {
4909 0 : ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn );
4910 :
4911 : // No Top / bottom borders for joint borders
4912 0 : if ( _rAttrs.JoinedWithPrev( _rFrm ) ) pTopBorder = NULL;
4913 0 : if ( _rAttrs.JoinedWithNext( _rFrm ) ) pBottomBorder = NULL;
4914 : }
4915 :
4916 0 : if ( !pLeftRightBorder->GetInWidth() )
4917 : {
4918 : // OD 06.05.2003 #107169# - init boolean indicating printer output device.
4919 : const bool bPrtOutputDev =
4920 0 : ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() );
4921 :
4922 : // OD 06.05.2003 #107169# - add 6th parameter
4923 0 : ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
4924 : }
4925 :
4926 0 : if ( lcl_GetLineWidth( pLeftRightBorder ) > 0 )
4927 : {
4928 : lcl_MakeBorderLine(
4929 0 : aRect, true, _bLeft, aRect.Height() > aRect.Width(),
4930 0 : *pLeftRightBorder, pTopBorder, pBottomBorder);
4931 : }
4932 : }
4933 :
4934 : // OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine>
4935 : // into <lcl_PaintTopLine>
4936 0 : static void lcl_PaintTopBottomLine( const bool _bTop,
4937 : const SwFrm& ,
4938 : const SwPageFrm& /*_rPage*/,
4939 : const SwRect& _rOutRect,
4940 : const SwRect& /*_rRect*/,
4941 : const SwBorderAttrs& _rAttrs,
4942 : const SwRectFn& _rRectFn )
4943 : {
4944 0 : const SvxBoxItem& rBox = _rAttrs.GetBox();
4945 0 : const SvxBorderLine* pTopBottomBorder = 0;
4946 :
4947 0 : if ( _bTop )
4948 : {
4949 0 : pTopBottomBorder = rBox.GetTop();
4950 : }
4951 : else
4952 : {
4953 0 : pTopBottomBorder = rBox.GetBottom();
4954 : }
4955 :
4956 0 : if ( !pTopBottomBorder )
4957 : {
4958 0 : return;
4959 : }
4960 :
4961 0 : SwRect aRect( _rOutRect );
4962 0 : if ( _bTop )
4963 : {
4964 0 : (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( lcl_GetLineWidth( pTopBottomBorder ) ) -
4965 0 : (aRect.*_rRectFn->fnGetHeight)() );
4966 :
4967 : // Push the top border up a bit.
4968 0 : sal_uInt16 nOffset = pTopBottomBorder->GetDistance();
4969 0 : Point aCurPos = aRect.Pos();
4970 0 : aCurPos.X() -= nOffset;
4971 0 : aCurPos.Y() -= nOffset;
4972 0 : aRect.Pos(aCurPos);
4973 0 : Size aCurSize = aRect.SSize();
4974 0 : aCurSize.Width() += nOffset * 2;
4975 0 : aRect.SSize(aCurSize);
4976 : }
4977 : else
4978 : {
4979 0 : (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( lcl_GetLineWidth( pTopBottomBorder ) ) -
4980 0 : (aRect.*_rRectFn->fnGetHeight)() );
4981 : }
4982 :
4983 0 : if ( lcl_GetLineWidth( pTopBottomBorder ) > 0 )
4984 : {
4985 : lcl_MakeBorderLine(
4986 0 : aRect, false, _bTop, aRect.Height() > aRect.Width(),
4987 0 : *pTopBottomBorder, rBox.GetLeft(), rBox.GetRight());
4988 : }
4989 : }
4990 :
4991 0 : void PaintCharacterBorder(
4992 : const SwFont& rFont,
4993 : const SwRect& rPaintArea,
4994 : const bool bVerticalLayout,
4995 : const bool bJoinWithPrev,
4996 : const bool bJoinWithNext )
4997 : {
4998 0 : SwRect aAlignedRect(rPaintArea);
4999 0 : SwAlignRect(aAlignedRect, pGlobalShell);
5000 :
5001 0 : bool bTop = true;
5002 0 : bool bBottom = true;
5003 0 : bool bLeft = true;
5004 0 : bool bRight = true;
5005 :
5006 0 : switch( rFont.GetOrientation(bVerticalLayout) )
5007 : {
5008 : case 0 :
5009 0 : bLeft = !bJoinWithPrev;
5010 0 : bRight = !bJoinWithNext;
5011 0 : break;
5012 : case 900 :
5013 0 : bBottom = !bJoinWithPrev;
5014 0 : bTop = !bJoinWithNext;
5015 0 : break;
5016 : case 1800 :
5017 0 : bRight = !bJoinWithPrev;
5018 0 : bLeft = !bJoinWithNext;
5019 0 : break;
5020 : case 2700 :
5021 0 : bTop = !bJoinWithPrev;
5022 0 : bBottom = !bJoinWithNext;
5023 0 : break;
5024 : }
5025 :
5026 : // Paint shadow (reduce painting rect)
5027 : {
5028 : const SvxShadowItem aShadow(
5029 0 : 0, &rFont.GetShadowColor(), rFont.GetShadowWidth(),
5030 0 : rFont.GetAbsShadowLocation(bVerticalLayout));
5031 :
5032 0 : if( aShadow.GetLocation() != SVX_SHADOW_NONE )
5033 : {
5034 : lcl_PaintShadow( SwRect(aAlignedRect), aAlignedRect, aShadow,
5035 0 : false, bTop, bBottom, bLeft, bRight);
5036 0 : }
5037 : }
5038 :
5039 : // Init borders, after this initialization top, bottom, right and left means the
5040 : // absolute position
5041 : boost::optional<editeng::SvxBorderLine> aTopBorder =
5042 0 : (bTop ? rFont.GetAbsTopBorder(bVerticalLayout) : boost::none);
5043 : boost::optional<editeng::SvxBorderLine> aBottomBorder =
5044 0 : (bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout) : boost::none);
5045 : boost::optional<editeng::SvxBorderLine> aLeftBorder =
5046 0 : (bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout) : boost::none);
5047 : boost::optional<editeng::SvxBorderLine> aRightBorder =
5048 0 : (bRight ? rFont.GetAbsRightBorder(bVerticalLayout) : boost::none);
5049 :
5050 0 : if( aTopBorder )
5051 : {
5052 0 : sal_uInt16 nOffset = aTopBorder->GetDistance();
5053 :
5054 : Point aLeftTop(
5055 0 : aAlignedRect.Left() - nOffset,
5056 0 : aAlignedRect.Top() - nOffset);
5057 : Point aRightBottom(
5058 0 : aAlignedRect.Right() + nOffset,
5059 0 : aAlignedRect.Top() - nOffset + aTopBorder->GetScaledWidth());
5060 :
5061 : lcl_MakeBorderLine(
5062 : SwRect(aLeftTop, aRightBottom),
5063 : false, true, false,
5064 0 : aTopBorder.get(),
5065 0 : aLeftBorder.get_ptr(),
5066 0 : aRightBorder.get_ptr());
5067 : }
5068 :
5069 0 : if( aBottomBorder )
5070 : {
5071 0 : aBottomBorder->SetMirrorWidths(true);
5072 :
5073 : Point aLeftTop(
5074 : aAlignedRect.Left(),
5075 0 : aAlignedRect.Bottom() - aBottomBorder.get().GetScaledWidth());
5076 : Point aRightBottom(
5077 : aAlignedRect.Right(),
5078 0 : aAlignedRect.Bottom());
5079 :
5080 : lcl_MakeBorderLine(
5081 : SwRect(aLeftTop, aRightBottom),
5082 : false, false, false,
5083 0 : aBottomBorder.get(),
5084 0 : aLeftBorder.get_ptr(),
5085 0 : aRightBorder.get_ptr());
5086 : }
5087 :
5088 0 : if( aLeftBorder )
5089 : {
5090 0 : sal_uInt16 nOffset = aLeftBorder->GetDistance();
5091 :
5092 : Point aLeftTop(
5093 0 : aAlignedRect.Left() - nOffset,
5094 0 : aAlignedRect.Top() - nOffset);
5095 : Point aRightBottom(
5096 0 : aAlignedRect.Left() - nOffset + aLeftBorder->GetScaledWidth(),
5097 0 : aAlignedRect.Bottom() + nOffset);
5098 :
5099 : lcl_MakeBorderLine(
5100 : SwRect(aLeftTop, aRightBottom),
5101 : true, true, true,
5102 0 : aLeftBorder.get(),
5103 0 : aTopBorder.get_ptr(),
5104 0 : aBottomBorder.get_ptr());
5105 : }
5106 :
5107 0 : if( aRightBorder )
5108 : {
5109 0 : aRightBorder->SetMirrorWidths(true);
5110 :
5111 : Point aLeftTop(
5112 0 : aAlignedRect.Right() - aRightBorder.get().GetScaledWidth(),
5113 0 : aAlignedRect.Top());
5114 : Point aRightBottom(
5115 : aAlignedRect.Right(),
5116 0 : aAlignedRect.Bottom());
5117 :
5118 : lcl_MakeBorderLine(
5119 : SwRect(aLeftTop, aRightBottom),
5120 : true, false, true,
5121 0 : aRightBorder.get(),
5122 0 : aTopBorder.get_ptr(),
5123 0 : aBottomBorder.get_ptr());
5124 0 : }
5125 0 : }
5126 :
5127 : // #i15844#
5128 0 : static const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
5129 : {
5130 : OSL_ENSURE( rFrm.IsCellFrm(),
5131 : "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" );
5132 :
5133 0 : const SwFrm* pTmpFrm = &rFrm;
5134 0 : do
5135 : {
5136 0 : if ( pTmpFrm->GetNext() )
5137 0 : return pTmpFrm->GetNext();
5138 :
5139 0 : pTmpFrm = pTmpFrm->GetUpper()->GetUpper();
5140 : }
5141 : while ( pTmpFrm->IsCellFrm() );
5142 :
5143 0 : return 0;
5144 : }
5145 :
5146 : /** local method to determine cell frame, from which the border attributes
5147 : for paint of top/bottom border has to be used.
5148 :
5149 : OD 21.02.2003 #b4779636#, #107692#
5150 :
5151 : @param _pCellFrm
5152 : input parameter - constant pointer to cell frame for which the cell frame
5153 : for the border attributes has to be determined.
5154 :
5155 : @param _rCellBorderAttrs
5156 : input parameter - constant reference to the border attributes of cell frame
5157 : <_pCellFrm>.
5158 :
5159 : @param _bTop
5160 : input parameter - boolean, that controls, if cell frame for top border or
5161 : for bottom border has to be determined.
5162 :
5163 : @return constant pointer to cell frame, for which the border attributes has
5164 : to be used
5165 : */
5166 0 : static const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm* _pCellFrm,
5167 : const SwBorderAttrs& _rCellBorderAttrs,
5168 : const bool _bTop )
5169 : {
5170 : OSL_ENSURE( _pCellFrm, "No cell frame available, dying soon" );
5171 :
5172 : // determine, if cell frame is at bottom/top border of a table frame and
5173 : // the table frame has/is a follow.
5174 0 : const SwFrm* pTmpFrm = _pCellFrm;
5175 0 : bool bCellAtBorder = true;
5176 0 : bool bCellAtLeftBorder = !_pCellFrm->GetPrev();
5177 0 : bool bCellAtRightBorder = !_pCellFrm->GetNext();
5178 0 : while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() )
5179 : {
5180 0 : pTmpFrm = pTmpFrm->GetUpper();
5181 0 : if ( pTmpFrm->IsRowFrm() &&
5182 0 : (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext())
5183 : )
5184 : {
5185 0 : bCellAtBorder = false;
5186 : }
5187 0 : if ( pTmpFrm->IsCellFrm() )
5188 : {
5189 0 : if ( pTmpFrm->GetPrev() )
5190 : {
5191 0 : bCellAtLeftBorder = false;
5192 : }
5193 0 : if ( pTmpFrm->GetNext() )
5194 : {
5195 0 : bCellAtRightBorder = false;
5196 : }
5197 : }
5198 : }
5199 : OSL_ENSURE( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" );
5200 :
5201 0 : const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm);
5202 : const SwTabFrm* pParentTabFrm =
5203 0 : static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper());
5204 :
5205 0 : const bool bCellNeedsAttribute = bCellAtBorder &&
5206 : ( _bTop ?
5207 : // bCellInFirstRowWithMaster
5208 0 : ( !pParentRowFrm->GetPrev() &&
5209 0 : pParentTabFrm->IsFollow() &&
5210 0 : 0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) :
5211 : // bCellInLastRowWithFollow
5212 0 : ( !pParentRowFrm->GetNext() &&
5213 0 : pParentTabFrm->GetFollow() )
5214 0 : );
5215 :
5216 0 : const SwFrm* pRet = _pCellFrm;
5217 0 : if ( bCellNeedsAttribute )
5218 : {
5219 : // determine, if cell frame has no borders inside the table.
5220 0 : const SwFrm* pNextCell = 0;
5221 0 : bool bNoBordersInside = false;
5222 :
5223 0 : if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) )
5224 : {
5225 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell );
5226 0 : const SwBorderAttrs &rBorderAttrs = *aAccess.Get();
5227 0 : const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox();
5228 0 : bCellAtRightBorder = !lcl_HasNextCell( *pNextCell );
5229 : bNoBordersInside =
5230 0 : ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) &&
5231 0 : !rBorderBox.GetLeft() &&
5232 0 : ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
5233 0 : ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
5234 : }
5235 : else
5236 : {
5237 0 : const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox();
5238 : bNoBordersInside =
5239 0 : ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) &&
5240 0 : ( !rBorderBox.GetLeft() || bCellAtLeftBorder ) &&
5241 0 : ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
5242 0 : ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
5243 : }
5244 :
5245 0 : if ( bNoBordersInside )
5246 : {
5247 0 : if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() )
5248 : {
5249 : //-hack
5250 : // Cell frame has no top border and no border inside the table, but
5251 : // it is at the top border of a table frame, which is a follow.
5252 : // Thus, use border attributes of cell frame in first row of complete table.
5253 : // First, determine first table frame of complete table.
5254 0 : SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true );
5255 : // determine first row of complete table.
5256 0 : const SwFrm* pFirstRow = pMasterTabFrm->GetLower();
5257 : // return first cell in first row
5258 0 : SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower());
5259 0 : while ( !pLowerCell->IsCellFrm() ||
5260 0 : ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
5261 : )
5262 : {
5263 0 : pLowerCell = pLowerCell->GetLower();
5264 : }
5265 : OSL_ENSURE( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
5266 0 : pRet = pLowerCell;
5267 : }
5268 0 : else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() )
5269 : {
5270 : //-hack
5271 : // Cell frame has no bottom border and no border inside the table,
5272 : // but it is at the bottom border of a table frame, which has a follow.
5273 : // Thus, use border attributes of cell frame in last row of complete table.
5274 : // First, determine last table frame of complete table.
5275 0 : SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow());
5276 0 : while ( pLastTabFrm->GetFollow() )
5277 : {
5278 0 : pLastTabFrm = pLastTabFrm->GetFollow();
5279 : }
5280 : // determine last row of complete table.
5281 0 : SwFrm* pLastRow = pLastTabFrm->GetLastLower();
5282 : // return first bottom border cell in last row
5283 0 : SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower());
5284 0 : while ( !pLowerCell->IsCellFrm() ||
5285 0 : ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
5286 : )
5287 : {
5288 0 : if ( pLowerCell->IsRowFrm() )
5289 : {
5290 0 : while ( pLowerCell->GetNext() )
5291 : {
5292 0 : pLowerCell = pLowerCell->GetNext();
5293 : }
5294 : }
5295 0 : pLowerCell = pLowerCell->GetLower();
5296 : }
5297 : OSL_ENSURE( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
5298 0 : pRet = pLowerCell;
5299 : }
5300 : }
5301 : }
5302 :
5303 0 : return pRet;
5304 : }
5305 :
5306 0 : drawinglayer::processor2d::BaseProcessor2D * SwFrm::CreateProcessor2D( ) const
5307 : {
5308 0 : basegfx::B2DRange aViewRange;
5309 :
5310 0 : SdrPage *pDrawPage = getRootFrm()->GetCurrShell()->Imp()->GetPageView()->GetPage();
5311 : const drawinglayer::geometry::ViewInformation2D aNewViewInfos(
5312 : basegfx::B2DHomMatrix( ),
5313 : getRootFrm()->GetCurrShell()->GetOut()->GetViewTransformation(),
5314 : aViewRange,
5315 : GetXDrawPageForSdrPage( pDrawPage ),
5316 : 0.0,
5317 0 : uno::Sequence< beans::PropertyValue >() );
5318 :
5319 : return drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
5320 0 : *getRootFrm()->GetCurrShell()->GetOut(),
5321 0 : aNewViewInfos );
5322 : }
5323 :
5324 0 : void SwFrm::ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DSequence& rSequence ) const
5325 : {
5326 0 : drawinglayer::processor2d::BaseProcessor2D * pProcessor2D = CreateProcessor2D();
5327 :
5328 0 : if ( pProcessor2D )
5329 : {
5330 0 : pProcessor2D->process( rSequence );
5331 0 : delete pProcessor2D;
5332 : }
5333 0 : }
5334 :
5335 : /// Paints shadows and borders
5336 0 : void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
5337 : const SwBorderAttrs &rAttrs ) const
5338 : {
5339 : // There's nothing (Row,Body,Ftn,Root,Column,NoTxt) need to do here
5340 0 : if ( (GetType() & 0x90C5) )
5341 0 : return;
5342 :
5343 0 : if ( (GetType() & 0x2000) && //Cell
5344 0 : !pGlobalShell->GetViewOptions()->IsTable() )
5345 0 : return;
5346 :
5347 : // #i29550#
5348 0 : if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
5349 : {
5350 0 : const SwTabFrm* pTabFrm = FindTabFrm();
5351 0 : if ( pTabFrm->IsCollapsingBorders() )
5352 0 : return;
5353 :
5354 0 : if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) )
5355 0 : return;
5356 : }
5357 :
5358 0 : const bool bLine = rAttrs.IsLine() ? true : false;
5359 0 : const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE;
5360 :
5361 : // - flag to control,
5362 : //-hack has to be used.
5363 0 : const bool bb4779636HackActive = true;
5364 :
5365 0 : const SwFrm* pCellFrmForBottomBorderAttrs = 0;
5366 0 : const SwFrm* pCellFrmForTopBorderAttrs = 0;
5367 0 : bool bFoundCellForTopOrBorderAttrs = false;
5368 0 : if ( bb4779636HackActive && IsCellFrm() )
5369 : {
5370 0 : pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false );
5371 0 : if ( pCellFrmForBottomBorderAttrs != this )
5372 0 : bFoundCellForTopOrBorderAttrs = true;
5373 0 : pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true );
5374 0 : if ( pCellFrmForTopBorderAttrs != this )
5375 0 : bFoundCellForTopOrBorderAttrs = true;
5376 : }
5377 :
5378 : // - add condition <bFoundCellForTopOrBorderAttrs>
5379 : //-hack
5380 0 : if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs )
5381 : {
5382 : //If the rectangle is completely inside the PrtArea, no border needs to
5383 : //be painted.
5384 : //For the PrtArea the aligned value needs to be used, otherwise it could
5385 : //happen, that some parts won't be processed.
5386 0 : SwRect aRect( Prt() );
5387 0 : aRect += Frm().Pos();
5388 0 : ::SwAlignRect( aRect, pGlobalShell );
5389 : // OD 27.09.2002 #103636# - new local boolean variable in order to
5390 : // suspend border paint under special cases - see below.
5391 : // NOTE: This is a fix for the implementation of feature #99657#.
5392 0 : bool bDrawOnlyShadowForTransparentFrame = false;
5393 0 : if ( aRect.IsInside( rRect ) )
5394 : {
5395 : // OD 27.09.2002 #103636# - paint shadow, if background is transparent.
5396 : // Because of introduced transparent background for fly frame #99657#,
5397 : // the shadow have to be drawn if the background is transparent,
5398 : // in spite the fact that the paint rectangle <rRect> lies fully
5399 : // in the printing area.
5400 : // NOTE to chosen solution:
5401 : // On transparent background, continue processing, but suspend
5402 : // drawing of border by setting <bDrawOnlyShadowForTransparentFrame>
5403 : // to true.
5404 0 : if ( IsLayoutFrm() &&
5405 0 : static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() )
5406 : {
5407 0 : bDrawOnlyShadowForTransparentFrame = true;
5408 : }
5409 : else
5410 : {
5411 0 : return;
5412 : }
5413 : }
5414 :
5415 0 : if ( !pPage )
5416 0 : pPage = FindPageFrm();
5417 :
5418 0 : ::lcl_CalcBorderRect( aRect, this, rAttrs, true );
5419 0 : rAttrs.SetGetCacheLine( sal_True );
5420 0 : if ( bShadow )
5421 0 : PaintShadow( rRect, aRect, rAttrs );
5422 : // OD 27.09.2002 #103636# - suspend drawing of border
5423 : // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
5424 : // - add condition <bFoundCellForTopOrBorderAttrs>
5425 : //-hack.
5426 0 : if ( ( bLine || bFoundCellForTopOrBorderAttrs ) &&
5427 0 : !bDrawOnlyShadowForTransparentFrame )
5428 : {
5429 0 : const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this;
5430 0 : SWRECTFN( pDirRefFrm )
5431 0 : ::lcl_PaintLeftRightLine ( true, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
5432 0 : ::lcl_PaintLeftRightLine ( false, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
5433 0 : if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) )
5434 : {
5435 : // -
5436 : //-hack
5437 : // paint is found, paint its top border.
5438 0 : if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this )
5439 : {
5440 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(),
5441 0 : pCellFrmForTopBorderAttrs );
5442 0 : const SwBorderAttrs &rTopAttrs = *aAccess.Get();
5443 0 : ::lcl_PaintTopBottomLine( true, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect );
5444 : }
5445 : else
5446 : {
5447 0 : ::lcl_PaintTopBottomLine( true, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
5448 : }
5449 : }
5450 0 : if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) )
5451 : {
5452 : // -
5453 : //-hack
5454 : // paint is found, paint its bottom border.
5455 0 : if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this )
5456 : {
5457 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(),
5458 0 : pCellFrmForBottomBorderAttrs );
5459 0 : const SwBorderAttrs &rBottomAttrs = *aAccess.Get();
5460 0 : ::lcl_PaintTopBottomLine(false, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect);
5461 : }
5462 : else
5463 : {
5464 0 : ::lcl_PaintTopBottomLine(false, *(this), *(pPage), aRect, rRect, rAttrs, fnRect);
5465 : }
5466 : }
5467 : }
5468 0 : rAttrs.SetGetCacheLine( sal_False );
5469 : }
5470 : }
5471 :
5472 : /* Special implementation because of the footnote line.
5473 : |* Currently only the top frame needs to be taken into account.
5474 : |* Other lines and shadows are set aside.
5475 : |*/
5476 0 : void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
5477 : const SwBorderAttrs & ) const
5478 : {
5479 : //If the rectangle is completely inside the PrtArea, no border needs to
5480 : //be painted.
5481 0 : SwRect aRect( Prt() );
5482 0 : aRect.Pos() += Frm().Pos();
5483 0 : if ( !aRect.IsInside( rRect ) )
5484 0 : PaintLine( rRect, pPage );
5485 0 : }
5486 :
5487 : /// Paint footnote lines.
5488 0 : void SwFtnContFrm::PaintLine( const SwRect& rRect,
5489 : const SwPageFrm *pPage ) const
5490 : {
5491 : //The length of the line is derived from the percentual indication on the
5492 : //PageDesc. The position is also stated on the PageDesc.
5493 : //The pen can directly be taken from the PageDesc.
5494 :
5495 0 : if ( !pPage )
5496 0 : pPage = FindPageFrm();
5497 0 : const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
5498 :
5499 0 : SWRECTFN( this )
5500 0 : SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)();
5501 0 : Fraction aFract( nPrtWidth, 1 );
5502 0 : const SwTwips nWidth = (long)(aFract *= rInf.GetWidth());
5503 :
5504 0 : SwTwips nX = (this->*fnRect->fnGetPrtLeft)();
5505 0 : switch ( rInf.GetAdj() )
5506 : {
5507 : case FTNADJ_CENTER:
5508 0 : nX += nPrtWidth/2 - nWidth/2; break;
5509 : case FTNADJ_RIGHT:
5510 0 : nX += nPrtWidth - nWidth; break;
5511 : case FTNADJ_LEFT:
5512 0 : /* do nothing */; break;
5513 : default:
5514 : OSL_ENSURE( !this, "New adjustment for footnote lines?" );
5515 : }
5516 0 : SwTwips nLineWidth = rInf.GetLineWidth();
5517 : const SwRect aLineRect = bVert ?
5518 0 : SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth,
5519 : nX), Size( nLineWidth, nWidth ) )
5520 0 : : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ),
5521 0 : Size( nWidth, rInf.GetLineWidth()));
5522 0 : if ( aLineRect.HasArea() )
5523 0 : PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor(),
5524 0 : rInf.GetLineStyle() );
5525 0 : }
5526 :
5527 : /// Paints the separator line for inside columns
5528 0 : void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol,
5529 : const SwPageFrm *pPage ) const
5530 : {
5531 0 : const SwFrm *pCol = Lower();
5532 0 : if ( !pCol || !pCol->IsColumnFrm() )
5533 0 : return;
5534 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
5535 0 : SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
5536 :
5537 0 : SwRect aLineRect = Prt();
5538 0 : aLineRect += Frm().Pos();
5539 :
5540 0 : SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight())
5541 0 : / 100 - (aLineRect.*fnRect->fnGetHeight)();
5542 0 : SwTwips nBottom = 0;
5543 :
5544 0 : switch ( rFmtCol.GetLineAdj() )
5545 : {
5546 : case COLADJ_CENTER:
5547 0 : nBottom = nTop / 2; nTop -= nBottom; break;
5548 : case COLADJ_TOP:
5549 0 : nBottom = nTop; nTop = 0; break;
5550 : case COLADJ_BOTTOM:
5551 0 : break;
5552 : default:
5553 : OSL_ENSURE( !this, "New adjustment for column lines?" );
5554 : }
5555 :
5556 0 : if( nTop )
5557 0 : (aLineRect.*fnRect->fnSubTop)( nTop );
5558 0 : if( nBottom )
5559 0 : (aLineRect.*fnRect->fnAddBottom)( nBottom );
5560 :
5561 0 : SwTwips nPenHalf = rFmtCol.GetLineWidth();
5562 0 : (aLineRect.*fnRect->fnSetWidth)( nPenHalf );
5563 0 : nPenHalf /= 2;
5564 :
5565 : //We need to be a bit generous here, to not lose something.
5566 0 : SwRect aRect( rRect );
5567 0 : (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW );
5568 0 : (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW );
5569 0 : SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight;
5570 0 : while ( pCol->GetNext() )
5571 : {
5572 : (aLineRect.*fnRect->fnSetPosX)
5573 0 : ( (pCol->Frm().*fnGetX)() - nPenHalf );
5574 0 : if ( aRect.IsOver( aLineRect ) )
5575 0 : PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor(),
5576 0 : rFmtCol.GetLineStyle() );
5577 0 : pCol = pCol->GetNext();
5578 : }
5579 : }
5580 :
5581 0 : void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const
5582 : {
5583 0 : if( !bHasGrid || pRetoucheFly || pRetoucheFly2 )
5584 0 : return;
5585 0 : SwTextGridItem const*const pGrid(GetGridItem(this));
5586 0 : if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ?
5587 0 : pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) )
5588 : {
5589 0 : const SwLayoutFrm* pBody = FindBodyCont();
5590 0 : if( pBody )
5591 : {
5592 0 : SwRect aGrid( pBody->Prt() );
5593 0 : aGrid += pBody->Frm().Pos();
5594 :
5595 0 : SwRect aInter( aGrid );
5596 0 : aInter.Intersection( rRect );
5597 0 : if( aInter.HasArea() )
5598 : {
5599 0 : sal_Bool bGrid = pGrid->GetRubyTextBelow();
5600 0 : bool bCell = GRID_LINES_CHARS == pGrid->GetGridType();
5601 0 : long nGrid = pGrid->GetBaseHeight();
5602 0 : const SwDoc* pDoc = GetFmt()->GetDoc();
5603 0 : long nGridWidth = GetGridWidth(*pGrid, *pDoc);
5604 0 : long nRuby = pGrid->GetRubyHeight();
5605 0 : long nSum = nGrid + nRuby;
5606 0 : const Color *pCol = &pGrid->GetColor();
5607 :
5608 0 : SwTwips nRight = aInter.Left() + aInter.Width();
5609 0 : SwTwips nBottom = aInter.Top() + aInter.Height();
5610 0 : if( IsVertical() )
5611 : {
5612 0 : SwTwips nOrig = aGrid.Left() + aGrid.Width();
5613 0 : SwTwips nY = nOrig + nSum *
5614 0 : ( ( nOrig - aInter.Left() ) / nSum );
5615 : SwRect aTmp( Point( nY, aInter.Top() ),
5616 0 : Size( 1, aInter.Height() ) );
5617 0 : SwTwips nX = aGrid.Top() + nGrid *
5618 0 : ( ( aInter.Top() - aGrid.Top() )/ nGrid );
5619 0 : if( nX < aInter.Top() )
5620 0 : nX += nGrid;
5621 0 : SwTwips nGridBottom = aGrid.Top() + aGrid.Height();
5622 0 : bool bLeft = aGrid.Top() >= aInter.Top();
5623 0 : bool bRight = nGridBottom <= nBottom;
5624 0 : bool bBorder = bLeft || bRight;
5625 0 : while( nY > nRight )
5626 : {
5627 0 : aTmp.Pos().X() = nY;
5628 0 : if( bGrid )
5629 : {
5630 0 : nY -= nGrid;
5631 0 : SwTwips nPosY = std::max( aInter.Left(), nY );
5632 0 : SwTwips nHeight = std::min(nRight, aTmp.Pos().X())-nPosY;
5633 0 : if( nHeight > 0 )
5634 : {
5635 0 : if( bCell )
5636 : {
5637 : SwRect aVert( Point( nPosY, nX ),
5638 0 : Size( nHeight, 1 ) );
5639 0 : while( aVert.Top() <= nBottom )
5640 : {
5641 0 : PaintBorderLine(rRect,aVert,this,pCol);
5642 0 : aVert.Pos().Y() += nGrid;
5643 : }
5644 : }
5645 0 : else if( bBorder )
5646 : {
5647 : SwRect aVert( Point( nPosY, aGrid.Top() ),
5648 0 : Size( nHeight, 1 ) );
5649 0 : if( bLeft )
5650 0 : PaintBorderLine(rRect,aVert,this,pCol);
5651 0 : if( bRight )
5652 : {
5653 0 : aVert.Pos().Y() = nGridBottom;
5654 0 : PaintBorderLine(rRect,aVert,this,pCol);
5655 : }
5656 : }
5657 : }
5658 : }
5659 : else
5660 : {
5661 0 : nY -= nRuby;
5662 0 : if( bBorder )
5663 : {
5664 0 : SwTwips nPos = std::max( aInter.Left(), nY );
5665 0 : SwTwips nW = std::min(nRight, aTmp.Pos().X()) - nPos;
5666 : SwRect aVert( Point( nPos, aGrid.Top() ),
5667 0 : Size( nW, 1 ) );
5668 0 : if( nW > 0 )
5669 : {
5670 0 : if( bLeft )
5671 0 : PaintBorderLine(rRect,aVert,this,pCol);
5672 0 : if( bRight )
5673 : {
5674 0 : aVert.Pos().Y() = nGridBottom;
5675 0 : PaintBorderLine(rRect,aVert,this,pCol);
5676 : }
5677 : }
5678 : }
5679 : }
5680 0 : bGrid = !bGrid;
5681 : }
5682 0 : while( nY >= aInter.Left() )
5683 : {
5684 0 : aTmp.Pos().X() = nY;
5685 0 : PaintBorderLine( rRect, aTmp, this, pCol);
5686 0 : if( bGrid )
5687 : {
5688 0 : nY -= nGrid;
5689 0 : SwTwips nHeight = aTmp.Pos().X()
5690 0 : - std::max(aInter.Left(), nY );
5691 0 : if( nHeight > 0 )
5692 : {
5693 0 : if( bCell )
5694 : {
5695 0 : SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5696 0 : nX ), Size( nHeight, 1 ) );
5697 0 : while( aVert.Top() <= nBottom )
5698 : {
5699 0 : PaintBorderLine(rRect,aVert,this,pCol);
5700 0 : aVert.Pos().Y() += nGrid;
5701 : }
5702 : }
5703 0 : else if( bBorder )
5704 : {
5705 0 : SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5706 0 : aGrid.Top() ), Size( nHeight, 1 ) );
5707 0 : if( bLeft )
5708 0 : PaintBorderLine(rRect,aVert,this,pCol);
5709 0 : if( bRight )
5710 : {
5711 0 : aVert.Pos().Y() = nGridBottom;
5712 0 : PaintBorderLine(rRect,aVert,this,pCol);
5713 : }
5714 : }
5715 : }
5716 : }
5717 : else
5718 : {
5719 0 : nY -= nRuby;
5720 0 : if( bBorder )
5721 : {
5722 0 : SwTwips nPos = std::max( aInter.Left(), nY );
5723 0 : SwTwips nW = std::min(nRight, aTmp.Pos().X()) - nPos;
5724 : SwRect aVert( Point( nPos, aGrid.Top() ),
5725 0 : Size( nW, 1 ) );
5726 0 : if( nW > 0 )
5727 : {
5728 0 : if( bLeft )
5729 0 : PaintBorderLine(rRect,aVert,this,pCol);
5730 0 : if( bRight )
5731 : {
5732 0 : aVert.Pos().Y() = nGridBottom;
5733 0 : PaintBorderLine(rRect,aVert,this,pCol);
5734 : }
5735 : }
5736 : }
5737 : }
5738 0 : bGrid = !bGrid;
5739 : }
5740 : }
5741 : else
5742 : {
5743 0 : SwTwips nOrig = aGrid.Top();
5744 0 : SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum );
5745 : SwRect aTmp( Point( aInter.Left(), nY ),
5746 0 : Size( aInter.Width(), 1 ) );
5747 : //for textgrid refactor
5748 0 : SwTwips nX = aGrid.Left() + nGridWidth *
5749 0 : ( ( aInter.Left() - aGrid.Left() )/ nGridWidth );
5750 0 : if( nX < aInter.Left() )
5751 0 : nX += nGridWidth;
5752 0 : SwTwips nGridRight = aGrid.Left() + aGrid.Width();
5753 0 : bool bLeft = aGrid.Left() >= aInter.Left();
5754 0 : bool bRight = nGridRight <= nRight;
5755 0 : bool bBorder = bLeft || bRight;
5756 0 : while( nY < aInter.Top() )
5757 : {
5758 0 : aTmp.Pos().setY(nY);
5759 0 : if( bGrid )
5760 : {
5761 0 : nY += nGrid;
5762 0 : SwTwips nPosY = std::max( aInter.Top(), aTmp.Pos().getY() );
5763 0 : SwTwips nHeight = std::min(nBottom, nY ) - nPosY;
5764 0 : if( nHeight )
5765 : {
5766 0 : if( bCell )
5767 : {
5768 : SwRect aVert( Point( nX, nPosY ),
5769 0 : Size( 1, nHeight ) );
5770 0 : while( aVert.Left() <= nRight )
5771 : {
5772 0 : PaintBorderLine(rRect,aVert,this,pCol);
5773 0 : aVert.Pos().X() += nGridWidth; //for textgrid refactor
5774 : }
5775 : }
5776 0 : else if ( bBorder )
5777 : {
5778 : SwRect aVert( Point( aGrid.Left(), nPosY ),
5779 0 : Size( 1, nHeight ) );
5780 0 : if( bLeft )
5781 0 : PaintBorderLine(rRect,aVert,this,pCol);
5782 0 : if( bRight )
5783 : {
5784 0 : aVert.Pos().X() = nGridRight;
5785 0 : PaintBorderLine(rRect,aVert,this,pCol);
5786 : }
5787 : }
5788 : }
5789 : }
5790 : else
5791 : {
5792 0 : nY += nRuby;
5793 0 : if( bBorder )
5794 : {
5795 0 : SwTwips nPos = std::max(aInter.Top(),aTmp.Pos().getY());
5796 0 : SwTwips nH = std::min( nBottom, nY ) - nPos;
5797 : SwRect aVert( Point( aGrid.Left(), nPos ),
5798 0 : Size( 1, nH ) );
5799 0 : if( nH > 0 )
5800 : {
5801 0 : if( bLeft )
5802 0 : PaintBorderLine(rRect,aVert,this,pCol);
5803 0 : if( bRight )
5804 : {
5805 0 : aVert.Pos().setX(nGridRight);
5806 0 : PaintBorderLine(rRect,aVert,this,pCol);
5807 : }
5808 : }
5809 : }
5810 : }
5811 0 : bGrid = !bGrid;
5812 : }
5813 0 : while( nY <= nBottom )
5814 : {
5815 0 : aTmp.Pos().setY(nY);
5816 0 : PaintBorderLine( rRect, aTmp, this, pCol);
5817 0 : if( bGrid )
5818 : {
5819 0 : nY += nGrid;
5820 0 : SwTwips nHeight = std::min(nBottom, nY) - aTmp.Pos().getY();
5821 0 : if( nHeight )
5822 : {
5823 0 : if( bCell )
5824 : {
5825 0 : SwRect aVert( Point( nX, aTmp.Pos().getY() ),
5826 0 : Size( 1, nHeight ) );
5827 0 : while( aVert.Left() <= nRight )
5828 : {
5829 0 : PaintBorderLine( rRect, aVert, this, pCol);
5830 0 : aVert.Pos().setX(aVert.Pos().getX() + nGridWidth); //for textgrid refactor
5831 : }
5832 : }
5833 0 : else if( bBorder )
5834 : {
5835 : SwRect aVert( Point( aGrid.Left(),
5836 0 : aTmp.Pos().getY() ), Size( 1, nHeight ) );
5837 0 : if( bLeft )
5838 0 : PaintBorderLine(rRect,aVert,this,pCol);
5839 0 : if( bRight )
5840 : {
5841 0 : aVert.Pos().setX(nGridRight);
5842 0 : PaintBorderLine(rRect,aVert,this,pCol);
5843 : }
5844 : }
5845 : }
5846 : }
5847 : else
5848 : {
5849 0 : nY += nRuby;
5850 0 : if( bBorder )
5851 : {
5852 0 : SwTwips nPos = std::max(aInter.Top(),aTmp.Pos().Y());
5853 0 : SwTwips nH = std::min( nBottom, nY ) - nPos;
5854 : SwRect aVert( Point( aGrid.Left(), nPos ),
5855 0 : Size( 1, nH ) );
5856 0 : if( nH > 0 )
5857 : {
5858 0 : if( bLeft )
5859 0 : PaintBorderLine(rRect,aVert,this,pCol);
5860 0 : if( bRight )
5861 : {
5862 0 : aVert.Pos().setX(nGridRight);
5863 0 : PaintBorderLine(rRect,aVert,this,pCol);
5864 : }
5865 : }
5866 : }
5867 : }
5868 0 : bGrid = !bGrid;
5869 : }
5870 : }
5871 : }
5872 : }
5873 : }
5874 : }
5875 :
5876 : /** paint margin area of a page
5877 :
5878 : OD 20.11.2002 for #104598#:
5879 : implement paint of margin area; margin area will be painted for a
5880 : view shell with a window and if the document is not in online layout.
5881 :
5882 : @param _rOutputRect
5883 : input parameter - constant instance reference of the rectangle, for
5884 : which an output has to be generated.
5885 :
5886 : @param _pViewShell
5887 : input parameter - instance of the view shell, on which the output
5888 : has to be generated.
5889 : */
5890 0 : void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect,
5891 : SwViewShell* _pViewShell ) const
5892 : {
5893 0 : if ( _pViewShell->GetWin() &&
5894 0 : !_pViewShell->GetViewOptions()->getBrowseMode() )
5895 : {
5896 0 : SwRect aPgPrtRect( Prt() );
5897 0 : aPgPrtRect.Pos() += Frm().Pos();
5898 0 : if ( !aPgPrtRect.IsInside( _rOutputRect ) )
5899 : {
5900 0 : SwRect aPgRect = Frm();
5901 0 : aPgRect._Intersection( _rOutputRect );
5902 0 : if(aPgRect.Height() < 0 || aPgRect.Width() <= 0) // No intersection
5903 0 : return;
5904 0 : SwRegionRects aPgRegion( aPgRect );
5905 0 : aPgRegion -= aPgPrtRect;
5906 : //const SwPageFrm* pPage = static_cast<const SwPageFrm*>(this);
5907 : //if ( pPage->GetSortedObjs() )
5908 : // ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion );
5909 0 : if ( !aPgRegion.empty() )
5910 : {
5911 0 : OutputDevice *pOut = _pViewShell->GetOut();
5912 0 : if ( pOut->GetFillColor() != aGlobalRetoucheColor )
5913 0 : pOut->SetFillColor( aGlobalRetoucheColor );
5914 0 : for ( sal_uInt16 i = 0; i < aPgRegion.size(); ++i )
5915 : {
5916 0 : if ( 1 < aPgRegion.size() )
5917 : {
5918 0 : ::SwAlignRect( aPgRegion[i], pGlobalShell );
5919 0 : if( !aPgRegion[i].HasArea() )
5920 0 : continue;
5921 : }
5922 0 : pOut->DrawRect(aPgRegion[i].SVRect());
5923 : }
5924 0 : }
5925 : }
5926 : }
5927 : }
5928 :
5929 : const sal_Int8 SwPageFrm::mnShadowPxWidth = 9;
5930 :
5931 0 : sal_Bool SwPageFrm::IsRightShadowNeeded() const
5932 : {
5933 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
5934 0 : const bool bIsLTR = getRootFrm()->IsLeftToRightViewLayout();
5935 :
5936 : // We paint the right shadow if we're not in book mode
5937 : // or if we've no sibling or are the last page of the "row"
5938 0 : return !pSh || (!pSh->GetViewOptions()->IsViewLayoutBookMode()) || !GetNext()
5939 0 : || (this == Lower()) || (bIsLTR && OnRightPage())
5940 0 : || (!bIsLTR && !OnRightPage());
5941 :
5942 : }
5943 :
5944 0 : sal_Bool SwPageFrm::IsLeftShadowNeeded() const
5945 : {
5946 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
5947 0 : const bool bIsLTR = getRootFrm()->IsLeftToRightViewLayout();
5948 :
5949 : // We paint the left shadow if we're not in book mode
5950 : // or if we've no sibling or are the last page of the "row"
5951 0 : return !pSh || (!pSh->GetViewOptions()->IsViewLayoutBookMode()) || !GetPrev()
5952 0 : || (bIsLTR && !OnRightPage())
5953 0 : || (!bIsLTR && OnRightPage());
5954 : }
5955 :
5956 : /** determine rectangle for bottom page shadow
5957 :
5958 : OD 12.02.2003 for #i9719# and #105645#
5959 : */
5960 0 : /*static*/ void SwPageFrm::GetHorizontalShadowRect( const SwRect& _rPageRect,
5961 : const SwViewShell* _pViewShell,
5962 : SwRect& _orHorizontalShadowRect,
5963 : bool bPaintLeftShadow,
5964 : bool bPaintRightShadow,
5965 : bool bRightSidebar )
5966 : {
5967 0 : const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
5968 0 : SwRect aAlignedPageRect( _rPageRect );
5969 0 : ::SwAlignRect( aAlignedPageRect, _pViewShell );
5970 : SwRect aPagePxRect =
5971 0 : _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
5972 :
5973 0 : long lShadowAdjustment = mnShadowPxWidth - 1; // TODO extract this
5974 :
5975 : _orHorizontalShadowRect.Chg(
5976 0 : Point( aPagePxRect.Left() + (bPaintLeftShadow ? lShadowAdjustment : 0), 0 ),
5977 0 : Size( aPagePxRect.Width() - ( (bPaintLeftShadow ? lShadowAdjustment : 0) + (bPaintRightShadow ? lShadowAdjustment : 0) ),
5978 0 : mnShadowPxWidth ) );
5979 :
5980 0 : if(pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
5981 : {
5982 : // Notes are displayed, we've to extend borders
5983 0 : SwTwips aSidebarTotalWidth = pMgr->GetSidebarWidth(true) + pMgr->GetSidebarBorderWidth(true);
5984 0 : if(bRightSidebar)
5985 0 : _orHorizontalShadowRect.Right( _orHorizontalShadowRect.Right() + aSidebarTotalWidth );
5986 : else
5987 0 : _orHorizontalShadowRect.Left( _orHorizontalShadowRect.Left() - aSidebarTotalWidth );
5988 : }
5989 0 : }
5990 :
5991 : enum PaintArea {LEFT, RIGHT, TOP, BOTTOM};
5992 :
5993 : /// Wrapper around pOut->DrawBitmapEx.
5994 0 : static void lcl_paintBitmapExToRect(OutputDevice *pOut, const Point& aPoint, const Size& aSize, const BitmapEx& rBitmapEx, PaintArea eArea)
5995 : {
5996 : // The problem is that if we get called multiple times and the color is
5997 : // partly transparent, then the result will get darker and darker. To avoid
5998 : // this, always paint the background color before doing the real paint.
5999 0 : Rectangle aRect(aPoint, aSize);
6000 :
6001 0 : switch (eArea)
6002 : {
6003 0 : case LEFT: aRect.Left() = aRect.Right() - 1; break;
6004 0 : case RIGHT: aRect.Right() = aRect.Left() + 1; break;
6005 0 : case TOP: aRect.Top() = aRect.Bottom() - 1; break;
6006 0 : case BOTTOM: aRect.Bottom() = aRect.Top() + 1; break;
6007 : }
6008 :
6009 0 : pOut->SetFillColor( SwViewOption::GetAppBackgroundColor());
6010 0 : pOut->SetLineColor();
6011 0 : pOut->DrawRect(pOut->PixelToLogic(aRect));
6012 :
6013 : pOut->DrawBitmapEx(pOut->PixelToLogic(aPoint), pOut->PixelToLogic(aSize),
6014 : Point(0, 0), aSize,
6015 0 : rBitmapEx);
6016 0 : }
6017 :
6018 : /** paint page border and shadow
6019 :
6020 : OD 12.02.2003 for #i9719# and #105645#
6021 : implement paint of page border and shadow
6022 : */
6023 0 : /*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect,
6024 : const SwViewShell* _pViewShell,
6025 : bool bPaintLeftShadow,
6026 : bool bPaintRightShadow,
6027 : bool bRightSidebar )
6028 : {
6029 : // No shadow in prefs
6030 0 : if (!SwViewOption::IsShadow())
6031 0 : return;
6032 :
6033 : // #i16816# tagged pdf support
6034 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() );
6035 :
6036 : static vcl::DeleteOnDeinit< drawinglayer::primitive2d::DiscreteShadow > shadowMaskObj
6037 0 : ( new drawinglayer::primitive2d::DiscreteShadow( SW_RES( BMP_PAGE_SHADOW_MASK ) ));
6038 0 : static drawinglayer::primitive2d::DiscreteShadow& shadowMask = *shadowMaskObj.get();
6039 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageTopRightShadowObj( new BitmapEx );
6040 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageBottomRightShadowObj( new BitmapEx );
6041 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageBottomLeftShadowObj( new BitmapEx );
6042 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageBottomShadowBaseObj( new BitmapEx );
6043 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageRightShadowBaseObj( new BitmapEx );
6044 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageTopShadowBaseObj( new BitmapEx );
6045 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageTopLeftShadowObj( new BitmapEx );
6046 0 : static vcl::DeleteOnDeinit< BitmapEx > aPageLeftShadowBaseObj( new BitmapEx );
6047 0 : static BitmapEx& aPageTopRightShadow = *aPageTopRightShadowObj.get();
6048 0 : static BitmapEx& aPageBottomRightShadow = *aPageBottomRightShadowObj.get();
6049 0 : static BitmapEx& aPageBottomLeftShadow = *aPageBottomLeftShadowObj.get();
6050 0 : static BitmapEx& aPageBottomShadow = *aPageBottomShadowBaseObj.get();
6051 0 : static BitmapEx& aPageRightShadow = *aPageRightShadowBaseObj.get();
6052 0 : static BitmapEx& aPageTopShadow = *aPageTopShadowBaseObj.get();
6053 0 : static BitmapEx& aPageTopLeftShadow = *aPageTopLeftShadowObj.get();
6054 0 : static BitmapEx& aPageLeftShadow = *aPageLeftShadowBaseObj.get();
6055 0 : static Color aShadowColor( COL_AUTO );
6056 :
6057 0 : SwRect aAlignedPageRect( _rPageRect );
6058 0 : ::SwAlignRect( aAlignedPageRect, _pViewShell );
6059 0 : SwRect aPagePxRect = _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
6060 :
6061 0 : if (aShadowColor != SwViewOption::GetShadowColor())
6062 : {
6063 0 : aShadowColor = SwViewOption::GetShadowColor();
6064 :
6065 0 : AlphaMask aMask( shadowMask.getBottomRight().GetBitmap() );
6066 0 : Bitmap aFilledSquare( aMask.GetSizePixel(), 24 );
6067 0 : aFilledSquare.Erase( aShadowColor );
6068 0 : aPageBottomRightShadow = BitmapEx( aFilledSquare, aMask );
6069 :
6070 0 : aMask = AlphaMask( shadowMask.getBottomLeft().GetBitmap() );
6071 0 : aFilledSquare = Bitmap( aMask.GetSizePixel(), 24 );
6072 0 : aFilledSquare.Erase( aShadowColor );
6073 0 : aPageBottomLeftShadow = BitmapEx( aFilledSquare, aMask );
6074 :
6075 0 : aMask = AlphaMask( shadowMask.getBottom().GetBitmap() );
6076 0 : aFilledSquare = Bitmap( aMask.GetSizePixel(), 24 );
6077 0 : aFilledSquare.Erase( aShadowColor );
6078 0 : aPageBottomShadow = BitmapEx( aFilledSquare, aMask );
6079 :
6080 0 : aMask = AlphaMask( shadowMask.getTop().GetBitmap() );
6081 0 : aFilledSquare = Bitmap( aMask.GetSizePixel(), 24 );
6082 0 : aFilledSquare.Erase( aShadowColor );
6083 0 : aPageTopShadow = BitmapEx( aFilledSquare, aMask );
6084 :
6085 0 : aMask = AlphaMask( shadowMask.getTopRight().GetBitmap() );
6086 0 : aFilledSquare = Bitmap( aMask.GetSizePixel(), 24 );
6087 0 : aFilledSquare.Erase( aShadowColor );
6088 0 : aPageTopRightShadow = BitmapEx( aFilledSquare, aMask );
6089 :
6090 0 : aMask = AlphaMask( shadowMask.getRight().GetBitmap() );
6091 0 : aFilledSquare = Bitmap( aMask.GetSizePixel(), 24 );
6092 0 : aFilledSquare.Erase( aShadowColor );
6093 0 : aPageRightShadow = BitmapEx( aFilledSquare, aMask );
6094 :
6095 0 : aMask = AlphaMask( shadowMask.getTopLeft().GetBitmap() );
6096 0 : aFilledSquare = Bitmap( aMask.GetSizePixel(), 24 );
6097 0 : aFilledSquare.Erase( aShadowColor );
6098 0 : aPageTopLeftShadow = BitmapEx( aFilledSquare, aMask );
6099 :
6100 0 : aMask = AlphaMask( shadowMask.getLeft().GetBitmap() );
6101 0 : aFilledSquare = Bitmap( aMask.GetSizePixel(), 24 );
6102 0 : aFilledSquare.Erase( aShadowColor );
6103 0 : aPageLeftShadow = BitmapEx( aFilledSquare, aMask );
6104 : }
6105 :
6106 0 : SwRect aPaintRect;
6107 0 : OutputDevice *pOut = _pViewShell->GetOut();
6108 :
6109 0 : SwPageFrm::GetHorizontalShadowRect( _rPageRect, _pViewShell, aPaintRect, bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
6110 :
6111 : // Right shadow & corners
6112 0 : if ( bPaintRightShadow )
6113 : {
6114 0 : pOut->DrawBitmapEx( pOut->PixelToLogic( Point( aPaintRect.Right(), aPagePxRect.Bottom() + 1 - (aPageBottomRightShadow.GetSizePixel().Height() - mnShadowPxWidth) ) ),
6115 0 : aPageBottomRightShadow );
6116 0 : pOut->DrawBitmapEx( pOut->PixelToLogic( Point( aPaintRect.Right(), aPagePxRect.Top() - mnShadowPxWidth ) ),
6117 0 : aPageTopRightShadow );
6118 :
6119 0 : if (aPagePxRect.Height() > 2 * mnShadowPxWidth)
6120 : {
6121 0 : const long nWidth = aPageRightShadow.GetSizePixel().Width();
6122 0 : const long nHeight = aPagePxRect.Height() - 2 * (mnShadowPxWidth - 1);
6123 0 : if (aPageRightShadow.GetSizePixel().Height() < nHeight)
6124 0 : aPageRightShadow.Scale(Size(nWidth, nHeight), BMP_SCALE_FAST);
6125 :
6126 : lcl_paintBitmapExToRect(pOut,
6127 0 : Point(aPaintRect.Right() + mnShadowPxWidth, aPagePxRect.Top() + mnShadowPxWidth - 1),
6128 : Size(nWidth, nHeight),
6129 0 : aPageRightShadow, RIGHT);
6130 : }
6131 : }
6132 :
6133 : // Left shadows and corners
6134 0 : if(bPaintLeftShadow)
6135 : {
6136 0 : const long lLeft = aPaintRect.Left() - aPageBottomLeftShadow.GetSizePixel().Width();
6137 : pOut->DrawBitmapEx( pOut->PixelToLogic( Point( lLeft,
6138 0 : aPagePxRect.Bottom() + 1 + mnShadowPxWidth - aPageBottomLeftShadow.GetSizePixel().Height() ) ), aPageBottomLeftShadow );
6139 0 : pOut->DrawBitmapEx( pOut->PixelToLogic( Point( lLeft, aPagePxRect.Top() - mnShadowPxWidth ) ), aPageTopLeftShadow );
6140 0 : if (aPagePxRect.Height() > 2 * mnShadowPxWidth)
6141 : {
6142 0 : const long nWidth = aPageLeftShadow.GetSizePixel().Width();
6143 0 : const long nHeight = aPagePxRect.Height() - 2 * (mnShadowPxWidth - 1);
6144 0 : if (aPageLeftShadow.GetSizePixel().Height() < nHeight)
6145 0 : aPageLeftShadow.Scale(Size(nWidth, nHeight), BMP_SCALE_FAST);
6146 :
6147 : lcl_paintBitmapExToRect(pOut,
6148 0 : Point(lLeft, aPagePxRect.Top() + mnShadowPxWidth - 1),
6149 : Size(nWidth, nHeight),
6150 0 : aPageLeftShadow, LEFT);
6151 : }
6152 : }
6153 :
6154 : // Bottom shadow
6155 0 : const long nBottomHeight = aPageBottomShadow.GetSizePixel().Height();
6156 0 : if (aPageBottomShadow.GetSizePixel().Width() < aPaintRect.Width())
6157 0 : aPageBottomShadow.Scale(Size(aPaintRect.Width(), nBottomHeight), BMP_SCALE_FAST);
6158 :
6159 : lcl_paintBitmapExToRect(pOut,
6160 0 : Point(aPaintRect.Left(), aPagePxRect.Bottom() + 2),
6161 : Size(aPaintRect.Width(), nBottomHeight),
6162 0 : aPageBottomShadow, BOTTOM);
6163 :
6164 : // Top shadow
6165 0 : const long nTopHeight = aPageTopShadow.GetSizePixel().Height();
6166 0 : if (aPageTopShadow.GetSizePixel().Width() < aPaintRect.Width())
6167 0 : aPageTopShadow.Scale(Size(aPaintRect.Width(), nTopHeight), BMP_SCALE_FAST);
6168 :
6169 : lcl_paintBitmapExToRect(pOut,
6170 0 : Point(aPaintRect.Left(), aPagePxRect.Top() - mnShadowPxWidth),
6171 : Size(aPaintRect.Width(), nTopHeight),
6172 0 : aPageTopShadow, TOP);
6173 : }
6174 :
6175 : //mod #i6193# paint sidebar for notes
6176 : //IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit
6177 0 : /*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, SwViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight)
6178 : {
6179 : //TODO: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons
6180 0 : if (!_pViewShell )
6181 0 : return;
6182 :
6183 0 : SwRect aPageRect( _rPageRect );
6184 0 : SwAlignRect( aPageRect, _pViewShell );
6185 :
6186 0 : const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
6187 0 : if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) // do not show anything in print preview
6188 : {
6189 0 : sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight();
6190 0 : const Rectangle &aVisRect = _pViewShell->VisArea().SVRect();
6191 : //draw border and sidepane
6192 0 : _pViewShell->GetOut()->SetLineColor();
6193 0 : if (!bRight)
6194 : {
6195 0 : _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
6196 0 : _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()))) ;
6197 0 : if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6198 0 : _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6199 : else
6200 0 : _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
6201 0 : _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()))) ;
6202 : }
6203 : else
6204 : {
6205 0 : _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
6206 0 : SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()));
6207 0 : _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect());
6208 0 : if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6209 0 : _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6210 : else
6211 0 : _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
6212 0 : SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()));
6213 0 : _pViewShell->GetOut()->DrawRect(aSidebar.SVRect());
6214 : }
6215 0 : if (pMgr->ShowScrollbar(nPageNum))
6216 : {
6217 : // draw scrollbar area and arrows
6218 0 : Point aPointBottom;
6219 0 : Point aPointTop;
6220 0 : 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()) :
6221 0 : Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height());
6222 0 : aPointTop = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) :
6223 0 : Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height());
6224 0 : Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ;
6225 0 : Rectangle aRectBottom(aPointBottom,aSize);
6226 0 : Rectangle aRectTop(aPointTop,aSize);
6227 :
6228 0 : if (aRectBottom.IsOver(aVisRect))
6229 : {
6230 :
6231 0 : if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6232 : {
6233 0 : _pViewShell->GetOut()->SetLineColor(COL_WHITE);
6234 0 : _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6235 : }
6236 : else
6237 : {
6238 0 : _pViewShell->GetOut()->SetLineColor(COL_BLACK);
6239 0 : _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
6240 : }
6241 0 : _pViewShell->GetOut()->DrawRect(aRectBottom);
6242 0 : _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
6243 :
6244 0 : _pViewShell->GetOut()->SetLineColor();
6245 0 : Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6246 0 : Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6247 0 : PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
6248 : }
6249 0 : if (aRectTop.IsOver(aVisRect))
6250 : {
6251 0 : if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6252 : {
6253 0 : _pViewShell->GetOut()->SetLineColor(COL_WHITE);
6254 0 : _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6255 : }
6256 : else
6257 : {
6258 0 : _pViewShell->GetOut()->SetLineColor(COL_BLACK);
6259 0 : _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
6260 : }
6261 0 : _pViewShell->GetOut()->DrawRect(aRectTop);
6262 0 : _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
6263 :
6264 0 : _pViewShell->GetOut()->SetLineColor();
6265 0 : Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6266 0 : Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6267 0 : PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
6268 : }
6269 : }
6270 : }
6271 : }
6272 :
6273 0 : /*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, SwViewShell* _pViewShell, const Color aColorUp, const Color aColorDown)
6274 : {
6275 0 : Polygon aTriangleUp(3);
6276 0 : Polygon aTriangleDown(3);
6277 :
6278 0 : aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
6279 0 : aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1);
6280 0 : aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
6281 :
6282 0 : aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
6283 0 : aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1);
6284 0 : aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
6285 :
6286 0 : _pViewShell->GetOut()->SetFillColor(aColorUp);
6287 0 : _pViewShell->GetOut()->DrawPolygon(aTriangleUp);
6288 0 : _pViewShell->GetOut()->SetFillColor(aColorDown);
6289 0 : _pViewShell->GetOut()->DrawPolygon(aTriangleDown);
6290 0 : }
6291 :
6292 : /** get bound rectangle of border and shadow for repaints
6293 :
6294 : OD 12.02.2003 for #i9719# and #105645#
6295 :
6296 : author OD
6297 : */
6298 0 : /*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect,
6299 : const SwViewShell* _pViewShell,
6300 : SwRect& _orBorderAndShadowBoundRect,
6301 : bool bLeftShadow,
6302 : bool bRightShadow,
6303 : bool bRightSidebar
6304 : )
6305 : {
6306 0 : SwRect aAlignedPageRect( _rPageRect );
6307 0 : ::SwAlignRect( aAlignedPageRect, _pViewShell );
6308 : SwRect aPagePxRect =
6309 0 : _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
6310 0 : aPagePxRect.Bottom( aPagePxRect.Bottom() + mnShadowPxWidth + 1 );
6311 0 : aPagePxRect.Top( aPagePxRect.Top() - mnShadowPxWidth - 1 );
6312 :
6313 0 : SwRect aTmpRect;
6314 :
6315 : // Always ask for full shadow since we want a bounding rect
6316 : // including at least the page frame
6317 0 : SwPageFrm::GetHorizontalShadowRect( _rPageRect, _pViewShell, aTmpRect, false, false, bRightSidebar );
6318 :
6319 0 : if(bLeftShadow) aPagePxRect.Left( aTmpRect.Left() - mnShadowPxWidth - 1);
6320 0 : if(bRightShadow) aPagePxRect.Right( aTmpRect.Right() + mnShadowPxWidth + 1);
6321 :
6322 0 : _orBorderAndShadowBoundRect = _pViewShell->GetOut()->PixelToLogic( aPagePxRect.SVRect() );
6323 0 : }
6324 :
6325 0 : SwRect SwPageFrm::GetBoundRect() const
6326 : {
6327 0 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
6328 0 : SwRect aPageRect( Frm() );
6329 0 : SwRect aResult;
6330 :
6331 0 : if(!pSh) {
6332 0 : return SwRect( Point(0, 0), Size(0, 0) );
6333 : }
6334 :
6335 : SwPageFrm::GetBorderAndShadowBoundRect( aPageRect, pSh, aResult,
6336 0 : IsLeftShadowNeeded(), IsRightShadowNeeded(), SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT );
6337 0 : return aResult;
6338 : }
6339 :
6340 0 : /*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const SwViewShell* _pViewShell )
6341 : {
6342 0 : const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
6343 0 : const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
6344 0 : return nRet;
6345 : }
6346 :
6347 0 : void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage,
6348 : const sal_Bool bLowerBorder, const bool bOnlyTxtBackground ) const
6349 : {
6350 0 : if ( !pPage )
6351 0 : pPage = FindPageFrm();
6352 :
6353 0 : OutputDevice *pOut = pGlobalShell->GetOut();
6354 :
6355 : // #i16816# tagged pdf support
6356 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
6357 :
6358 : // OD 2004-04-23 #116347#
6359 0 : pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
6360 0 : pOut->SetLineColor();
6361 :
6362 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
6363 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
6364 :
6365 : // OD 20.11.2002 #104598# - take care of page margin area
6366 : // Note: code move from <SwFrm::PaintBackground(..)> to new method
6367 : // <SwPageFrm::Paintmargin(..)>.
6368 0 : if ( IsPageFrm() && !bOnlyTxtBackground)
6369 : {
6370 0 : static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell );
6371 : }
6372 :
6373 : // paint background
6374 : {
6375 0 : PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder, bOnlyTxtBackground );
6376 : }
6377 :
6378 : // OD 06.08.2002 #99657# - paint border before painting background
6379 : // paint grid for page frame and paint border
6380 0 : if (!bOnlyTxtBackground)
6381 : {
6382 0 : SwRect aRect( rRect );
6383 0 : if( IsPageFrm() )
6384 0 : ((SwPageFrm*)this)->PaintGrid( pOut, aRect );
6385 0 : PaintBorder( aRect, pPage, rAttrs );
6386 : }
6387 :
6388 0 : pOut->Pop();
6389 0 : }
6390 :
6391 : /// OD 05.09.2002 #102912#
6392 : /// Do not paint background for fly frames without a background brush by
6393 : /// calling <PaintBaBo> at the page or at the fly frame its anchored
6394 0 : void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
6395 : const SwBorderAttrs & rAttrs,
6396 : const sal_Bool bLowerMode,
6397 : const sal_Bool bLowerBorder,
6398 : const bool bOnlyTxtBackground ) const
6399 : {
6400 : // OD 20.01.2003 #i1837# - no paint of table background, if corresponding
6401 : // option is *not* set.
6402 0 : if( IsTabFrm() &&
6403 0 : !pGlobalShell->GetViewOptions()->IsTable() )
6404 : {
6405 0 : return;
6406 : }
6407 :
6408 : // nothing to do for covered table cells:
6409 0 : if( IsCellFrm() && IsCoveredCell() )
6410 0 : return;
6411 :
6412 0 : SwViewShell *pSh = pGlobalShell;
6413 :
6414 : // #i16816# tagged pdf support
6415 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
6416 :
6417 : const SvxBrushItem* pItem;
6418 : // OD 05.09.2002 #102912#
6419 : // temporary background brush for a fly frame without a background brush
6420 0 : SvxBrushItem* pTmpBackBrush = 0;
6421 : const Color* pCol;
6422 0 : SwRect aOrigBackRect;
6423 0 : const bool bPageFrm = IsPageFrm();
6424 0 : sal_Bool bLowMode = sal_True;
6425 :
6426 : //UUUU
6427 0 : FillAttributesPtr aFillAttributes;
6428 :
6429 0 : sal_Bool bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, bLowerMode );
6430 : //- Output if a separate background is used.
6431 0 : bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm();
6432 0 : if ( bNoFlyBackground )
6433 : {
6434 : // OD 05.09.2002 #102912# - Fly frame has no background.
6435 : // Try to find background brush at parents, if previous call of
6436 : // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode>
6437 0 : if ( bLowerMode )
6438 : {
6439 0 : bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, false );
6440 : }
6441 : // If still no background found for the fly frame, initialize the
6442 : // background brush <pItem> with global retouche color and set <bBack>
6443 : // to sal_True, that fly frame will paint its background using this color.
6444 0 : if ( !bBack )
6445 : {
6446 : // OD 10.01.2003 #i6467# - on print output, pdf output and
6447 : // in embedded mode not editing color COL_WHITE is used instead of
6448 : // the global retouche color.
6449 0 : if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
6450 0 : pSh->GetViewOptions()->IsPDFExport() ||
6451 0 : ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED &&
6452 0 : !pSh->GetDoc()->GetDocShell()->IsInPlaceActive()
6453 : )
6454 : )
6455 : {
6456 0 : pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND );
6457 :
6458 : //UUU
6459 0 : aFillAttributes.reset(new FillAttributes(Color( COL_WHITE )));
6460 : }
6461 : else
6462 : {
6463 0 : pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND);
6464 :
6465 : //UUU
6466 0 : aFillAttributes.reset(new FillAttributes(aGlobalRetoucheColor));
6467 : }
6468 :
6469 0 : pItem = pTmpBackBrush;
6470 0 : bBack = true;
6471 : }
6472 : }
6473 :
6474 0 : SwRect aPaintRect( Frm() );
6475 0 : if( IsTxtFrm() || IsSctFrm() )
6476 0 : aPaintRect = UnionFrm( sal_True );
6477 :
6478 0 : if ( aPaintRect.IsOver( rRect ) )
6479 : {
6480 0 : if ( bBack || bPageFrm || !bLowerMode )
6481 : {
6482 0 : const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode();
6483 0 : SwRect aRect;
6484 0 : if ( (bPageFrm && bBrowse) ||
6485 0 : (IsTxtFrm() && Prt().SSize() == Frm().SSize()) )
6486 : {
6487 0 : aRect = Frm();
6488 0 : ::SwAlignRect( aRect, pGlobalShell );
6489 : }
6490 : else
6491 : {
6492 0 : ::lcl_CalcBorderRect( aRect, this, rAttrs, false );
6493 0 : if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() )
6494 : {
6495 0 : if ( GetPrev()->GetAttrSet()->GetBackground() ==
6496 0 : GetAttrSet()->GetBackground() )
6497 : {
6498 0 : aRect.Top( Frm().Top() );
6499 : }
6500 : }
6501 : }
6502 0 : aRect.Intersection( rRect );
6503 :
6504 0 : OutputDevice *pOut = pSh->GetOut();
6505 :
6506 0 : if ( aRect.HasArea() )
6507 : {
6508 0 : SvxBrushItem* pNewItem = 0;
6509 : //SwRegionRects aRegion( aRect );
6510 :
6511 0 : if( pCol )
6512 : {
6513 0 : pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND );
6514 0 : pItem = pNewItem;
6515 :
6516 : //UUUU
6517 0 : aFillAttributes.reset(new FillAttributes(*pCol));
6518 : }
6519 :
6520 : //if ( pPage->GetSortedObjs() )
6521 : //{
6522 : // ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
6523 : //}
6524 :
6525 : // OD 06.08.2002 #99657# - determine, if background transparency
6526 : // have to be considered for drawing.
6527 : // --> Status Quo: background transparency have to be
6528 : // considered for fly frames
6529 0 : const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm();
6530 0 : bool bDone(false);
6531 :
6532 0 : if(pOut && aFillAttributes.get() && aFillAttributes->isUsed())
6533 : {
6534 0 : bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRect, *pOut);
6535 : }
6536 :
6537 0 : if(!bDone)
6538 : {
6539 : //for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
6540 : //{
6541 : // if ( 1 < aRegion.Count() )
6542 : // {
6543 : // ::SwAlignRect( aRegion[i], pGlobalShell );
6544 : // if( !aRegion[i].HasArea() )
6545 : // continue;
6546 : // }
6547 : // OD 06.08.2002 #99657# - add 6th parameter to indicate, if
6548 : // background transparency have to be considered
6549 : // Set missing 5th parameter to the default value GRFNUM_NO
6550 : // - see declaration in /core/inc/frmtool.hxx.
6551 0 : if (IsTxtFrm() || !bOnlyTxtBackground)
6552 : ::DrawGraphic(
6553 : pItem,
6554 : pOut,
6555 : aOrigBackRect,
6556 : aRect, // aRegion[i],
6557 : GRFNUM_NO,
6558 0 : bConsiderBackgroundTransparency );
6559 : //}
6560 : }
6561 0 : if( pCol )
6562 0 : delete pNewItem;
6563 0 : }
6564 : }
6565 : else
6566 0 : bLowMode = bLowerMode ? sal_True : sal_False;
6567 : }
6568 :
6569 : // OD 05.09.2002 #102912#
6570 : // delete temporary background brush.
6571 0 : delete pTmpBackBrush;
6572 :
6573 : //Now process lower and his neighbour.
6574 : //We end this as soon as a Frm leaves the chain and therefore is not a lower
6575 : //of me anymore
6576 0 : const SwFrm *pFrm = GetLower();
6577 0 : if ( pFrm )
6578 : {
6579 0 : SwRect aFrmRect;
6580 0 : SwRect aRect( PaintArea() );
6581 0 : aRect._Intersection( rRect );
6582 0 : SwRect aBorderRect( aRect );
6583 0 : SwShortCut aShortCut( *pFrm, aBorderRect );
6584 0 : do
6585 0 : { if ( pProgress )
6586 0 : pProgress->Reschedule();
6587 :
6588 0 : aFrmRect = pFrm->PaintArea();
6589 0 : if ( aFrmRect.IsOver( aBorderRect ) )
6590 : {
6591 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
6592 0 : const SwBorderAttrs &rTmpAttrs = *aAccess.Get();
6593 0 : if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) ||
6594 0 : aFrmRect.IsOver( aRect ) )
6595 : pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode,
6596 0 : bLowerBorder );
6597 0 : if ( bLowerBorder )
6598 0 : pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs );
6599 : }
6600 0 : pFrm = pFrm->GetNext();
6601 0 : } while ( pFrm && pFrm->GetUpper() == this &&
6602 0 : !aShortCut.Stop( aFrmRect ) );
6603 0 : }
6604 : }
6605 :
6606 : /// Refreshes all subsidiary lines of a page.
6607 0 : void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
6608 : {
6609 0 : if ( IS_SUBS || isTableBoundariesEnabled() || IS_SUBS_SECTION || IS_SUBS_FLYS )
6610 : {
6611 0 : SwRect aRect( rRect );
6612 0 : if ( aRect.HasArea() )
6613 : {
6614 : //During paint using the root, the array is controlled from there.
6615 : //Otherwise we'll handle it for our self.
6616 0 : bool bDelSubs = false;
6617 0 : if ( !pSubsLines )
6618 : {
6619 0 : pSubsLines = new SwSubsRects;
6620 : // OD 20.12.2002 #106318# - create container for special subsidiary lines
6621 0 : pSpecSubsLines = new SwSubsRects;
6622 0 : bDelSubs = true;
6623 : }
6624 :
6625 0 : RefreshLaySubsidiary( this, aRect );
6626 :
6627 0 : if ( bDelSubs )
6628 : {
6629 : // OD 20.12.2002 #106318# - paint special subsidiary lines
6630 : // and delete its container
6631 0 : pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL );
6632 0 : DELETEZ( pSpecSubsLines );
6633 :
6634 0 : pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines );
6635 0 : DELETEZ( pSubsLines );
6636 : }
6637 : }
6638 : }
6639 0 : }
6640 :
6641 0 : void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage,
6642 : const SwRect &rRect ) const
6643 : {
6644 0 : const sal_Bool bSubsOpt = IS_SUBS;
6645 0 : if ( bSubsOpt )
6646 0 : PaintSubsidiaryLines( pPage, rRect );
6647 :
6648 0 : const SwFrm *pLow = Lower();
6649 0 : if( !pLow )
6650 0 : return;
6651 0 : SwShortCut aShortCut( *pLow, rRect );
6652 0 : while( pLow && !aShortCut.Stop( pLow->Frm() ) )
6653 : {
6654 0 : if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() )
6655 : {
6656 0 : if ( pLow->IsLayoutFrm() )
6657 0 : ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect);
6658 0 : else if ( pLow->GetDrawObjs() )
6659 : {
6660 0 : const SwSortedObjs& rObjs = *(pLow->GetDrawObjs());
6661 0 : for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
6662 : {
6663 0 : const SwAnchoredObject* pAnchoredObj = rObjs[i];
6664 0 : if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
6665 0 : pAnchoredObj->GetDrawObj()->GetLayer() ) &&
6666 0 : pAnchoredObj->ISA(SwFlyFrm) )
6667 : {
6668 : const SwFlyFrm *pFly =
6669 0 : static_cast<const SwFlyFrm*>(pAnchoredObj);
6670 0 : if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) )
6671 : {
6672 0 : if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
6673 0 : !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
6674 0 : pFly->RefreshLaySubsidiary( pPage, rRect );
6675 : }
6676 : }
6677 : }
6678 : }
6679 : }
6680 0 : pLow = pLow->GetNext();
6681 : }
6682 : }
6683 :
6684 : /// Subsidiary lines to paint the PrtAreas.
6685 : /// Only the LayoutFrms which directly contain Cntnt.
6686 : /// Paints the desired line and pays attention to not overpaint any flys.
6687 : // OD 18.11.2002 #99672# - new parameter <_pSubsLines>
6688 0 : static void lcl_RefreshLine( const SwLayoutFrm *pLay,
6689 : const SwPageFrm *pPage,
6690 : const Point &rP1,
6691 : const Point &rP2,
6692 : const sal_uInt8 nSubColor,
6693 : SwLineRects* _pSubsLines )
6694 : {
6695 : //In which direction do we loop? Can only be horizontal or vertical.
6696 : OSL_ENSURE( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
6697 : "Sloped subsidiary lines are not allowed." );
6698 :
6699 0 : const bool bHori = rP1.Y() == rP2.Y();
6700 :
6701 : // use pointers to member function in order to unify flow
6702 : typedef long& (Point:: *pmfPt)();
6703 0 : const pmfPt pmfPtX = &Point::X;
6704 0 : const pmfPt pmfPtY = &Point::Y;
6705 0 : const pmfPt pDirPt = bHori ? pmfPtX : pmfPtY;
6706 :
6707 0 : Point aP1( rP1 );
6708 0 : Point aP2( rP2 );
6709 :
6710 0 : while ( (aP1.*pDirPt)() < (aP2.*pDirPt)() )
6711 : {
6712 : //If the starting point lies in a fly, it is directly set behind the
6713 : //fly.
6714 : //The end point moves to the start if the end point lies in a fly or we
6715 : //have a fly between starting point and end point.
6716 : // In this way, every position is output one by one.
6717 :
6718 : //If I'm a fly I'll only avoid those flys which are places 'above' me;
6719 : //this means those who are behind me in the array.
6720 : //Even if I'm inside a fly or inside a fly inside a fly a.s.o I won't
6721 : //avoid any of those flys.
6722 0 : SwOrderIter aIter( pPage );
6723 0 : const SwFlyFrm *pMyFly = pLay->FindFlyFrm();
6724 0 : if ( pMyFly )
6725 : {
6726 0 : aIter.Current( pMyFly->GetVirtDrawObj() );
6727 0 : while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) )
6728 : {
6729 0 : if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
6730 0 : aIter.Current( pMyFly->GetVirtDrawObj() );
6731 : }
6732 : }
6733 : else
6734 0 : aIter.Bottom();
6735 :
6736 0 : while ( aIter() )
6737 : {
6738 0 : const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
6739 0 : const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
6740 :
6741 : //I certainly won't avoid myself, even if I'm placed _inside_ the
6742 : //fly I won't avoid it.
6743 0 : if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
6744 : {
6745 0 : aIter.Next();
6746 0 : continue;
6747 : }
6748 :
6749 : // OD 19.12.2002 #106318# - do *not* consider fly frames with
6750 : // a transparent background.
6751 : // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which
6752 : // belongs to a invisible layer
6753 0 : if ( pFly->IsBackgroundTransparent() ||
6754 0 : !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) )
6755 : {
6756 0 : aIter.Next();
6757 0 : continue;
6758 : }
6759 :
6760 : //Is the Obj placed on the line
6761 0 : const long nP1OthPt = !bHori ? rP1.X() : rP1.Y();
6762 0 : const Rectangle &rBound = pObj->GetCurrentBoundRect();
6763 0 : const Point aDrPt( rBound.TopLeft() );
6764 0 : const long nDrOthPt = !bHori ? aDrPt.X() : aDrPt.Y();
6765 0 : const Size aDrSz( rBound.GetSize() );
6766 0 : const long nDrOthSz = !bHori ? aDrSz.Width() : aDrSz.Height();
6767 :
6768 0 : if ( nP1OthPt >= nDrOthPt && nP1OthPt <= nDrOthPt + nDrOthSz )
6769 : {
6770 0 : const long nDrDirPt = bHori ? aDrPt.X() : aDrPt.Y();
6771 0 : const long nDrDirSz = bHori ? aDrSz.Width() : aDrSz.Height();
6772 :
6773 0 : if ( (aP1.*pDirPt)() >= nDrDirPt && (aP1.*pDirPt)() <= nDrDirPt + nDrDirSz )
6774 0 : (aP1.*pDirPt)() = nDrDirPt + nDrDirSz;
6775 :
6776 0 : if ( (aP2.*pDirPt)() >= nDrDirPt && (aP1.*pDirPt)() < (nDrDirPt - 1) )
6777 0 : (aP2.*pDirPt)() = nDrDirPt - 1;
6778 : }
6779 0 : aIter.Next();
6780 : }
6781 :
6782 0 : if ( (aP1.*pDirPt)() < (aP2.*pDirPt)() )
6783 : {
6784 0 : SwRect aRect( aP1, aP2 );
6785 : // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of
6786 : // global variable <pSubsLines>.
6787 : _pSubsLines->AddLineRect( aRect, 0, table::BorderLineStyle::SOLID,
6788 0 : 0, nSubColor );
6789 : }
6790 0 : aP1 = aP2;
6791 0 : (aP1.*pDirPt)() += 1;
6792 0 : aP2 = rP2;
6793 : }
6794 0 : }
6795 :
6796 0 : static drawinglayer::primitive2d::Primitive2DSequence lcl_CreatePageAreaDelimiterPrimitives(
6797 : const SwRect& rRect )
6798 : {
6799 0 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 4 );
6800 :
6801 0 : basegfx::BColor aLineColor = SwViewOption::GetDocBoundariesColor().getBColor();
6802 0 : double nLineLength = 200.0; // in Twips
6803 :
6804 0 : Point aPoints[] = { rRect.TopLeft(), rRect.TopRight(), rRect.BottomRight(), rRect.BottomLeft() };
6805 0 : double aXOffDirs[] = { -1.0, 1.0, 1.0, -1.0 };
6806 0 : double aYOffDirs[] = { -1.0, -1.0, 1.0, 1.0 };
6807 :
6808 : // Actually loop over the corners to create the two lines
6809 0 : for ( int i = 0; i < 4; i++ )
6810 : {
6811 0 : basegfx::B2DVector aHorizVector( aXOffDirs[i], 0.0 );
6812 0 : basegfx::B2DVector aVertVector( 0.0, aYOffDirs[i] );
6813 :
6814 0 : basegfx::B2DPoint aBPoint( aPoints[i].getX(), aPoints[i].getY() );
6815 :
6816 0 : basegfx::B2DPolygon aPolygon;
6817 0 : aPolygon.append( aBPoint + aHorizVector * nLineLength );
6818 0 : aPolygon.append( aBPoint );
6819 0 : aPolygon.append( aBPoint + aVertVector * nLineLength );
6820 :
6821 : drawinglayer::primitive2d::PolygonHairlinePrimitive2D* pLine =
6822 : new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
6823 0 : aPolygon, aLineColor );
6824 0 : aSeq[i] = drawinglayer::primitive2d::Primitive2DReference( pLine );
6825 0 : }
6826 :
6827 0 : return aSeq;
6828 : }
6829 :
6830 0 : static drawinglayer::primitive2d::Primitive2DSequence lcl_CreateRectangleDelimiterPrimitives (
6831 : const SwRect& rRect )
6832 : {
6833 0 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 1 );
6834 0 : basegfx::BColor aLineColor = SwViewOption::GetDocBoundariesColor().getBColor();
6835 :
6836 0 : basegfx::B2DPolygon aPolygon;
6837 0 : aPolygon.append( basegfx::B2DPoint( rRect.Left(), rRect.Top() ) );
6838 0 : aPolygon.append( basegfx::B2DPoint( rRect.Right(), rRect.Top() ) );
6839 0 : aPolygon.append( basegfx::B2DPoint( rRect.Right(), rRect.Bottom() ) );
6840 0 : aPolygon.append( basegfx::B2DPoint( rRect.Left(), rRect.Bottom() ) );
6841 0 : aPolygon.setClosed( true );
6842 :
6843 : drawinglayer::primitive2d::PolygonHairlinePrimitive2D* pLine =
6844 : new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
6845 0 : aPolygon, aLineColor );
6846 0 : aSeq[0] = drawinglayer::primitive2d::Primitive2DReference( pLine );
6847 :
6848 0 : return aSeq;
6849 : }
6850 :
6851 0 : static drawinglayer::primitive2d::Primitive2DSequence lcl_CreateColumnAreaDelimiterPrimitives(
6852 : const SwRect& rRect )
6853 : {
6854 0 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 4 );
6855 :
6856 0 : basegfx::BColor aLineColor = SwViewOption::GetDocBoundariesColor().getBColor();
6857 0 : double nLineLength = 100.0; // in Twips
6858 :
6859 0 : Point aPoints[] = { rRect.TopLeft(), rRect.TopRight(), rRect.BottomRight(), rRect.BottomLeft() };
6860 0 : double aXOffDirs[] = { 1.0, -1.0, -1.0, 1.0 };
6861 0 : double aYOffDirs[] = { 1.0, 1.0, -1.0, -1.0 };
6862 :
6863 : // Actually loop over the corners to create the two lines
6864 0 : for ( int i = 0; i < 4; i++ )
6865 : {
6866 0 : basegfx::B2DVector aHorizVector( aXOffDirs[i], 0.0 );
6867 0 : basegfx::B2DVector aVertVector( 0.0, aYOffDirs[i] );
6868 :
6869 0 : basegfx::B2DPoint aBPoint( aPoints[i].getX(), aPoints[i].getY() );
6870 :
6871 0 : basegfx::B2DPolygon aPolygon;
6872 0 : aPolygon.append( aBPoint + aHorizVector * nLineLength );
6873 0 : aPolygon.append( aBPoint );
6874 0 : aPolygon.append( aBPoint + aVertVector * nLineLength );
6875 :
6876 : drawinglayer::primitive2d::PolygonHairlinePrimitive2D* pLine =
6877 : new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
6878 0 : aPolygon, aLineColor );
6879 0 : aSeq[i] = drawinglayer::primitive2d::Primitive2DReference( pLine );
6880 0 : }
6881 :
6882 0 : return aSeq;
6883 : }
6884 :
6885 0 : void SwPageFrm::PaintSubsidiaryLines( const SwPageFrm *,
6886 : const SwRect & ) const
6887 : {
6888 0 : if ( !pGlobalShell->IsHeaderFooterEdit() )
6889 : {
6890 0 : const SwFrm* pLay = Lower();
6891 0 : const SwFrm* pFtnCont = NULL;
6892 0 : const SwFrm* pPageBody = NULL;
6893 0 : while ( pLay && !( pFtnCont && pPageBody ) )
6894 : {
6895 0 : if ( pLay->IsFtnContFrm( ) )
6896 0 : pFtnCont = pLay;
6897 0 : if ( pLay->IsBodyFrm() )
6898 0 : pPageBody = pLay;
6899 0 : pLay = pLay->GetNext();
6900 : }
6901 :
6902 0 : SwRect aArea( pPageBody->Frm() );
6903 0 : if ( pFtnCont )
6904 0 : aArea.AddBottom( pFtnCont->Frm().Bottom() - aArea.Bottom() );
6905 :
6906 0 : if ( !pGlobalShell->GetViewOptions()->IsViewMetaChars( ) )
6907 0 : ProcessPrimitives( lcl_CreatePageAreaDelimiterPrimitives( aArea ) );
6908 : else
6909 0 : ProcessPrimitives( lcl_CreateRectangleDelimiterPrimitives( aArea ) );
6910 : }
6911 0 : }
6912 :
6913 0 : void SwColumnFrm::PaintSubsidiaryLines( const SwPageFrm *,
6914 : const SwRect & ) const
6915 : {
6916 0 : const SwFrm* pLay = Lower();
6917 0 : const SwFrm* pFtnCont = NULL;
6918 0 : const SwFrm* pColBody = NULL;
6919 0 : while ( pLay && !( pFtnCont && pColBody ) )
6920 : {
6921 0 : if ( pLay->IsFtnContFrm( ) )
6922 0 : pFtnCont = pLay;
6923 0 : if ( pLay->IsBodyFrm() )
6924 0 : pColBody = pLay;
6925 0 : pLay = pLay->GetNext();
6926 : }
6927 :
6928 0 : SwRect aArea( pColBody->Frm() );
6929 :
6930 : // #i3662# - enlarge top of column body frame's printing area
6931 : // in sections to top of section frame.
6932 0 : const bool bColInSection = GetUpper()->IsSctFrm();
6933 0 : if ( bColInSection )
6934 : {
6935 0 : if ( IsVertical() )
6936 0 : aArea.Right( GetUpper()->Frm().Right() );
6937 : else
6938 0 : aArea.Top( GetUpper()->Frm().Top() );
6939 : }
6940 :
6941 0 : if ( pFtnCont )
6942 0 : aArea.AddBottom( pFtnCont->Frm().Bottom() - aArea.Bottom() );
6943 :
6944 0 : ::SwAlignRect( aArea, pGlobalShell );
6945 :
6946 0 : if ( !pGlobalShell->GetViewOptions()->IsViewMetaChars( ) )
6947 0 : ProcessPrimitives( lcl_CreateColumnAreaDelimiterPrimitives( aArea ) );
6948 : else
6949 0 : ProcessPrimitives( lcl_CreateRectangleDelimiterPrimitives( aArea ) );
6950 0 : }
6951 :
6952 0 : void SwSectionFrm::PaintSubsidiaryLines( const SwPageFrm * pPage,
6953 : const SwRect & rRect ) const
6954 : {
6955 0 : const bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm();
6956 0 : if ( bNoLowerColumn )
6957 : {
6958 0 : SwLayoutFrm::PaintSubsidiaryLines( pPage, rRect );
6959 : }
6960 0 : }
6961 :
6962 : /** The SwBodyFrm doesn't print any subsidiary line: it's bounds are painted
6963 : either by the parent page or the parent column frame.
6964 : */
6965 0 : void SwBodyFrm::PaintSubsidiaryLines( const SwPageFrm *,
6966 : const SwRect & ) const
6967 : {
6968 0 : }
6969 :
6970 0 : void SwHeadFootFrm::PaintSubsidiaryLines( const SwPageFrm *, const SwRect & ) const
6971 : {
6972 0 : if ( pGlobalShell->IsHeaderFooterEdit() )
6973 : {
6974 0 : SwRect aArea( Prt() );
6975 0 : aArea.Pos() += Frm().Pos();
6976 0 : if ( !pGlobalShell->GetViewOptions()->IsViewMetaChars( ) )
6977 0 : ProcessPrimitives( lcl_CreatePageAreaDelimiterPrimitives( aArea ) );
6978 : else
6979 0 : ProcessPrimitives( lcl_CreateRectangleDelimiterPrimitives( aArea ) );
6980 : }
6981 0 : }
6982 :
6983 : /** This method is overridden in order to have no subsidiary lines
6984 : around the footnotes.
6985 : */
6986 0 : void SwFtnFrm::PaintSubsidiaryLines( const SwPageFrm *,
6987 : const SwRect & ) const
6988 : {
6989 0 : }
6990 :
6991 : /** This method is overridden in order to have no subsidiary lines
6992 : around the footnotes containers.
6993 : */
6994 0 : void SwFtnContFrm::PaintSubsidiaryLines( const SwPageFrm *,
6995 : const SwRect & ) const
6996 : {
6997 0 : }
6998 :
6999 0 : void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage,
7000 : const SwRect &rRect ) const
7001 : {
7002 0 : bool bNewTableModel = false;
7003 :
7004 : // #i29550#
7005 0 : if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
7006 : {
7007 0 : const SwTabFrm* pTabFrm = FindTabFrm();
7008 0 : if ( pTabFrm->IsCollapsingBorders() )
7009 0 : return;
7010 :
7011 0 : bNewTableModel = pTabFrm->GetTable()->IsNewModel();
7012 : // in the new table model, we have an early return for all cell-related
7013 : // frames, except from non-covered table cells
7014 0 : if ( bNewTableModel )
7015 0 : if ( IsTabFrm() ||
7016 0 : IsRowFrm() ||
7017 0 : ( IsCellFrm() && IsCoveredCell() ) )
7018 0 : return;
7019 : }
7020 :
7021 0 : const bool bFlys = pPage->GetSortedObjs() ? true : false;
7022 :
7023 0 : const bool bCell = IsCellFrm();
7024 : // use frame area for cells
7025 : // OD 13.02.2003 #i3662# - for section use also frame area
7026 0 : const bool bUseFrmArea = bCell || IsSctFrm();
7027 0 : SwRect aOriginal( bUseFrmArea ? Frm() : Prt() );
7028 0 : if ( !bUseFrmArea )
7029 0 : aOriginal.Pos() += Frm().Pos();
7030 :
7031 0 : ::SwAlignRect( aOriginal, pGlobalShell );
7032 :
7033 0 : if ( !aOriginal.IsOver( rRect ) )
7034 0 : return;
7035 :
7036 0 : SwRect aOut( aOriginal );
7037 0 : aOut._Intersection( rRect );
7038 :
7039 0 : const SwTwips nRight = aOut.Right();
7040 0 : const SwTwips nBottom= aOut.Bottom();
7041 :
7042 0 : const Point aRT( nRight, aOut.Top() );
7043 0 : const Point aRB( nRight, nBottom );
7044 0 : const Point aLB( aOut.Left(), nBottom );
7045 :
7046 0 : sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB :
7047 0 : ( IsInSct() ? SUBCOL_SECT :
7048 0 : ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
7049 :
7050 : // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section
7051 : // sub-lines in <pSpecSubsLine> array.
7052 0 : const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() ||
7053 0 : IsFtnFrm() || IsSctFrm();
7054 0 : SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines;
7055 :
7056 : // NOTE: for cell frames only left and right (horizontal layout) respectively
7057 : // top and bottom (vertical layout) lines painted.
7058 : // NOTE2: this does not hold for the new table model!!! We paint the top border
7059 : // of each non-covered table cell.
7060 0 : const bool bVert = IsVertical() ? true : false;
7061 0 : if ( bFlys )
7062 : {
7063 : // OD 14.11.2002 #104822# - add control for drawing left and right lines
7064 0 : if ( !bCell || bNewTableModel || !bVert )
7065 : {
7066 0 : if ( aOriginal.Left() == aOut.Left() )
7067 0 : ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor, pUsedSubsLines );
7068 : // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
7069 0 : if ( aOriginal.Right() == nRight )
7070 0 : ::lcl_RefreshLine( this, pPage, aRT, aRB, nSubColor, pUsedSubsLines );
7071 : }
7072 : // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
7073 0 : if ( !bCell || bNewTableModel || bVert )
7074 : {
7075 0 : if ( aOriginal.Top() == aOut.Top() )
7076 : // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
7077 0 : ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT, nSubColor, pUsedSubsLines );
7078 0 : if ( aOriginal.Bottom() == nBottom )
7079 : ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor,
7080 0 : pUsedSubsLines );
7081 : }
7082 : }
7083 : else
7084 : {
7085 : // OD 14.11.2002 #104822# - add control for drawing left and right lines
7086 0 : if ( !bCell || bNewTableModel || !bVert )
7087 : {
7088 0 : if ( aOriginal.Left() == aOut.Left() )
7089 : {
7090 0 : const SwRect aRect( aOut.Pos(), aLB );
7091 : pUsedSubsLines->AddLineRect( aRect, 0,
7092 0 : table::BorderLineStyle::SOLID, 0, nSubColor );
7093 : }
7094 : // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
7095 0 : if ( aOriginal.Right() == nRight )
7096 : {
7097 0 : const SwRect aRect( aRT, aRB );
7098 : pUsedSubsLines->AddLineRect( aRect, 0,
7099 0 : table::BorderLineStyle::SOLID, 0, nSubColor );
7100 : }
7101 : }
7102 : // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
7103 0 : if ( !bCell || bNewTableModel || bVert )
7104 : {
7105 0 : if ( aOriginal.Top() == aOut.Top() )
7106 : {
7107 : // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
7108 0 : const SwRect aRect( aOut.Pos(), aRT );
7109 : pUsedSubsLines->AddLineRect( aRect, 0,
7110 0 : table::BorderLineStyle::SOLID, 0, nSubColor );
7111 : }
7112 0 : if ( aOriginal.Bottom() == nBottom )
7113 : {
7114 0 : const SwRect aRect( aLB, aRB );
7115 : pUsedSubsLines->AddLineRect( aRect, 0,
7116 0 : table::BorderLineStyle::SOLID, 0, nSubColor );
7117 : }
7118 : }
7119 : }
7120 : }
7121 :
7122 : /// Refreshes all extra data (line breaks a.s.o) of the page. Basically only those objects
7123 : /// are considered which horizontally overlap the Rect.
7124 0 : void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const
7125 : {
7126 0 : const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
7127 0 : bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys())
7128 0 : || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE;
7129 :
7130 0 : SwRect aRect( rRect );
7131 0 : ::SwAlignRect( aRect, pGlobalShell );
7132 0 : if ( aRect.HasArea() )
7133 : {
7134 0 : SwLayoutFrm::RefreshExtraData( aRect );
7135 :
7136 0 : if ( bLineInFly && GetSortedObjs() )
7137 0 : for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i )
7138 : {
7139 0 : const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
7140 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
7141 : {
7142 0 : const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
7143 0 : if ( pFly->Frm().Top() <= aRect.Bottom() &&
7144 0 : pFly->Frm().Bottom() >= aRect.Top() )
7145 0 : pFly->RefreshExtraData( aRect );
7146 : }
7147 : }
7148 : }
7149 0 : }
7150 :
7151 0 : void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const
7152 : {
7153 :
7154 0 : const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
7155 0 : bool bLineInBody = rInfo.IsPaintLineNumbers(),
7156 0 : bLineInFly = bLineInBody && rInfo.IsCountInFlys(),
7157 0 : bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE;
7158 :
7159 0 : const SwCntntFrm *pCnt = ContainsCntnt();
7160 0 : while ( pCnt && IsAnLower( pCnt ) )
7161 : {
7162 0 : if ( pCnt->IsTxtFrm() && ( bRedLine ||
7163 0 : ( !pCnt->IsInTab() &&
7164 0 : ((bLineInBody && pCnt->IsInDocBody()) ||
7165 0 : (bLineInFly && pCnt->IsInFly())) ) ) &&
7166 0 : pCnt->Frm().Top() <= rRect.Bottom() &&
7167 0 : pCnt->Frm().Bottom() >= rRect.Top() )
7168 : {
7169 0 : ((SwTxtFrm*)pCnt)->PaintExtraData( rRect );
7170 : }
7171 0 : if ( bLineInFly && pCnt->GetDrawObjs() )
7172 0 : for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i )
7173 : {
7174 0 : const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i];
7175 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
7176 : {
7177 0 : const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
7178 0 : if ( pFly->IsFlyInCntFrm() &&
7179 0 : pFly->Frm().Top() <= rRect.Bottom() &&
7180 0 : pFly->Frm().Bottom() >= rRect.Top() )
7181 0 : pFly->RefreshExtraData( rRect );
7182 : }
7183 : }
7184 0 : pCnt = pCnt->GetNextCntntFrm();
7185 : }
7186 0 : }
7187 :
7188 : /** SwPageFrm::GetDrawBackgrdColor - for #102450#
7189 :
7190 : determine the color, that is respectively will be drawn as background
7191 : for the page frame.
7192 : Using existing method SwFrm::GetBackgroundBrush to determine the color
7193 : that is set at the page frame respectively is parent. If none is found
7194 : return the global retouche color
7195 :
7196 : @return Color
7197 : */
7198 0 : const Color& SwPageFrm::GetDrawBackgrdColor() const
7199 : {
7200 : const SvxBrushItem* pBrushItem;
7201 : const Color* pDummyColor;
7202 0 : SwRect aDummyRect;
7203 :
7204 : //UUUU
7205 0 : FillAttributesPtr aFillAttributes;
7206 :
7207 0 : if ( GetBackgroundBrush( aFillAttributes, pBrushItem, pDummyColor, aDummyRect, true) )
7208 : {
7209 0 : OUString referer;
7210 0 : SwViewShell * sh1 = getRootFrm()->GetCurrShell();
7211 0 : if (sh1 != 0) {
7212 0 : SfxObjectShell * sh2 = sh1->GetDoc()->GetPersist();
7213 0 : if (sh2 != 0 && sh2->HasName()) {
7214 0 : referer = sh2->GetMedium()->GetName();
7215 : }
7216 : }
7217 0 : const Graphic* pGraphic = pBrushItem->GetGraphic(referer);
7218 :
7219 0 : if(pGraphic)
7220 : {
7221 : // #i29105# when a graphic is set, it may be possible to calculate a single
7222 : // color which looks good in all places of the graphic. Since it is
7223 : // planned to have text edit on the overlay one day and the fallback
7224 : // to aGlobalRetoucheColor returns something useful, just use that
7225 : // for now.
7226 : }
7227 : else
7228 : {
7229 : // not a graphic, use (hopefully) initialized color
7230 0 : return pBrushItem->GetColor();
7231 0 : }
7232 : }
7233 :
7234 0 : return aGlobalRetoucheColor;
7235 : }
7236 :
7237 : /// create/return font used to paint the "empty page" string
7238 0 : const Font& SwPageFrm::GetEmptyPageFont()
7239 : {
7240 : static Font* pEmptyPgFont = 0;
7241 0 : if ( 0 == pEmptyPgFont )
7242 : {
7243 0 : pEmptyPgFont = new Font;
7244 0 : pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt
7245 0 : pEmptyPgFont->SetWeight( WEIGHT_BOLD );
7246 0 : pEmptyPgFont->SetStyleName( aEmptyOUStr );
7247 0 : pEmptyPgFont->SetName(OUString("Helvetica"));
7248 0 : pEmptyPgFont->SetFamily( FAMILY_SWISS );
7249 0 : pEmptyPgFont->SetTransparent( true );
7250 0 : pEmptyPgFont->SetColor( COL_GRAY );
7251 : }
7252 :
7253 0 : return *pEmptyPgFont;
7254 : }
7255 :
7256 : /** Retouch for a section.
7257 : |*
7258 : |* Retouch will only be done, if the Frm is the last one in his chain.
7259 : |* The whole area of the upper which is located below the Frm will be
7260 : |* cleared using PaintBackground.
7261 : |*/
7262 0 : void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const
7263 : {
7264 0 : if ( bFlyMetafile )
7265 0 : return;
7266 :
7267 : OSL_ENSURE( GetUpper(), "Retouche try without Upper." );
7268 : OSL_ENSURE( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche on a printer?" );
7269 :
7270 0 : SwRect aRetouche( GetUpper()->PaintArea() );
7271 0 : aRetouche.Top( Frm().Top() + Frm().Height() );
7272 0 : aRetouche.Intersection( pGlobalShell->VisArea() );
7273 :
7274 0 : if ( aRetouche.HasArea() )
7275 : {
7276 : //Omit the passed Rect. To do this, we unfortunately need a region to
7277 : //cut out.
7278 0 : SwRegionRects aRegion( aRetouche );
7279 0 : aRegion -= rRect;
7280 0 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
7281 :
7282 : // #i16816# tagged pdf support
7283 0 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
7284 :
7285 0 : for ( sal_uInt16 i = 0; i < aRegion.size(); ++i )
7286 : {
7287 0 : SwRect &rRetouche = aRegion[i];
7288 :
7289 0 : GetUpper()->PaintBaBo( rRetouche, pPage, sal_True );
7290 :
7291 : //Hell and Heaven need to be refreshed too.
7292 : //To avoid recursion my retouch flag needs to be reset first!
7293 0 : ResetRetouche();
7294 0 : SwRect aRetouchePart( rRetouche );
7295 0 : if ( aRetouchePart.HasArea() )
7296 : {
7297 0 : const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
7298 0 : const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
7299 : // --> OD #i76669#
7300 0 : SwViewObjectContactRedirector aSwRedirector( *pSh );
7301 : // <--
7302 :
7303 0 : pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0,
7304 : aRetouchePart, &aPageBackgrdColor,
7305 : (pPage->IsRightToLeft() ? true : false),
7306 0 : &aSwRedirector );
7307 0 : pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0,
7308 : aRetouchePart, &aPageBackgrdColor,
7309 : (pPage->IsRightToLeft() ? true : false),
7310 0 : &aSwRedirector );
7311 : }
7312 :
7313 0 : SetRetouche();
7314 :
7315 : //Because we leave all paint areas, we need to refresh the
7316 : //subsidiary lines.
7317 0 : pPage->RefreshSubsidiary( aRetouchePart );
7318 0 : }
7319 : }
7320 0 : if ( SwViewShell::IsLstEndAction() )
7321 0 : ResetRetouche();
7322 : }
7323 :
7324 : /** SwFrm::GetBackgroundBrush
7325 :
7326 : @descr
7327 : determine the background brush for the frame:
7328 : the background brush is taken from it-self or from its parent (anchor/upper).
7329 : Normally, the background brush is taken, which has no transparent color or
7330 : which has a background graphic. But there are some special cases:
7331 : (1) No background brush is taken from a page frame, if view option "IsPageBack"
7332 : isn't set.
7333 : (2) Background brush from a index section is taken under special conditions.
7334 : In this case parameter <rpCol> is set to the index shading color.
7335 : (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing
7336 : of the frame transparency is considered and its color is not "no fill"/"auto fill"
7337 : ---- old description in german:
7338 : Description Returns the Backgroundbrush for the area of the Frm.
7339 : The Brush is defined by the Frm or by an upper, the first Brush is
7340 : used. If no Brush is defined for a Frm, sal_False is returned.
7341 :
7342 : @param rpBrush
7343 : output parameter - constant reference pointer the found background brush
7344 :
7345 : @param rpFillStyle
7346 : output parameter - constant reference pointer the found background fill style
7347 :
7348 : @param rpFillGradient
7349 : output parameter - constant reference pointer the found background fill gradient
7350 :
7351 : @param rpCol
7352 : output parameter - constant reference pointer to the color of the index shading
7353 : set under special conditions, if background brush is taken from an index section.
7354 :
7355 : @param rOrigRect
7356 : in-/output parameter - reference to the retangle the background brush is
7357 : considered for - adjusted to the frame, from which the background brush is
7358 : taken.
7359 :
7360 : @parem bLowerMode
7361 : input parameter - boolean indicating, if background brush should *not* be
7362 : taken from parent.
7363 :
7364 : @return true, if a background brush for the frame is found
7365 : */
7366 0 : sal_Bool SwFrm::GetBackgroundBrush(
7367 : FillAttributesPtr& rFillAttributes,
7368 : const SvxBrushItem* & rpBrush,
7369 : const Color*& rpCol,
7370 : SwRect &rOrigRect,
7371 : sal_Bool bLowerMode ) const
7372 : {
7373 0 : const SwFrm *pFrm = this;
7374 0 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
7375 0 : const SwViewOption *pOpt = pSh->GetViewOptions();
7376 0 : rpBrush = 0;
7377 0 : rpCol = NULL;
7378 0 : do
7379 0 : { if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() )
7380 0 : return sal_False;
7381 :
7382 : //UUUU
7383 0 : const SwLayoutFrm* pSwLayoutFrm = dynamic_cast< const SwLayoutFrm* >(pFrm);
7384 :
7385 0 : if(pSwLayoutFrm)
7386 : {
7387 0 : const SwFrmFmt* pSwFrmFmt = dynamic_cast< const SwFrmFmt* >(pSwLayoutFrm->GetFmt());
7388 :
7389 0 : if(pSwFrmFmt && RES_FLYFRMFMT == pSwFrmFmt->Which())
7390 : {
7391 0 : rFillAttributes = pSwFrmFmt->getFillAttributes();
7392 : }
7393 : }
7394 :
7395 0 : const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
7396 :
7397 0 : if( pFrm->IsSctFrm() )
7398 : {
7399 0 : const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
7400 : // OD 20.08.2002 #99657# #GetTransChg#
7401 : // Note: If frame <pFrm> is a section of the index and
7402 : // it its background color is "no fill"/"auto fill" and
7403 : // it has no background graphic and
7404 : // we are not in the page preview and
7405 : // we are not in read-only mode and
7406 : // option "index shadings" is set and
7407 : // the output is not the printer
7408 : // then set <rpCol> to the color of the index shading
7409 0 : if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
7410 0 : TOX_CONTENT_SECTION == pSection->GetType() ) &&
7411 0 : (rBack.GetColor() == COL_TRANSPARENT) &&
7412 0 : rBack.GetGraphicPos() == GPOS_NONE &&
7413 0 : !pOpt->IsPagePreview() &&
7414 0 : !pOpt->IsReadonly() &&
7415 : // #114856# Formular view
7416 0 : !pOpt->IsFormView() &&
7417 0 : SwViewOption::IsIndexShadings() &&
7418 0 : !pOpt->IsPDFExport() &&
7419 0 : pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
7420 : {
7421 0 : rpCol = &SwViewOption::GetIndexShadingsColor();
7422 : }
7423 : }
7424 :
7425 : // OD 20.08.2002 #99657#
7426 : // determine, if background draw of frame <pFrm> considers transparency
7427 : // --> Status Quo: background transparency have to be
7428 : // considered for fly frames
7429 0 : const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm();
7430 : // OD 20.08.2002 #99657#
7431 : // add condition:
7432 : // If <bConsiderBackgroundTransparency> is set - see above -,
7433 : // return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill"
7434 0 : if (
7435 : // done when FillAttributesare set
7436 0 : (rFillAttributes.get() && rFillAttributes->isUsed()) ||
7437 :
7438 : // done when SvxBrushItem is used
7439 0 : !rBack.GetColor().GetTransparency() || rBack.GetGraphicPos() != GPOS_NONE ||
7440 :
7441 : // done when direct color is forced
7442 0 : rpCol ||
7443 :
7444 : // done when consider BG transparency and color is not completely transparent
7445 0 : (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT))
7446 : )
7447 : {
7448 0 : rpBrush = &rBack;
7449 0 : if ( pFrm->IsPageFrm() && pSh->GetViewOptions()->getBrowseMode() )
7450 : {
7451 0 : rOrigRect = pFrm->Frm();
7452 : }
7453 : else
7454 : {
7455 0 : if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() )
7456 : {
7457 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
7458 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
7459 0 : ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, false );
7460 : }
7461 : else
7462 : {
7463 0 : rOrigRect = pFrm->Prt();
7464 0 : rOrigRect += pFrm->Frm().Pos();
7465 : }
7466 : }
7467 :
7468 0 : return sal_True;
7469 : }
7470 :
7471 0 : if ( bLowerMode )
7472 : {
7473 : // Do not try to get background brush from parent (anchor/upper)
7474 0 : return sal_False;
7475 : }
7476 :
7477 : // get parent frame - anchor or upper - for next loop
7478 0 : if ( pFrm->IsFlyFrm() )
7479 : {
7480 : // OD 20.08.2002 - use "static_cast" instead of "old C-cast"
7481 0 : pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm();
7482 : }
7483 : else
7484 : {
7485 0 : pFrm = pFrm->GetUpper();
7486 : }
7487 : } while ( pFrm );
7488 :
7489 0 : return sal_False;
7490 : }
7491 :
7492 0 : void SetOutDevAndWin( SwViewShell *pSh, OutputDevice *pO,
7493 : Window *pW, sal_uInt16 nZoom )
7494 : {
7495 0 : pSh->mpOut = pO;
7496 0 : pSh->mpWin = pW;
7497 0 : pSh->mpOpt->SetZoom( nZoom );
7498 0 : }
7499 :
7500 0 : Graphic SwFrmFmt::MakeGraphic( ImageMap* )
7501 : {
7502 0 : return Graphic();
7503 : }
7504 :
7505 0 : Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap )
7506 : {
7507 0 : Graphic aRet;
7508 : //search any Fly!
7509 0 : SwIterator<SwFrm,SwFmt> aIter( *this );
7510 0 : SwFrm *pFirst = aIter.First();
7511 : SwViewShell *pSh;
7512 0 : if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) )
7513 : {
7514 0 : SwViewShell *pOldGlobal = pGlobalShell;
7515 0 : pGlobalShell = pSh;
7516 :
7517 0 : bool bNoteURL = pMap &&
7518 0 : SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, true );
7519 0 : if( bNoteURL )
7520 : {
7521 : OSL_ENSURE( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
7522 0 : pNoteURL = new SwNoteURL;
7523 : }
7524 0 : SwFlyFrm *pFly = (SwFlyFrm*)pFirst;
7525 :
7526 0 : OutputDevice *pOld = pSh->GetOut();
7527 0 : VirtualDevice aDev( *pOld );
7528 0 : aDev.EnableOutput( false );
7529 :
7530 0 : GDIMetaFile aMet;
7531 0 : MapMode aMap( pOld->GetMapMode().GetMapUnit() );
7532 0 : aDev.SetMapMode( aMap );
7533 0 : aMet.SetPrefMapMode( aMap );
7534 :
7535 0 : ::SwCalcPixStatics( pSh->GetOut() );
7536 0 : aMet.SetPrefSize( pFly->Frm().SSize() );
7537 :
7538 0 : aMet.Record( &aDev );
7539 0 : aDev.SetLineColor();
7540 0 : aDev.SetFillColor();
7541 0 : aDev.SetFont( pOld->GetFont() );
7542 :
7543 : //Enlarge the rectangle if needed, so the border is painted too.
7544 0 : SwRect aOut( pFly->Frm() );
7545 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
7546 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
7547 0 : if ( rAttrs.CalcRightLine() )
7548 0 : aOut.SSize().Width() += 2*nPixelSzW;
7549 0 : if ( rAttrs.CalcBottomLine() )
7550 0 : aOut.SSize().Height()+= 2*nPixelSzH;
7551 :
7552 : // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
7553 0 : const Region aRepaintRegion(aOut.SVRect());
7554 0 : pSh->DLPrePaint2(aRepaintRegion);
7555 :
7556 0 : Window *pWin = pSh->GetWin();
7557 0 : sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom();
7558 0 : ::SetOutDevAndWin( pSh, &aDev, 0, 100 );
7559 0 : bFlyMetafile = sal_True;
7560 0 : pFlyMetafileOut = pWin;
7561 :
7562 0 : SwViewImp *pImp = pSh->Imp();
7563 0 : pFlyOnlyDraw = pFly;
7564 0 : pLines = new SwLineRects;
7565 :
7566 : // OD 09.12.2002 #103045# - determine page, fly frame is on
7567 0 : const SwPageFrm* pFlyPage = pFly->FindPageFrm();
7568 0 : const Color aPageBackgrdColor = pFlyPage->GetDrawBackgrdColor();
7569 0 : const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
7570 : // --> OD #i76669#
7571 0 : SwViewObjectContactRedirector aSwRedirector( *pSh );
7572 : // <--
7573 0 : pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor,
7574 : (pFlyPage->IsRightToLeft() ? true : false),
7575 0 : &aSwRedirector );
7576 0 : pLines->PaintLines( &aDev );
7577 0 : if ( pFly->IsFlyInCntFrm() )
7578 0 : pFly->Paint( aOut );
7579 0 : pLines->PaintLines( &aDev );
7580 : // OD 30.08.2002 #102450# - add 3rd parameter
7581 0 : pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor,
7582 : (pFlyPage->IsRightToLeft() ? true : false),
7583 0 : &aSwRedirector );
7584 0 : pLines->PaintLines( &aDev );
7585 0 : DELETEZ( pLines );
7586 0 : pFlyOnlyDraw = 0;
7587 :
7588 0 : pFlyMetafileOut = 0;
7589 0 : bFlyMetafile = sal_False;
7590 0 : ::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
7591 :
7592 : // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted
7593 0 : pSh->DLPostPaint2(true);
7594 :
7595 0 : aMet.Stop();
7596 0 : aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() );
7597 0 : aRet = Graphic( aMet );
7598 :
7599 0 : if( bNoteURL )
7600 : {
7601 : OSL_ENSURE( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
7602 0 : pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap );
7603 0 : delete pNoteURL;
7604 0 : pNoteURL = NULL;
7605 : }
7606 0 : pGlobalShell = pOldGlobal;
7607 : }
7608 0 : return aRet;
7609 : }
7610 :
7611 0 : Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* )
7612 : {
7613 0 : Graphic aRet;
7614 0 : SdrModel *pMod = getIDocumentDrawModelAccess()->GetDrawModel();
7615 0 : if ( pMod )
7616 : {
7617 0 : SdrObject *pObj = FindSdrObject();
7618 0 : SdrView *pView = new SdrView( pMod );
7619 0 : SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0));
7620 0 : pView->MarkObj( pObj, pPgView );
7621 0 : aRet = pView->GetMarkedObjBitmapEx();
7622 0 : pView->HideSdrPage();
7623 0 : delete pView;
7624 : }
7625 0 : return aRet;
7626 0 : }
7627 :
7628 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|