Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / cppcanvas / source / mtfrenderer / polypolyaction.cxx
blobe5363a64982697cbb1c8ee7c6eb508b54a906da7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/rendering/XCanvas.hpp>
22 #include <com/sun/star/rendering/TexturingMode.hpp>
24 #include <sal/types.h>
25 #include <vcl/canvastools.hxx>
27 #include <basegfx/range/b2drectangle.hxx>
28 #include <basegfx/tools/canvastools.hxx>
29 #include <basegfx/polygon/b2dpolypolygon.hxx>
30 #include <basegfx/polygon/b2dpolypolygontools.hxx>
31 #include <basegfx/matrix/b2dhommatrix.hxx>
32 #include <canvas/canvastools.hxx>
34 #include "cachedprimitivebase.hxx"
35 #include "polypolyaction.hxx"
36 #include "outdevstate.hxx"
37 #include "mtftools.hxx"
40 using namespace ::com::sun::star;
42 namespace cppcanvas
44 namespace internal
46 namespace
48 class PolyPolyAction : public CachedPrimitiveBase
50 public:
51 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
52 const CanvasSharedPtr&,
53 const OutDevState&,
54 bool bFill,
55 bool bStroke );
56 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
57 const CanvasSharedPtr&,
58 const OutDevState&,
59 bool bFill,
60 bool bStroke,
61 int nTransparency );
63 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
64 const Subset& rSubset ) const override;
66 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
67 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
68 const Subset& rSubset ) const override;
70 virtual sal_Int32 getActionCount() const override;
72 private:
73 using Action::render;
74 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
75 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
77 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
78 const ::basegfx::B2DRange maBounds;
79 const CanvasSharedPtr mpCanvas;
81 // stroke color is now implicit: the maState.DeviceColor member
82 rendering::RenderState maState;
84 uno::Sequence< double > maFillColor;
87 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
88 const CanvasSharedPtr& rCanvas,
89 const OutDevState& rState,
90 bool bFill,
91 bool bStroke ) :
92 CachedPrimitiveBase( rCanvas, false ),
93 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
94 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
95 mpCanvas( rCanvas ),
96 maState(),
97 maFillColor()
99 tools::initRenderState(maState,rState);
101 if( bFill )
102 maFillColor = rState.fillColor;
104 if( bStroke )
105 maState.DeviceColor = rState.lineColor;
108 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
109 const CanvasSharedPtr& rCanvas,
110 const OutDevState& rState,
111 bool bFill,
112 bool bStroke,
113 int nTransparency ) :
114 CachedPrimitiveBase( rCanvas, false ),
115 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
116 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
117 mpCanvas( rCanvas ),
118 maState(),
119 maFillColor()
121 tools::initRenderState(maState,rState);
123 if( bFill )
125 maFillColor = rState.fillColor;
127 if( maFillColor.getLength() < 4 )
128 maFillColor.realloc( 4 );
130 // TODO(F1): Color management
131 // adapt fill color transparency
132 maFillColor[3] = 1.0 - nTransparency / 100.0;
135 if( bStroke )
137 maState.DeviceColor = rState.lineColor;
139 if( maState.DeviceColor.getLength() < 4 )
140 maState.DeviceColor.realloc( 4 );
142 // TODO(F1): Color management
143 // adapt fill color transparency
144 maState.DeviceColor[3] = 1.0 - nTransparency / 100.0;
148 bool PolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
149 const ::basegfx::B2DHomMatrix& rTransformation ) const
151 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
152 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
154 rendering::RenderState aLocalState( maState );
155 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
157 if( maFillColor.getLength() )
159 // TODO(E3): Use DBO's finalizer here,
160 // fillPolyPolygon() might throw
161 const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
162 aLocalState.DeviceColor = maFillColor;
164 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
165 mpCanvas->getViewState(),
166 aLocalState );
168 aLocalState.DeviceColor = aTmpColor;
171 if( aLocalState.DeviceColor.getLength() )
173 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
174 mpCanvas->getViewState(),
175 aLocalState );
178 return true;
181 bool PolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
182 const Subset& rSubset ) const
184 // TODO(F1): Split up poly-polygon into polygons, or even
185 // line segments, when subsets are requested.
187 // polygon only contains a single action, fail if subset
188 // requests different range
189 if( rSubset.mnSubsetBegin != 0 ||
190 rSubset.mnSubsetEnd != 1 )
191 return false;
193 return CachedPrimitiveBase::render( rTransformation );
196 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
198 rendering::RenderState aLocalState( maState );
199 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
201 return tools::calcDevicePixelBounds(
202 maBounds,
203 mpCanvas->getViewState(),
204 aLocalState );
207 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
208 const Subset& rSubset ) const
210 // TODO(F1): Split up poly-polygon into polygons, or even
211 // line segments, when subsets are requested.
213 // polygon only contains a single action, empty bounds
214 // if subset requests different range
215 if( rSubset.mnSubsetBegin != 0 ||
216 rSubset.mnSubsetEnd != 1 )
217 return ::basegfx::B2DRange();
219 return getBounds( rTransformation );
222 sal_Int32 PolyPolyAction::getActionCount() const
224 // TODO(F1): Split up poly-polygon into polygons, or even
225 // line segments, when subsets are requested.
226 return 1;
230 class TexturedPolyPolyAction : public CachedPrimitiveBase
232 public:
233 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
234 const CanvasSharedPtr& rCanvas,
235 const OutDevState& rState,
236 const rendering::Texture& rTexture );
238 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
239 const Subset& rSubset ) const override;
241 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
242 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
243 const Subset& rSubset ) const override;
245 virtual sal_Int32 getActionCount() const override;
247 private:
248 using Action::render;
249 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
250 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
252 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
253 const ::basegfx::B2DRectangle maBounds;
254 const CanvasSharedPtr mpCanvas;
256 // stroke color is now implicit: the maState.DeviceColor member
257 rendering::RenderState maState;
258 const rendering::Texture maTexture;
261 TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
262 const CanvasSharedPtr& rCanvas,
263 const OutDevState& rState,
264 const rendering::Texture& rTexture ) :
265 CachedPrimitiveBase( rCanvas, true ),
266 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
267 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
268 mpCanvas( rCanvas ),
269 maState(),
270 maTexture( rTexture )
272 tools::initRenderState(maState,rState);
275 bool TexturedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
276 const ::basegfx::B2DHomMatrix& rTransformation ) const
278 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
279 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
281 rendering::RenderState aLocalState( maState );
282 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
284 uno::Sequence< rendering::Texture > aSeq(1);
285 aSeq[0] = maTexture;
287 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
288 mpCanvas->getViewState(),
289 aLocalState,
290 aSeq );
291 return true;
294 bool TexturedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
295 const Subset& rSubset ) const
297 // TODO(F1): Split up poly-polygon into polygons, or even
298 // line segments, when subsets are requested.
300 // polygon only contains a single action, fail if subset
301 // requests different range
302 if( rSubset.mnSubsetBegin != 0 ||
303 rSubset.mnSubsetEnd != 1 )
304 return false;
306 return CachedPrimitiveBase::render( rTransformation );
309 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
311 rendering::RenderState aLocalState( maState );
312 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
314 return tools::calcDevicePixelBounds(
315 maBounds,
316 mpCanvas->getViewState(),
317 aLocalState );
320 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
321 const Subset& rSubset ) const
323 // TODO(F1): Split up poly-polygon into polygons, or even
324 // line segments, when subsets are requested.
326 // polygon only contains a single action, empty bounds
327 // if subset requests different range
328 if( rSubset.mnSubsetBegin != 0 ||
329 rSubset.mnSubsetEnd != 1 )
330 return ::basegfx::B2DRange();
332 return getBounds( rTransformation );
335 sal_Int32 TexturedPolyPolyAction::getActionCount() const
337 // TODO(F1): Split up poly-polygon into polygons, or even
338 // line segments, when subsets are requested.
339 return 1;
343 class StrokedPolyPolyAction : public CachedPrimitiveBase
345 public:
346 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
347 const CanvasSharedPtr& rCanvas,
348 const OutDevState& rState,
349 const rendering::StrokeAttributes& rStrokeAttributes );
351 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
352 const Subset& rSubset ) const override;
354 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
355 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
356 const Subset& rSubset ) const override;
358 virtual sal_Int32 getActionCount() const override;
360 private:
361 using Action::render;
362 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
363 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
365 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
366 const ::basegfx::B2DRectangle maBounds;
367 const CanvasSharedPtr mpCanvas;
368 rendering::RenderState maState;
369 const rendering::StrokeAttributes maStrokeAttributes;
372 StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
373 const CanvasSharedPtr& rCanvas,
374 const OutDevState& rState,
375 const rendering::StrokeAttributes& rStrokeAttributes ) :
376 CachedPrimitiveBase( rCanvas, false ),
377 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
378 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
379 mpCanvas( rCanvas ),
380 maState(),
381 maStrokeAttributes( rStrokeAttributes )
383 tools::initRenderState(maState,rState);
384 maState.DeviceColor = rState.lineColor;
387 bool StrokedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
388 const ::basegfx::B2DHomMatrix& rTransformation ) const
390 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
391 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
393 rendering::RenderState aLocalState( maState );
394 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
396 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
397 mpCanvas->getViewState(),
398 aLocalState,
399 maStrokeAttributes );
400 return true;
403 bool StrokedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
404 const Subset& rSubset ) const
406 // TODO(F1): Split up poly-polygon into polygons, or even
407 // line segments, when subsets are requested.
409 // polygon only contains a single action, fail if subset
410 // requests different range
411 if( rSubset.mnSubsetBegin != 0 ||
412 rSubset.mnSubsetEnd != 1 )
413 return false;
415 return CachedPrimitiveBase::render( rTransformation );
418 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
420 rendering::RenderState aLocalState( maState );
421 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
423 return tools::calcDevicePixelBounds(
424 maBounds,
425 mpCanvas->getViewState(),
426 aLocalState );
429 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
430 const Subset& rSubset ) const
432 // TODO(F1): Split up poly-polygon into polygons, or even
433 // line segments, when subsets are requested.
435 // polygon only contains a single action, empty bounds
436 // if subset requests different range
437 if( rSubset.mnSubsetBegin != 0 ||
438 rSubset.mnSubsetEnd != 1 )
439 return ::basegfx::B2DRange();
441 return getBounds( rTransformation );
444 sal_Int32 StrokedPolyPolyAction::getActionCount() const
446 // TODO(F1): Split up poly-polygon into polygons, or even
447 // line segments, when subsets are requested.
448 return 1;
452 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
453 const CanvasSharedPtr& rCanvas,
454 const OutDevState& rState )
456 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
457 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
458 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
459 rState.isFillColorSet,
460 rState.isLineColorSet ) );
463 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
464 const CanvasSharedPtr& rCanvas,
465 const OutDevState& rState,
466 const rendering::Texture& rTexture )
468 return ActionSharedPtr( new TexturedPolyPolyAction( rPoly, rCanvas, rState, rTexture ) );
471 ActionSharedPtr PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
472 const CanvasSharedPtr& rCanvas,
473 const OutDevState& rState )
475 OSL_ENSURE( rState.isLineColorSet,
476 "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
478 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
479 false,
480 rState.isLineColorSet ) );
483 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
484 const CanvasSharedPtr& rCanvas,
485 const OutDevState& rState,
486 const rendering::StrokeAttributes& rStrokeAttributes )
488 OSL_ENSURE( rState.isLineColorSet,
489 "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
490 return ActionSharedPtr( new StrokedPolyPolyAction( rPoly, rCanvas, rState, rStrokeAttributes ) );
493 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
494 const CanvasSharedPtr& rCanvas,
495 const OutDevState& rState,
496 int nTransparency )
498 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
499 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
500 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
501 rState.isFillColorSet,
502 rState.isLineColorSet,
503 nTransparency ) );
509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */