Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / cppcanvas / source / mtfrenderer / polypolyaction.cxx
blobaf08d65435b178d32981c2ac3a651c8d61682e83
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 <boost/utility.hpp>
36 #include "cachedprimitivebase.hxx"
37 #include "polypolyaction.hxx"
38 #include "outdevstate.hxx"
39 #include "mtftools.hxx"
42 using namespace ::com::sun::star;
44 namespace cppcanvas
46 namespace internal
48 namespace
50 class PolyPolyAction : public CachedPrimitiveBase
52 public:
53 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
54 const CanvasSharedPtr&,
55 const OutDevState&,
56 bool bFill,
57 bool bStroke );
58 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
59 const CanvasSharedPtr&,
60 const OutDevState&,
61 bool bFill,
62 bool bStroke,
63 int nTransparency );
65 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
66 const Subset& rSubset ) const;
68 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
69 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
70 const Subset& rSubset ) const;
72 virtual sal_Int32 getActionCount() const;
74 private:
75 using Action::render;
76 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
77 const ::basegfx::B2DHomMatrix& rTransformation ) const;
79 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
80 const ::basegfx::B2DRange maBounds;
81 const CanvasSharedPtr mpCanvas;
83 // stroke color is now implicit: the maState.DeviceColor member
84 rendering::RenderState maState;
86 uno::Sequence< double > maFillColor;
89 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
90 const CanvasSharedPtr& rCanvas,
91 const OutDevState& rState,
92 bool bFill,
93 bool bStroke ) :
94 CachedPrimitiveBase( rCanvas, false ),
95 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
96 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
97 mpCanvas( rCanvas ),
98 maState(),
99 maFillColor()
101 tools::initRenderState(maState,rState);
103 if( bFill )
104 maFillColor = rState.fillColor;
106 if( bStroke )
107 maState.DeviceColor = rState.lineColor;
110 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
111 const CanvasSharedPtr& rCanvas,
112 const OutDevState& rState,
113 bool bFill,
114 bool bStroke,
115 int nTransparency ) :
116 CachedPrimitiveBase( rCanvas, false ),
117 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
118 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
119 mpCanvas( rCanvas ),
120 maState(),
121 maFillColor()
123 tools::initRenderState(maState,rState);
125 if( bFill )
127 maFillColor = rState.fillColor;
129 if( maFillColor.getLength() < 4 )
130 maFillColor.realloc( 4 );
132 // TODO(F1): Color management
133 // adapt fill color transparency
134 maFillColor[3] = 1.0 - nTransparency / 100.0;
137 if( bStroke )
139 maState.DeviceColor = rState.lineColor;
141 if( maState.DeviceColor.getLength() < 4 )
142 maState.DeviceColor.realloc( 4 );
144 // TODO(F1): Color management
145 // adapt fill color transparency
146 maState.DeviceColor[3] = 1.0 - nTransparency / 100.0;
150 bool PolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
151 const ::basegfx::B2DHomMatrix& rTransformation ) const
153 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
154 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
156 rendering::RenderState aLocalState( maState );
157 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
159 if( maFillColor.getLength() )
161 // TODO(E3): Use DBO's finalizer here,
162 // fillPolyPolygon() might throw
163 const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
164 aLocalState.DeviceColor = maFillColor;
166 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
167 mpCanvas->getViewState(),
168 aLocalState );
170 aLocalState.DeviceColor = aTmpColor;
173 if( aLocalState.DeviceColor.getLength() )
175 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
176 mpCanvas->getViewState(),
177 aLocalState );
180 return true;
183 bool PolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
184 const Subset& rSubset ) const
186 // TODO(F1): Split up poly-polygon into polygons, or even
187 // line segments, when subsets are requested.
189 // polygon only contains a single action, fail if subset
190 // requests different range
191 if( rSubset.mnSubsetBegin != 0 ||
192 rSubset.mnSubsetEnd != 1 )
193 return false;
195 return CachedPrimitiveBase::render( rTransformation );
198 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
200 rendering::RenderState aLocalState( maState );
201 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
203 return tools::calcDevicePixelBounds(
204 maBounds,
205 mpCanvas->getViewState(),
206 aLocalState );
209 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
210 const Subset& rSubset ) const
212 // TODO(F1): Split up poly-polygon into polygons, or even
213 // line segments, when subsets are requested.
215 // polygon only contains a single action, empty bounds
216 // if subset requests different range
217 if( rSubset.mnSubsetBegin != 0 ||
218 rSubset.mnSubsetEnd != 1 )
219 return ::basegfx::B2DRange();
221 return getBounds( rTransformation );
224 sal_Int32 PolyPolyAction::getActionCount() const
226 // TODO(F1): Split up poly-polygon into polygons, or even
227 // line segments, when subsets are requested.
228 return 1;
232 // -------------------------------------------------------------------------------
234 class TexturedPolyPolyAction : public CachedPrimitiveBase
236 public:
237 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
238 const CanvasSharedPtr& rCanvas,
239 const OutDevState& rState,
240 const rendering::Texture& rTexture );
242 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
243 const Subset& rSubset ) const;
245 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
246 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
247 const Subset& rSubset ) const;
249 virtual sal_Int32 getActionCount() const;
251 private:
252 using Action::render;
253 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
254 const ::basegfx::B2DHomMatrix& rTransformation ) const;
256 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
257 const ::basegfx::B2DRectangle maBounds;
258 const CanvasSharedPtr mpCanvas;
260 // stroke color is now implicit: the maState.DeviceColor member
261 rendering::RenderState maState;
262 const rendering::Texture maTexture;
265 TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
266 const CanvasSharedPtr& rCanvas,
267 const OutDevState& rState,
268 const rendering::Texture& rTexture ) :
269 CachedPrimitiveBase( rCanvas, true ),
270 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
271 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
272 mpCanvas( rCanvas ),
273 maState(),
274 maTexture( rTexture )
276 tools::initRenderState(maState,rState);
279 bool TexturedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
280 const ::basegfx::B2DHomMatrix& rTransformation ) const
282 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
283 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
285 rendering::RenderState aLocalState( maState );
286 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
288 uno::Sequence< rendering::Texture > aSeq(1);
289 aSeq[0] = maTexture;
291 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
292 mpCanvas->getViewState(),
293 aLocalState,
294 aSeq );
295 return true;
298 bool TexturedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
299 const Subset& rSubset ) const
301 // TODO(F1): Split up poly-polygon into polygons, or even
302 // line segments, when subsets are requested.
304 // polygon only contains a single action, fail if subset
305 // requests different range
306 if( rSubset.mnSubsetBegin != 0 ||
307 rSubset.mnSubsetEnd != 1 )
308 return false;
310 return CachedPrimitiveBase::render( rTransformation );
313 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
315 rendering::RenderState aLocalState( maState );
316 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
318 return tools::calcDevicePixelBounds(
319 maBounds,
320 mpCanvas->getViewState(),
321 aLocalState );
324 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
325 const Subset& rSubset ) const
327 // TODO(F1): Split up poly-polygon into polygons, or even
328 // line segments, when subsets are requested.
330 // polygon only contains a single action, empty bounds
331 // if subset requests different range
332 if( rSubset.mnSubsetBegin != 0 ||
333 rSubset.mnSubsetEnd != 1 )
334 return ::basegfx::B2DRange();
336 return getBounds( rTransformation );
339 sal_Int32 TexturedPolyPolyAction::getActionCount() const
341 // TODO(F1): Split up poly-polygon into polygons, or even
342 // line segments, when subsets are requested.
343 return 1;
346 // -------------------------------------------------------------------------------
348 class StrokedPolyPolyAction : public CachedPrimitiveBase
350 public:
351 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
352 const CanvasSharedPtr& rCanvas,
353 const OutDevState& rState,
354 const rendering::StrokeAttributes& rStrokeAttributes );
356 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
357 const Subset& rSubset ) const;
359 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
360 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
361 const Subset& rSubset ) const;
363 virtual sal_Int32 getActionCount() const;
365 private:
366 using Action::render;
367 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
368 const ::basegfx::B2DHomMatrix& rTransformation ) const;
370 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
371 const ::basegfx::B2DRectangle maBounds;
372 const CanvasSharedPtr mpCanvas;
373 rendering::RenderState maState;
374 const rendering::StrokeAttributes maStrokeAttributes;
377 StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
378 const CanvasSharedPtr& rCanvas,
379 const OutDevState& rState,
380 const rendering::StrokeAttributes& rStrokeAttributes ) :
381 CachedPrimitiveBase( rCanvas, false ),
382 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
383 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
384 mpCanvas( rCanvas ),
385 maState(),
386 maStrokeAttributes( rStrokeAttributes )
388 tools::initRenderState(maState,rState);
389 maState.DeviceColor = rState.lineColor;
392 bool StrokedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
393 const ::basegfx::B2DHomMatrix& rTransformation ) const
395 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
396 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
398 rendering::RenderState aLocalState( maState );
399 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
401 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
402 mpCanvas->getViewState(),
403 aLocalState,
404 maStrokeAttributes );
405 return true;
408 bool StrokedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
409 const Subset& rSubset ) const
411 // TODO(F1): Split up poly-polygon into polygons, or even
412 // line segments, when subsets are requested.
414 // polygon only contains a single action, fail if subset
415 // requests different range
416 if( rSubset.mnSubsetBegin != 0 ||
417 rSubset.mnSubsetEnd != 1 )
418 return false;
420 return CachedPrimitiveBase::render( rTransformation );
423 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
425 rendering::RenderState aLocalState( maState );
426 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
428 return tools::calcDevicePixelBounds(
429 maBounds,
430 mpCanvas->getViewState(),
431 aLocalState );
434 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
435 const Subset& rSubset ) const
437 // TODO(F1): Split up poly-polygon into polygons, or even
438 // line segments, when subsets are requested.
440 // polygon only contains a single action, empty bounds
441 // if subset requests different range
442 if( rSubset.mnSubsetBegin != 0 ||
443 rSubset.mnSubsetEnd != 1 )
444 return ::basegfx::B2DRange();
446 return getBounds( rTransformation );
449 sal_Int32 StrokedPolyPolyAction::getActionCount() const
451 // TODO(F1): Split up poly-polygon into polygons, or even
452 // line segments, when subsets are requested.
453 return 1;
457 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
458 const CanvasSharedPtr& rCanvas,
459 const OutDevState& rState )
461 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
462 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
463 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
464 rState.isFillColorSet,
465 rState.isLineColorSet ) );
468 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
469 const CanvasSharedPtr& rCanvas,
470 const OutDevState& rState,
471 const rendering::Texture& rTexture )
473 return ActionSharedPtr( new TexturedPolyPolyAction( rPoly, rCanvas, rState, rTexture ) );
476 ActionSharedPtr PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
477 const CanvasSharedPtr& rCanvas,
478 const OutDevState& rState )
480 OSL_ENSURE( rState.isLineColorSet,
481 "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
483 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
484 false,
485 rState.isLineColorSet ) );
488 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
489 const CanvasSharedPtr& rCanvas,
490 const OutDevState& rState,
491 const rendering::StrokeAttributes& rStrokeAttributes )
493 OSL_ENSURE( rState.isLineColorSet,
494 "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
495 return ActionSharedPtr( new StrokedPolyPolyAction( rPoly, rCanvas, rState, rStrokeAttributes ) );
498 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
499 const CanvasSharedPtr& rCanvas,
500 const OutDevState& rState,
501 int nTransparency )
503 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
504 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
505 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
506 rState.isFillColorSet,
507 rState.isLineColorSet,
508 nTransparency ) );
514 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */