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