Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <drawinglayer/processor2d/vclpixelprocessor2d.hxx>
30 : : #include <vcl/outdev.hxx>
31 : : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
32 : : #include <drawinglayer/primitive2d/textprimitive2d.hxx>
33 : : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
34 : : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
35 : : #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
36 : : #include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
37 : : #include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
38 : : #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
39 : : #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
40 : : #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
41 : : #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
42 : : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
43 : : #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
44 : : #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
45 : : #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx>
46 : : #include <drawinglayer/primitive2d/controlprimitive2d.hxx>
47 : : #include <com/sun/star/awt/XWindow2.hpp>
48 : : #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
49 : : #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
50 : : #include <drawinglayer/primitive2d/chartprimitive2d.hxx>
51 : : #include <helperchartrenderer.hxx>
52 : : #include <helperwrongspellrenderer.hxx>
53 : : #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
54 : : #include <basegfx/polygon/b2dpolygontools.hxx>
55 : : #include <vcl/hatch.hxx>
56 : : #include <tools/diagnose_ex.h>
57 : : #include <com/sun/star/awt/PosSize.hpp>
58 : : #include <drawinglayer/primitive2d/invertprimitive2d.hxx>
59 : : #include <cstdio>
60 : : #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx>
61 : : #include <basegfx/matrix/b2dhommatrixtools.hxx>
62 : : #include <drawinglayer/primitive2d/epsprimitive2d.hxx>
63 : :
64 : : #include <toolkit/helper/vclunohelper.hxx>
65 : : #include <vcl/window.hxx>
66 : :
67 : : //////////////////////////////////////////////////////////////////////////////
68 : :
69 : : using namespace com::sun::star;
70 : :
71 : : //////////////////////////////////////////////////////////////////////////////
72 : :
73 : : namespace drawinglayer
74 : : {
75 : : namespace processor2d
76 : : {
77 : 46519 : VclPixelProcessor2D::VclPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation, OutputDevice& rOutDev)
78 : : : VclProcessor2D(rViewInformation, rOutDev),
79 [ + - ]: 46519 : maOriginalMapMode(rOutDev.GetMapMode())
80 : : {
81 : : // prepare maCurrentTransformation matrix with viewTransformation to target directly to pixels
82 [ + - ][ + - ]: 46519 : maCurrentTransformation = rViewInformation.getObjectToViewTransformation();
83 : :
84 : : // prepare output directly to pixels
85 [ + - ]: 46519 : mpOutputDevice->Push(PUSH_MAPMODE);
86 [ + - ]: 46519 : mpOutputDevice->SetMapMode();
87 : :
88 : : // react on AntiAliasing settings
89 [ + - ][ - + ]: 46519 : if(getOptionsDrawinglayer().IsAntiAliasing())
90 : : {
91 [ # # ]: 0 : mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW);
92 : : }
93 : : else
94 : : {
95 [ + - ]: 46519 : mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
96 : : }
97 : 46519 : }
98 : :
99 [ + - ]: 46519 : VclPixelProcessor2D::~VclPixelProcessor2D()
100 : : {
101 : : // restore MapMode
102 [ + - ]: 46519 : mpOutputDevice->Pop();
103 : :
104 : : // restore AntiAliasing
105 [ + - ]: 46519 : mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
106 [ - + ]: 93038 : }
107 : :
108 : 627323 : void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
109 : : {
110 [ - + + + : 627323 : switch(rCandidate.getPrimitive2DID())
+ - + + +
+ + + + +
+ + - - -
+ + - + +
- + - + ]
111 : : {
112 : : case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
113 : : {
114 : : // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose
115 : : static bool bHandleWrongSpellDirectly(true);
116 : :
117 [ # # ]: 0 : if(bHandleWrongSpellDirectly)
118 : : {
119 : 0 : const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate);
120 : :
121 [ # # ]: 0 : if(!renderWrongSpellPrimitive2D(
122 : : rWrongSpellPrimitive,
123 : : *mpOutputDevice,
124 : : maCurrentTransformation,
125 : 0 : maBColorModifierStack))
126 : : {
127 : : // fallback to decomposition (MetaFile)
128 [ # # ]: 0 : process(rWrongSpellPrimitive.get2DDecomposition(getViewInformation2D()));
129 : : }
130 : : }
131 : : else
132 : : {
133 [ # # ]: 0 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
134 : : }
135 : 0 : break;
136 : : }
137 : : case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
138 : : {
139 : : // directdraw of text simple portion; added test possibility to check text decompose
140 : : static bool bForceSimpleTextDecomposition(false);
141 : :
142 : : // Adapt evtl. used special DrawMode
143 : 13817 : const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
144 : 13817 : adaptTextToFillDrawMode();
145 : :
146 [ + - ][ + - ]: 13817 : if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect())
[ + - ]
147 : : {
148 : 13817 : RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate));
149 : : }
150 : : else
151 : : {
152 [ # # ]: 0 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
153 : : }
154 : :
155 : : // restore DrawMode
156 : 13817 : mpOutputDevice->SetDrawMode(nOriginalDrawMode);
157 : :
158 : 13817 : break;
159 : : }
160 : : case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D :
161 : : {
162 : : // directdraw of text simple portion; added test possibility to check text decompose
163 : : static bool bForceComplexTextDecomposition(false);
164 : :
165 : : // Adapt evtl. used special DrawMode
166 : 2357 : const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
167 : 2357 : adaptTextToFillDrawMode();
168 : :
169 [ + - ][ + - ]: 2357 : if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect())
[ + - ]
170 : : {
171 : 2357 : RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate));
172 : : }
173 : : else
174 : : {
175 [ # # ]: 0 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
176 : : }
177 : :
178 : : // restore DrawMode
179 : 2357 : mpOutputDevice->SetDrawMode(nOriginalDrawMode);
180 : :
181 : 2357 : break;
182 : : }
183 : : case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
184 : : {
185 : : // direct draw of hairline
186 : 136143 : RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), true);
187 : 136143 : break;
188 : : }
189 : : case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
190 : : {
191 : : // direct draw of transformed BitmapEx primitive
192 : 17532 : RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
193 : 17532 : break;
194 : : }
195 : : case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D :
196 : : {
197 : : // direct draw of transformed BitmapEx primitive
198 : 0 : RenderRenderGraphicPrimitive2D(static_cast< const primitive2d::RenderGraphicPrimitive2D& >(rCandidate));
199 : 0 : break;
200 : : }
201 : : case PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D :
202 : : {
203 : : // direct draw of fillBitmapPrimitive
204 : 313 : RenderFillBitmapPrimitive2D(static_cast< const primitive2d::FillBitmapPrimitive2D& >(rCandidate));
205 : 313 : break;
206 : : }
207 : : case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D :
208 : : {
209 : : // direct draw of gradient
210 : 235 : RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate));
211 : 235 : break;
212 : : }
213 : : case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D :
214 : : {
215 : : // direct draw of bitmap
216 : 313 : RenderPolyPolygonBitmapPrimitive2D(static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate));
217 : 313 : break;
218 : : }
219 : : case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
220 : : {
221 : : // direct draw of PolyPolygon with color
222 : 261939 : RenderPolyPolygonColorPrimitive2D(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate));
223 : 261939 : break;
224 : : }
225 : : case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
226 : : {
227 : : // #i98289#
228 [ - + ][ # # ]: 67 : const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete());
229 : 67 : const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing());
230 : :
231 [ - + ]: 67 : if(bForceLineSnap)
232 : : {
233 : 0 : mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE);
234 : : }
235 : :
236 : 67 : const primitive2d::MetafilePrimitive2D& rMetafilePrimitive( static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate) );
237 : :
238 : : static bool bTestMetaFilePrimitiveDecomposition( true );
239 [ + - ][ + - ]: 67 : if( bTestMetaFilePrimitiveDecomposition && !rMetafilePrimitive.getMetaFile().GetUseCanvas() )
[ + - ]
240 : : {
241 : : // use new Metafile decomposition
242 [ + - ]: 67 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
243 : : }
244 : : else
245 : : {
246 : : // direct draw of MetaFile
247 : 0 : RenderMetafilePrimitive2D( rMetafilePrimitive );
248 : : }
249 : :
250 [ - + ]: 67 : if(bForceLineSnap)
251 : : {
252 : 0 : mpOutputDevice->SetAntialiasing(nOldAntiAliase);
253 : : }
254 : :
255 : 67 : break;
256 : : }
257 : : case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
258 : : {
259 : : // mask group.
260 : 1026 : RenderMaskPrimitive2DPixel(static_cast< const primitive2d::MaskPrimitive2D& >(rCandidate));
261 : 1026 : break;
262 : : }
263 : : case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D :
264 : : {
265 : : // modified color group. Force output to unified color.
266 : 726 : RenderModifiedColorPrimitive2D(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate));
267 : 726 : break;
268 : : }
269 : : case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D :
270 : : {
271 : : // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case,
272 : : // use the faster OutputDevice::DrawTransparent method
273 : 249 : const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate);
274 [ + - ]: 249 : const primitive2d::Primitive2DSequence rContent = rUniTransparenceCandidate.getChildren();
275 : :
276 [ + - ]: 249 : if(rContent.hasElements())
277 : : {
278 [ - + ]: 249 : if(0.0 == rUniTransparenceCandidate.getTransparence())
279 : : {
280 : : // not transparent at all, use content
281 [ # # ]: 0 : process(rUniTransparenceCandidate.getChildren());
282 : : }
283 [ + - ][ + - ]: 249 : else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0)
[ + - ]
284 : : {
285 : 249 : bool bDrawTransparentUsed(false);
286 : :
287 : : // since DEV300 m33 DrawTransparent is supported in VCL (for some targets
288 : : // natively), so i am now enabling this shortcut
289 : : static bool bAllowUsingDrawTransparent(true);
290 : :
291 [ + - ][ + - ]: 249 : if(bAllowUsingDrawTransparent && 1 == rContent.getLength())
[ + - ]
292 : : {
293 : 249 : const primitive2d::Primitive2DReference xReference(rContent[0]);
294 [ - + ][ + - ]: 249 : const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get());
295 : :
296 [ + - ]: 249 : if(pBasePrimitive)
297 : : {
298 [ + - ][ - + ]: 249 : switch(pBasePrimitive->getPrimitive2DID())
299 : : {
300 : : case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D:
301 : : {
302 : : // single transparent PolyPolygon identified, use directly
303 : 0 : const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive);
304 : : OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)");
305 [ # # ]: 0 : const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor()));
306 [ # # ]: 0 : mpOutputDevice->SetFillColor(Color(aPolygonColor));
307 [ # # ]: 0 : mpOutputDevice->SetLineColor();
308 : :
309 [ # # ]: 0 : basegfx::B2DPolyPolygon aLocalPolyPolygon(pPoPoColor->getB2DPolyPolygon());
310 [ # # ]: 0 : aLocalPolyPolygon.transform(maCurrentTransformation);
311 : :
312 [ # # ]: 0 : mpOutputDevice->DrawTransparent(aLocalPolyPolygon, rUniTransparenceCandidate.getTransparence());
313 : 0 : bDrawTransparentUsed = true;
314 [ # # ]: 0 : break;
315 : : }
316 : : // #i# need to wait for #i101378# which is in CWS vcl112 to directly paint transparent hairlines
317 : : //case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D:
318 : : //{
319 : : // // single transparent PolygonHairlinePrimitive2D identified, use directly
320 : : // const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive);
321 : : // OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)");
322 : : // break;
323 : : //}
324 : : }
325 : 249 : }
326 : : }
327 : :
328 [ + - ]: 249 : if(!bDrawTransparentUsed)
329 : : {
330 : : // unified sub-transparence. Draw to VDev first.
331 [ + - ]: 249 : RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate);
332 : : }
333 : : }
334 : : }
335 : :
336 [ + - ]: 249 : break;
337 : : }
338 : : case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D :
339 : : {
340 : : // sub-transparence group. Draw to VDev first.
341 : 1638 : RenderTransparencePrimitive2D(static_cast< const primitive2d::TransparencePrimitive2D& >(rCandidate));
342 : 1638 : break;
343 : : }
344 : : case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D :
345 : : {
346 : : // transform group.
347 : 4356 : RenderTransformPrimitive2D(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate));
348 : 4356 : break;
349 : : }
350 : : case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D :
351 : : {
352 : : // new XDrawPage for ViewInformation2D
353 : 0 : RenderPagePreviewPrimitive2D(static_cast< const primitive2d::PagePreviewPrimitive2D& >(rCandidate));
354 : 0 : break;
355 : : }
356 : : case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
357 : : {
358 : : // marker array
359 : 0 : RenderMarkerArrayPrimitive2D(static_cast< const primitive2d::MarkerArrayPrimitive2D& >(rCandidate));
360 : 0 : break;
361 : : }
362 : : case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
363 : : {
364 : : // point array
365 : 0 : RenderPointArrayPrimitive2D(static_cast< const primitive2d::PointArrayPrimitive2D& >(rCandidate));
366 : 0 : break;
367 : : }
368 : : case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D :
369 : : {
370 : : // control primitive
371 : 6723 : const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate);
372 : 6723 : const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl());
373 : :
374 : : try
375 : : {
376 : : // remember old graphics and create new
377 [ + + ]: 6723 : uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW);
378 [ + - ][ + - ]: 4273 : const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics());
379 [ + - ]: 4273 : const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics());
380 : :
381 [ + - ]: 4273 : if(xNewGraphics.is())
382 : : {
383 : : // link graphics and view
384 [ + - ][ + - ]: 4273 : xControlView->setGraphics(xNewGraphics);
385 : :
386 : : // get position
387 [ + - ]: 4273 : const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation * rControlPrimitive.getTransform());
388 [ + - ]: 4273 : const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0));
389 : :
390 : : // find out if the control is already visualized as a VCL-ChildWindow. If yes,
391 : : // it does not need to be painted at all.
392 [ + - ]: 4273 : uno::Reference< awt::XWindow2 > xControlWindow(rXControl, uno::UNO_QUERY_THROW);
393 [ + - ][ + - ]: 4273 : const bool bControlIsVisibleAsChildWindow(rXControl->getPeer().is() && xControlWindow->isVisible());
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ # # ]
394 : :
395 [ + + ]: 4273 : if(!bControlIsVisibleAsChildWindow)
396 : : {
397 : : // draw it. Do not forget to use the evtl. offsetted origin of the target device,
398 : : // e.g. when used with mask/transparence buffer device
399 : 4143 : const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin());
400 [ + - ]: 4143 : xControlView->draw(
401 : 4143 : aOrigin.X() + basegfx::fround(aTopLeftPixel.getX()),
402 [ + - ]: 8286 : aOrigin.Y() + basegfx::fround(aTopLeftPixel.getY()));
403 : : }
404 : :
405 : : // restore original graphics
406 [ + - ][ + - ]: 4273 : xControlView->setGraphics(xOriginalGraphics);
[ + - ]
407 : 6723 : }
408 : : }
409 [ - + ]: 4900 : catch(const uno::Exception&)
410 : : {
411 : : // #i116763# removing since there is a good alternative when the xControlView
412 : : // is not found and it is allowed to happen
413 : : // DBG_UNHANDLED_EXCEPTION();
414 : :
415 : : // process recursively and use the decomposition as Bitmap
416 [ - + ][ - + ]: 2450 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
[ - + ]
417 : : }
418 : :
419 : 6723 : break;
420 : : }
421 : : case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
422 : : {
423 : : // the stroke primitive may be decomposed to filled polygons. To keep
424 : : // evtl. set DrawModes aka DRAWMODE_BLACKLINE, DRAWMODE_GRAYLINE,
425 : : // DRAWMODE_GHOSTEDLINE, DRAWMODE_WHITELINE or DRAWMODE_SETTINGSLINE
426 : : // working, these need to be copied to the corresponding fill modes
427 : 26097 : const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode());
428 : 26097 : adaptLineToFillDrawMode();
429 : :
430 : : // polygon stroke primitive
431 : : static bool bSuppressFatToHairlineCorrection(false);
432 : :
433 [ - + ]: 26097 : if(bSuppressFatToHairlineCorrection)
434 : : {
435 : : // remeber that we enter a PolygonStrokePrimitive2D decomposition,
436 : : // used for AA thick line drawing
437 : 0 : mnPolygonStrokePrimitive2D++;
438 : :
439 : : // with AA there is no need to handle thin lines special
440 [ # # ]: 0 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
441 : :
442 : : // leave PolygonStrokePrimitive2D
443 : 0 : mnPolygonStrokePrimitive2D--;
444 : : }
445 : : else
446 : : {
447 : : // Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation
448 : : // as filled polygons is geometrically corret but looks wrong since polygon filling avoids
449 : : // the right and bottom pixels. The used method evaluates that and takes the correct action,
450 : : // including calling recursively with decomposition if line is wide enough
451 : 26097 : const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);
452 : :
453 : 26097 : RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive);
454 : : }
455 : :
456 : : // restore DrawMode
457 : 26097 : mpOutputDevice->SetDrawMode(nOriginalDrawMode);
458 : :
459 : 26097 : break;
460 : : }
461 : : case PRIMITIVE2D_ID_CHARTPRIMITIVE2D :
462 : : {
463 : : // chart primitive in pixel renderer; restore original DrawMode during call
464 : : // since the evtl. used ChartPrettyPainter will use the MapMode
465 : 0 : const primitive2d::ChartPrimitive2D& rChartPrimitive = static_cast< const primitive2d::ChartPrimitive2D& >(rCandidate);
466 : 0 : mpOutputDevice->Push(PUSH_MAPMODE);
467 : 0 : mpOutputDevice->SetMapMode(maOriginalMapMode);
468 : :
469 [ # # ]: 0 : if(!renderChartPrimitive2D(
470 : : rChartPrimitive,
471 : : *mpOutputDevice,
472 : 0 : getViewInformation2D()))
473 : : {
474 : : // fallback to decomposition (MetaFile)
475 [ # # ]: 0 : process(rChartPrimitive.get2DDecomposition(getViewInformation2D()));
476 : : }
477 : :
478 : 0 : mpOutputDevice->Pop();
479 : 0 : break;
480 : : }
481 : : case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D :
482 : : {
483 : : static bool bForceIgnoreHatchSmoothing(false);
484 : :
485 [ + - ][ - + ]: 616 : if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing())
[ - + ]
486 : : {
487 : : // if AA is used (or ignore smoothing is on), there is no need to smooth
488 : : // hatch painting, use decomposition
489 [ # # ]: 0 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
490 : : }
491 : : else
492 : : {
493 : : // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel
494 : : // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother.
495 : : // This is wrong in principle, but looks nicer. This could also be done here directly
496 : : // without VCL usage if needed
497 : 616 : const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate);
498 : 616 : const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch();
499 : :
500 : : // create hatch polygon in range size and discrete coordinates
501 : 616 : basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getObjectRange());
502 [ + - ]: 616 : aHatchRange.transform(maCurrentTransformation);
503 [ + - ]: 616 : const basegfx::B2DPolygon aHatchPolygon(basegfx::tools::createPolygonFromRect(aHatchRange));
504 : :
505 [ + - ][ - + ]: 616 : if(rFillHatchAttributes.isFillBackground())
506 : : {
507 : : // #i111846# background fill is active; draw fill polygon
508 [ # # ]: 0 : const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
509 : :
510 [ # # ]: 0 : mpOutputDevice->SetFillColor(Color(aPolygonColor));
511 [ # # ]: 0 : mpOutputDevice->SetLineColor();
512 [ # # ]: 0 : mpOutputDevice->DrawPolygon(aHatchPolygon);
513 : : }
514 : :
515 : : // set hatch line color
516 [ + - ]: 616 : const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
517 [ + - ]: 616 : mpOutputDevice->SetFillColor();
518 [ + - ]: 616 : mpOutputDevice->SetLineColor(Color(aHatchColor));
519 : :
520 : : // get hatch style
521 : 616 : HatchStyle eHatchStyle(HATCH_SINGLE);
522 : :
523 [ + - ]: 616 : switch(rFillHatchAttributes.getStyle())
[ + - - ]
524 : : {
525 : : default : // HATCHSTYLE_SINGLE
526 : : {
527 : 616 : break;
528 : : }
529 : : case attribute::HATCHSTYLE_DOUBLE :
530 : : {
531 : 0 : eHatchStyle = HATCH_DOUBLE;
532 : 0 : break;
533 : : }
534 : : case attribute::HATCHSTYLE_TRIPLE :
535 : : {
536 : 0 : eHatchStyle = HATCH_TRIPLE;
537 : 0 : break;
538 : : }
539 : : }
540 : :
541 : : // create hatch
542 [ + - ][ + - ]: 616 : const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0));
543 [ + - ]: 616 : const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength()));
544 [ + - ]: 616 : const sal_uInt16 nAngle10((sal_uInt16)basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800));
545 [ + - ][ + - ]: 616 : ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10);
546 : :
547 : : // draw hatch using VCL
548 [ + - ][ + - ]: 616 : mpOutputDevice->DrawHatch(PolyPolygon(Polygon(aHatchPolygon)), aVCLHatch);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
549 : : }
550 : 616 : break;
551 : : }
552 : : case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D :
553 : : {
554 : : // #i98404# Handle directly, especially when AA is active
555 : 1854 : const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate);
556 : 1854 : const sal_uInt16 nOriginalAA(mpOutputDevice->GetAntialiasing());
557 : :
558 : : // switch AA off in all cases
559 [ + - ]: 1854 : mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
560 : :
561 : : // create color for fill
562 [ + - ]: 1854 : const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor()));
563 [ + - ]: 1854 : mpOutputDevice->SetFillColor(Color(aPolygonColor));
564 [ + - ]: 1854 : mpOutputDevice->SetLineColor();
565 : :
566 : : // create rectangle for fill
567 [ + - ]: 1854 : const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport());
568 : : const Rectangle aRectangle(
569 [ + - ][ + - ]: 1854 : (sal_Int32)floor(aViewport.getMinX()), (sal_Int32)floor(aViewport.getMinY()),
570 [ + - ][ + - ]: 3708 : (sal_Int32)ceil(aViewport.getMaxX()), (sal_Int32)ceil(aViewport.getMaxY()));
[ + - ]
571 [ + - ]: 1854 : mpOutputDevice->DrawRect(aRectangle);
572 : :
573 : : // restore AA setting
574 [ + - ]: 1854 : mpOutputDevice->SetAntialiasing(nOriginalAA);
575 : 1854 : break;
576 : : }
577 : : case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D :
578 : : {
579 : : // #i97628#
580 : : // This primitive means that the content is derived from an active text edit,
581 : : // not from model data itself. Some renderers need to suppress this content, e.g.
582 : : // the pixel renderer used for displaying the edit view (like this one). It's
583 : : // not to be suppressed by the MetaFile renderers, so that the edited text is
584 : : // part of the MetaFile, e.g. needed for presentation previews.
585 : : // Action: Ignore here, do nothing.
586 : 0 : break;
587 : : }
588 : : case PRIMITIVE2D_ID_INVERTPRIMITIVE2D :
589 : : {
590 : : // invert primitive (currently only used for HighContrast fallback for selection in SW and SC).
591 : : // Set OutDev to XOR and switch AA off (XOR does not work with AA)
592 : 2637 : mpOutputDevice->Push();
593 : 2637 : mpOutputDevice->SetRasterOp( ROP_XOR );
594 : 2637 : const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing());
595 : 2637 : mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW);
596 : :
597 : : // process content recursively
598 [ + - ]: 2637 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
599 : :
600 : : // restore OutDev
601 : 2637 : mpOutputDevice->Pop();
602 : 2637 : mpOutputDevice->SetAntialiasing(nAntiAliasing);
603 : 2637 : break;
604 : : }
605 : : case PRIMITIVE2D_ID_EPSPRIMITIVE2D :
606 : : {
607 : 0 : RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate));
608 : 0 : break;
609 : : }
610 : : default :
611 : : {
612 : : // process recursively
613 [ + - ]: 148685 : process(rCandidate.get2DDecomposition(getViewInformation2D()));
614 : 148685 : break;
615 : : }
616 : : }
617 : 627323 : }
618 : : } // end of namespace processor2d
619 : : } // end of namespace drawinglayer
620 : :
621 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|