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