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