Prepare for removal of non-const operator[] from Sequence in cppcanvas
[LibreOffice.git] / cppcanvas / source / mtfrenderer / polypolyaction.cxx
blobe191e512ec61ba6c9c4bb54c1eb37aa703c1c3f5
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>
23 #include <sal/types.h>
25 #include <basegfx/range/b2drectangle.hxx>
26 #include <basegfx/utils/canvastools.hxx>
27 #include <basegfx/polygon/b2dpolypolygon.hxx>
28 #include <basegfx/polygon/b2dpolypolygontools.hxx>
29 #include <basegfx/matrix/b2dhommatrix.hxx>
30 #include <canvas/canvastools.hxx>
31 #include <sal/log.hxx>
33 #include "cachedprimitivebase.hxx"
34 #include "polypolyaction.hxx"
35 #include <outdevstate.hxx>
36 #include "mtftools.hxx"
39 using namespace ::com::sun::star;
41 namespace cppcanvas::internal
43 namespace
45 class PolyPolyAction : public CachedPrimitiveBase
47 public:
48 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
49 const CanvasSharedPtr&,
50 const OutDevState&,
51 bool bFill,
52 bool bStroke );
53 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
54 const CanvasSharedPtr&,
55 const OutDevState&,
56 bool bFill,
57 bool bStroke,
58 int nTransparency );
60 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
61 const Subset& rSubset ) const override;
63 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
64 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
65 const Subset& rSubset ) const override;
67 virtual sal_Int32 getActionCount() const override;
69 private:
70 using Action::render;
71 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
72 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
74 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
75 const ::basegfx::B2DRange maBounds;
76 const CanvasSharedPtr mpCanvas;
78 // stroke color is now implicit: the maState.DeviceColor member
79 rendering::RenderState maState;
81 uno::Sequence< double > maFillColor;
84 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
85 const CanvasSharedPtr& rCanvas,
86 const OutDevState& rState,
87 bool bFill,
88 bool bStroke ) :
89 CachedPrimitiveBase( rCanvas, false ),
90 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
91 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
92 mpCanvas( rCanvas )
94 tools::initRenderState(maState,rState);
96 if( bFill )
97 maFillColor = rState.fillColor;
99 if( bStroke )
100 maState.DeviceColor = rState.lineColor;
103 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
104 const CanvasSharedPtr& rCanvas,
105 const OutDevState& rState,
106 bool bFill,
107 bool bStroke,
108 int nTransparency ) :
109 CachedPrimitiveBase( rCanvas, false ),
110 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
111 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
112 mpCanvas( rCanvas )
114 tools::initRenderState(maState,rState);
116 if( bFill )
118 maFillColor = rState.fillColor;
120 if( maFillColor.getLength() < 4 )
121 maFillColor.realloc( 4 );
123 // TODO(F1): Color management
124 // adapt fill color transparency
125 maFillColor.getArray()[3] = 1.0 - nTransparency / 100.0;
128 if( bStroke )
130 maState.DeviceColor = rState.lineColor;
132 if( maState.DeviceColor.getLength() < 4 )
133 maState.DeviceColor.realloc( 4 );
135 // TODO(F1): Color management
136 // adapt fill color transparency
137 maState.DeviceColor.getArray()[3] = 1.0 - nTransparency / 100.0;
141 bool PolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
142 const ::basegfx::B2DHomMatrix& rTransformation ) const
144 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
145 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
147 rendering::RenderState aLocalState( maState );
148 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
150 if( maFillColor.hasElements() )
152 // TODO(E3): Use DBO's finalizer here,
153 // fillPolyPolygon() might throw
154 const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
155 aLocalState.DeviceColor = maFillColor;
157 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
158 mpCanvas->getViewState(),
159 aLocalState );
161 aLocalState.DeviceColor = aTmpColor;
164 if( aLocalState.DeviceColor.hasElements() )
166 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
167 mpCanvas->getViewState(),
168 aLocalState );
171 return true;
174 bool PolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
175 const Subset& rSubset ) const
177 // TODO(F1): Split up poly-polygon into polygons, or even
178 // line segments, when subsets are requested.
180 // polygon only contains a single action, fail if subset
181 // requests different range
182 if( rSubset.mnSubsetBegin != 0 ||
183 rSubset.mnSubsetEnd != 1 )
184 return false;
186 return CachedPrimitiveBase::render( rTransformation );
189 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
191 rendering::RenderState aLocalState( maState );
192 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
194 return tools::calcDevicePixelBounds(
195 maBounds,
196 mpCanvas->getViewState(),
197 aLocalState );
200 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
201 const Subset& rSubset ) const
203 // TODO(F1): Split up poly-polygon into polygons, or even
204 // line segments, when subsets are requested.
206 // polygon only contains a single action, empty bounds
207 // if subset requests different range
208 if( rSubset.mnSubsetBegin != 0 ||
209 rSubset.mnSubsetEnd != 1 )
210 return ::basegfx::B2DRange();
212 return getBounds( rTransformation );
215 sal_Int32 PolyPolyAction::getActionCount() const
217 // TODO(F1): Split up poly-polygon into polygons, or even
218 // line segments, when subsets are requested.
219 return 1;
223 class TexturedPolyPolyAction : public CachedPrimitiveBase
225 public:
226 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
227 const CanvasSharedPtr& rCanvas,
228 const OutDevState& rState,
229 const rendering::Texture& rTexture );
231 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
232 const Subset& rSubset ) const override;
234 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
235 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
236 const Subset& rSubset ) const override;
238 virtual sal_Int32 getActionCount() const override;
240 private:
241 using Action::render;
242 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
243 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
245 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
246 const ::basegfx::B2DRectangle maBounds;
247 const CanvasSharedPtr mpCanvas;
249 // stroke color is now implicit: the maState.DeviceColor member
250 rendering::RenderState maState;
251 const rendering::Texture maTexture;
254 TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
255 const CanvasSharedPtr& rCanvas,
256 const OutDevState& rState,
257 const rendering::Texture& rTexture ) :
258 CachedPrimitiveBase( rCanvas, true ),
259 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
260 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
261 mpCanvas( rCanvas ),
262 maTexture( rTexture )
264 tools::initRenderState(maState,rState);
267 bool TexturedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
268 const ::basegfx::B2DHomMatrix& rTransformation ) const
270 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
271 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
273 rendering::RenderState aLocalState( maState );
274 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
276 uno::Sequence< rendering::Texture > aSeq { maTexture };
278 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
279 mpCanvas->getViewState(),
280 aLocalState,
281 aSeq );
282 return true;
285 bool TexturedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
286 const Subset& rSubset ) const
288 // TODO(F1): Split up poly-polygon into polygons, or even
289 // line segments, when subsets are requested.
291 // polygon only contains a single action, fail if subset
292 // requests different range
293 if( rSubset.mnSubsetBegin != 0 ||
294 rSubset.mnSubsetEnd != 1 )
295 return false;
297 return CachedPrimitiveBase::render( rTransformation );
300 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
302 rendering::RenderState aLocalState( maState );
303 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
305 return tools::calcDevicePixelBounds(
306 maBounds,
307 mpCanvas->getViewState(),
308 aLocalState );
311 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
312 const Subset& rSubset ) const
314 // TODO(F1): Split up poly-polygon into polygons, or even
315 // line segments, when subsets are requested.
317 // polygon only contains a single action, empty bounds
318 // if subset requests different range
319 if( rSubset.mnSubsetBegin != 0 ||
320 rSubset.mnSubsetEnd != 1 )
321 return ::basegfx::B2DRange();
323 return getBounds( rTransformation );
326 sal_Int32 TexturedPolyPolyAction::getActionCount() const
328 // TODO(F1): Split up poly-polygon into polygons, or even
329 // line segments, when subsets are requested.
330 return 1;
334 class StrokedPolyPolyAction : public CachedPrimitiveBase
336 public:
337 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
338 const CanvasSharedPtr& rCanvas,
339 const OutDevState& rState,
340 const rendering::StrokeAttributes& rStrokeAttributes );
342 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
343 const Subset& rSubset ) const override;
345 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
346 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
347 const Subset& rSubset ) const override;
349 virtual sal_Int32 getActionCount() const override;
351 private:
352 using Action::render;
353 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
354 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
356 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
357 const ::basegfx::B2DRectangle maBounds;
358 const CanvasSharedPtr mpCanvas;
359 rendering::RenderState maState;
360 const rendering::StrokeAttributes maStrokeAttributes;
363 StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
364 const CanvasSharedPtr& rCanvas,
365 const OutDevState& rState,
366 const rendering::StrokeAttributes& rStrokeAttributes ) :
367 CachedPrimitiveBase( rCanvas, false ),
368 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
369 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
370 mpCanvas( rCanvas ),
371 maStrokeAttributes( rStrokeAttributes )
373 tools::initRenderState(maState,rState);
374 maState.DeviceColor = rState.lineColor;
377 bool StrokedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
378 const ::basegfx::B2DHomMatrix& rTransformation ) const
380 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
381 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
383 rendering::RenderState aLocalState( maState );
384 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
386 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
387 mpCanvas->getViewState(),
388 aLocalState,
389 maStrokeAttributes );
390 return true;
393 bool StrokedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
394 const Subset& rSubset ) const
396 // TODO(F1): Split up poly-polygon into polygons, or even
397 // line segments, when subsets are requested.
399 // polygon only contains a single action, fail if subset
400 // requests different range
401 if( rSubset.mnSubsetBegin != 0 ||
402 rSubset.mnSubsetEnd != 1 )
403 return false;
405 return CachedPrimitiveBase::render( rTransformation );
408 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
410 rendering::RenderState aLocalState( maState );
411 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
413 return tools::calcDevicePixelBounds(
414 maBounds,
415 mpCanvas->getViewState(),
416 aLocalState );
419 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
420 const Subset& rSubset ) const
422 // TODO(F1): Split up poly-polygon into polygons, or even
423 // line segments, when subsets are requested.
425 // polygon only contains a single action, empty bounds
426 // if subset requests different range
427 if( rSubset.mnSubsetBegin != 0 ||
428 rSubset.mnSubsetEnd != 1 )
429 return ::basegfx::B2DRange();
431 return getBounds( rTransformation );
434 sal_Int32 StrokedPolyPolyAction::getActionCount() const
436 // TODO(F1): Split up poly-polygon into polygons, or even
437 // line segments, when subsets are requested.
438 return 1;
442 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
443 const CanvasSharedPtr& rCanvas,
444 const OutDevState& rState )
446 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
447 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
448 return std::make_shared<PolyPolyAction>( rPoly, rCanvas, rState,
449 rState.isFillColorSet,
450 rState.isLineColorSet );
453 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
454 const CanvasSharedPtr& rCanvas,
455 const OutDevState& rState,
456 const rendering::Texture& rTexture )
458 return std::make_shared<TexturedPolyPolyAction>( rPoly, rCanvas, rState, rTexture );
461 std::shared_ptr<Action> PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
462 const CanvasSharedPtr& rCanvas,
463 const OutDevState& rState )
465 OSL_ENSURE( rState.isLineColorSet,
466 "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
468 return std::make_shared<PolyPolyAction>( rPoly, rCanvas, rState,
469 false,
470 rState.isLineColorSet );
473 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
474 const CanvasSharedPtr& rCanvas,
475 const OutDevState& rState,
476 const rendering::StrokeAttributes& rStrokeAttributes )
478 OSL_ENSURE( rState.isLineColorSet,
479 "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
480 return std::make_shared<StrokedPolyPolyAction>( rPoly, rCanvas, rState, rStrokeAttributes );
483 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
484 const CanvasSharedPtr& rCanvas,
485 const OutDevState& rState,
486 int nTransparency )
488 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
489 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
490 return std::make_shared<PolyPolyAction>( rPoly, rCanvas, rState,
491 rState.isFillColorSet,
492 rState.isLineColorSet,
493 nTransparency );
498 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */