bump product version to 6.3.0.0.beta1
[LibreOffice.git] / cppcanvas / source / mtfrenderer / polypolyaction.cxx
blobb2bf7e5ab81668190505d8d7ecc403048c9946b7
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/utils/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>
33 #include <sal/log.hxx>
35 #include "cachedprimitivebase.hxx"
36 #include "polypolyaction.hxx"
37 #include <outdevstate.hxx>
38 #include "mtftools.hxx"
41 using namespace ::com::sun::star;
43 namespace cppcanvas
45 namespace internal
47 namespace
49 class PolyPolyAction : public CachedPrimitiveBase
51 public:
52 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
53 const CanvasSharedPtr&,
54 const OutDevState&,
55 bool bFill,
56 bool bStroke );
57 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
58 const CanvasSharedPtr&,
59 const OutDevState&,
60 bool bFill,
61 bool bStroke,
62 int nTransparency );
64 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
65 const Subset& rSubset ) const override;
67 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
68 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
69 const Subset& rSubset ) const override;
71 virtual sal_Int32 getActionCount() const override;
73 private:
74 using Action::render;
75 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
76 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
78 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
79 const ::basegfx::B2DRange maBounds;
80 const CanvasSharedPtr mpCanvas;
82 // stroke color is now implicit: the maState.DeviceColor member
83 rendering::RenderState maState;
85 uno::Sequence< double > maFillColor;
88 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
89 const CanvasSharedPtr& rCanvas,
90 const OutDevState& rState,
91 bool bFill,
92 bool bStroke ) :
93 CachedPrimitiveBase( rCanvas, false ),
94 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
95 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
96 mpCanvas( rCanvas ),
97 maState(),
98 maFillColor()
100 tools::initRenderState(maState,rState);
102 if( bFill )
103 maFillColor = rState.fillColor;
105 if( bStroke )
106 maState.DeviceColor = rState.lineColor;
109 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
110 const CanvasSharedPtr& rCanvas,
111 const OutDevState& rState,
112 bool bFill,
113 bool bStroke,
114 int nTransparency ) :
115 CachedPrimitiveBase( rCanvas, false ),
116 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
117 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
118 mpCanvas( rCanvas ),
119 maState(),
120 maFillColor()
122 tools::initRenderState(maState,rState);
124 if( bFill )
126 maFillColor = rState.fillColor;
128 if( maFillColor.getLength() < 4 )
129 maFillColor.realloc( 4 );
131 // TODO(F1): Color management
132 // adapt fill color transparency
133 maFillColor[3] = 1.0 - nTransparency / 100.0;
136 if( bStroke )
138 maState.DeviceColor = rState.lineColor;
140 if( maState.DeviceColor.getLength() < 4 )
141 maState.DeviceColor.realloc( 4 );
143 // TODO(F1): Color management
144 // adapt fill color transparency
145 maState.DeviceColor[3] = 1.0 - nTransparency / 100.0;
149 bool PolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
150 const ::basegfx::B2DHomMatrix& rTransformation ) const
152 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
153 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
155 rendering::RenderState aLocalState( maState );
156 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
158 if( maFillColor.getLength() )
160 // TODO(E3): Use DBO's finalizer here,
161 // fillPolyPolygon() might throw
162 const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
163 aLocalState.DeviceColor = maFillColor;
165 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
166 mpCanvas->getViewState(),
167 aLocalState );
169 aLocalState.DeviceColor = aTmpColor;
172 if( aLocalState.DeviceColor.getLength() )
174 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
175 mpCanvas->getViewState(),
176 aLocalState );
179 return true;
182 bool PolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
183 const Subset& rSubset ) const
185 // TODO(F1): Split up poly-polygon into polygons, or even
186 // line segments, when subsets are requested.
188 // polygon only contains a single action, fail if subset
189 // requests different range
190 if( rSubset.mnSubsetBegin != 0 ||
191 rSubset.mnSubsetEnd != 1 )
192 return false;
194 return CachedPrimitiveBase::render( rTransformation );
197 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
199 rendering::RenderState aLocalState( maState );
200 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
202 return tools::calcDevicePixelBounds(
203 maBounds,
204 mpCanvas->getViewState(),
205 aLocalState );
208 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
209 const Subset& rSubset ) const
211 // TODO(F1): Split up poly-polygon into polygons, or even
212 // line segments, when subsets are requested.
214 // polygon only contains a single action, empty bounds
215 // if subset requests different range
216 if( rSubset.mnSubsetBegin != 0 ||
217 rSubset.mnSubsetEnd != 1 )
218 return ::basegfx::B2DRange();
220 return getBounds( rTransformation );
223 sal_Int32 PolyPolyAction::getActionCount() const
225 // TODO(F1): Split up poly-polygon into polygons, or even
226 // line segments, when subsets are requested.
227 return 1;
231 class TexturedPolyPolyAction : public CachedPrimitiveBase
233 public:
234 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
235 const CanvasSharedPtr& rCanvas,
236 const OutDevState& rState,
237 const rendering::Texture& rTexture );
239 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
240 const Subset& rSubset ) const override;
242 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
243 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
244 const Subset& rSubset ) const override;
246 virtual sal_Int32 getActionCount() const override;
248 private:
249 using Action::render;
250 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
251 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
253 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
254 const ::basegfx::B2DRectangle maBounds;
255 const CanvasSharedPtr mpCanvas;
257 // stroke color is now implicit: the maState.DeviceColor member
258 rendering::RenderState maState;
259 const rendering::Texture maTexture;
262 TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
263 const CanvasSharedPtr& rCanvas,
264 const OutDevState& rState,
265 const rendering::Texture& rTexture ) :
266 CachedPrimitiveBase( rCanvas, true ),
267 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
268 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
269 mpCanvas( rCanvas ),
270 maState(),
271 maTexture( rTexture )
273 tools::initRenderState(maState,rState);
276 bool TexturedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
277 const ::basegfx::B2DHomMatrix& rTransformation ) const
279 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
280 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
282 rendering::RenderState aLocalState( maState );
283 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
285 uno::Sequence< rendering::Texture > aSeq(1);
286 aSeq[0] = maTexture;
288 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
289 mpCanvas->getViewState(),
290 aLocalState,
291 aSeq );
292 return true;
295 bool TexturedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
296 const Subset& rSubset ) const
298 // TODO(F1): Split up poly-polygon into polygons, or even
299 // line segments, when subsets are requested.
301 // polygon only contains a single action, fail if subset
302 // requests different range
303 if( rSubset.mnSubsetBegin != 0 ||
304 rSubset.mnSubsetEnd != 1 )
305 return false;
307 return CachedPrimitiveBase::render( rTransformation );
310 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
312 rendering::RenderState aLocalState( maState );
313 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
315 return tools::calcDevicePixelBounds(
316 maBounds,
317 mpCanvas->getViewState(),
318 aLocalState );
321 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
322 const Subset& rSubset ) const
324 // TODO(F1): Split up poly-polygon into polygons, or even
325 // line segments, when subsets are requested.
327 // polygon only contains a single action, empty bounds
328 // if subset requests different range
329 if( rSubset.mnSubsetBegin != 0 ||
330 rSubset.mnSubsetEnd != 1 )
331 return ::basegfx::B2DRange();
333 return getBounds( rTransformation );
336 sal_Int32 TexturedPolyPolyAction::getActionCount() const
338 // TODO(F1): Split up poly-polygon into polygons, or even
339 // line segments, when subsets are requested.
340 return 1;
344 class StrokedPolyPolyAction : public CachedPrimitiveBase
346 public:
347 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
348 const CanvasSharedPtr& rCanvas,
349 const OutDevState& rState,
350 const rendering::StrokeAttributes& rStrokeAttributes );
352 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
353 const Subset& rSubset ) const override;
355 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
356 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
357 const Subset& rSubset ) const override;
359 virtual sal_Int32 getActionCount() const override;
361 private:
362 using Action::render;
363 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
364 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
366 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
367 const ::basegfx::B2DRectangle maBounds;
368 const CanvasSharedPtr mpCanvas;
369 rendering::RenderState maState;
370 const rendering::StrokeAttributes maStrokeAttributes;
373 StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
374 const CanvasSharedPtr& rCanvas,
375 const OutDevState& rState,
376 const rendering::StrokeAttributes& rStrokeAttributes ) :
377 CachedPrimitiveBase( rCanvas, false ),
378 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
379 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
380 mpCanvas( rCanvas ),
381 maState(),
382 maStrokeAttributes( rStrokeAttributes )
384 tools::initRenderState(maState,rState);
385 maState.DeviceColor = rState.lineColor;
388 bool StrokedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
389 const ::basegfx::B2DHomMatrix& rTransformation ) const
391 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
392 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
394 rendering::RenderState aLocalState( maState );
395 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
397 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
398 mpCanvas->getViewState(),
399 aLocalState,
400 maStrokeAttributes );
401 return true;
404 bool StrokedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
405 const Subset& rSubset ) const
407 // TODO(F1): Split up poly-polygon into polygons, or even
408 // line segments, when subsets are requested.
410 // polygon only contains a single action, fail if subset
411 // requests different range
412 if( rSubset.mnSubsetBegin != 0 ||
413 rSubset.mnSubsetEnd != 1 )
414 return false;
416 return CachedPrimitiveBase::render( rTransformation );
419 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
421 rendering::RenderState aLocalState( maState );
422 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
424 return tools::calcDevicePixelBounds(
425 maBounds,
426 mpCanvas->getViewState(),
427 aLocalState );
430 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
431 const Subset& rSubset ) const
433 // TODO(F1): Split up poly-polygon into polygons, or even
434 // line segments, when subsets are requested.
436 // polygon only contains a single action, empty bounds
437 // if subset requests different range
438 if( rSubset.mnSubsetBegin != 0 ||
439 rSubset.mnSubsetEnd != 1 )
440 return ::basegfx::B2DRange();
442 return getBounds( rTransformation );
445 sal_Int32 StrokedPolyPolyAction::getActionCount() const
447 // TODO(F1): Split up poly-polygon into polygons, or even
448 // line segments, when subsets are requested.
449 return 1;
453 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
454 const CanvasSharedPtr& rCanvas,
455 const OutDevState& rState )
457 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
458 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
459 return std::shared_ptr<Action>( new PolyPolyAction( rPoly, rCanvas, rState,
460 rState.isFillColorSet,
461 rState.isLineColorSet ) );
464 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
465 const CanvasSharedPtr& rCanvas,
466 const OutDevState& rState,
467 const rendering::Texture& rTexture )
469 return std::shared_ptr<Action>( new TexturedPolyPolyAction( rPoly, rCanvas, rState, rTexture ) );
472 std::shared_ptr<Action> PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
473 const CanvasSharedPtr& rCanvas,
474 const OutDevState& rState )
476 OSL_ENSURE( rState.isLineColorSet,
477 "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
479 return std::shared_ptr<Action>( new PolyPolyAction( rPoly, rCanvas, rState,
480 false,
481 rState.isLineColorSet ) );
484 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
485 const CanvasSharedPtr& rCanvas,
486 const OutDevState& rState,
487 const rendering::StrokeAttributes& rStrokeAttributes )
489 OSL_ENSURE( rState.isLineColorSet,
490 "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
491 return std::shared_ptr<Action>( new StrokedPolyPolyAction( rPoly, rCanvas, rState, rStrokeAttributes ) );
494 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
495 const CanvasSharedPtr& rCanvas,
496 const OutDevState& rState,
497 int nTransparency )
499 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
500 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
501 return std::shared_ptr<Action>( new PolyPolyAction( rPoly, rCanvas, rState,
502 rState.isFillColorSet,
503 rState.isLineColorSet,
504 nTransparency ) );
510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */