Bump for 3.6-28
[LibreOffice.git] / cppcanvas / source / mtfrenderer / polypolyaction.cxx
blob9f480f5acfc798fe0f8b90eac46b3ed07474c7c7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
30 #include <rtl/logfile.hxx>
32 #include <com/sun/star/rendering/XCanvas.hpp>
33 #include <com/sun/star/rendering/TexturingMode.hpp>
35 #include <tools/gen.hxx>
36 #include <vcl/canvastools.hxx>
38 #include <basegfx/range/b2drectangle.hxx>
39 #include <basegfx/tools/canvastools.hxx>
40 #include <basegfx/polygon/b2dpolypolygon.hxx>
41 #include <basegfx/polygon/b2dpolypolygontools.hxx>
42 #include <basegfx/matrix/b2dhommatrix.hxx>
43 #include <canvas/canvastools.hxx>
45 #include <boost/utility.hpp>
47 #include "cachedprimitivebase.hxx"
48 #include "polypolyaction.hxx"
49 #include "outdevstate.hxx"
50 #include "mtftools.hxx"
53 using namespace ::com::sun::star;
55 namespace cppcanvas
57 namespace internal
59 namespace
61 class PolyPolyAction : public CachedPrimitiveBase
63 public:
64 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
65 const CanvasSharedPtr&,
66 const OutDevState&,
67 bool bFill,
68 bool bStroke );
69 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
70 const CanvasSharedPtr&,
71 const OutDevState&,
72 bool bFill,
73 bool bStroke,
74 int nTransparency );
76 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
77 const Subset& rSubset ) const;
79 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
80 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
81 const Subset& rSubset ) const;
83 virtual sal_Int32 getActionCount() const;
85 private:
86 using Action::render;
87 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
88 const ::basegfx::B2DHomMatrix& rTransformation ) const;
90 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
91 const ::basegfx::B2DRange maBounds;
92 const CanvasSharedPtr mpCanvas;
94 // stroke color is now implicit: the maState.DeviceColor member
95 rendering::RenderState maState;
97 uno::Sequence< double > maFillColor;
100 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
101 const CanvasSharedPtr& rCanvas,
102 const OutDevState& rState,
103 bool bFill,
104 bool bStroke ) :
105 CachedPrimitiveBase( rCanvas, false ),
106 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
107 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
108 mpCanvas( rCanvas ),
109 maState(),
110 maFillColor()
112 tools::initRenderState(maState,rState);
114 if( bFill )
115 maFillColor = rState.fillColor;
117 if( bStroke )
118 maState.DeviceColor = rState.lineColor;
121 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
122 const CanvasSharedPtr& rCanvas,
123 const OutDevState& rState,
124 bool bFill,
125 bool bStroke,
126 int nTransparency ) :
127 CachedPrimitiveBase( rCanvas, false ),
128 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
129 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
130 mpCanvas( rCanvas ),
131 maState(),
132 maFillColor()
134 tools::initRenderState(maState,rState);
136 if( bFill )
138 maFillColor = rState.fillColor;
140 if( maFillColor.getLength() < 4 )
141 maFillColor.realloc( 4 );
143 // TODO(F1): Color management
144 // adapt fill color transparency
145 maFillColor[3] = 1.0 - nTransparency / 100.0;
148 if( bStroke )
150 maState.DeviceColor = rState.lineColor;
152 if( maState.DeviceColor.getLength() < 4 )
153 maState.DeviceColor.realloc( 4 );
155 // TODO(F1): Color management
156 // adapt fill color transparency
157 maState.DeviceColor[3] = 1.0 - nTransparency / 100.0;
161 bool PolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
162 const ::basegfx::B2DHomMatrix& rTransformation ) const
164 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
165 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
167 rendering::RenderState aLocalState( maState );
168 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
170 if( maFillColor.getLength() )
172 // TODO(E3): Use DBO's finalizer here,
173 // fillPolyPolygon() might throw
174 const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
175 aLocalState.DeviceColor = maFillColor;
177 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
178 mpCanvas->getViewState(),
179 aLocalState );
181 aLocalState.DeviceColor = aTmpColor;
184 if( aLocalState.DeviceColor.getLength() )
186 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
187 mpCanvas->getViewState(),
188 aLocalState );
191 return true;
194 bool PolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
195 const Subset& rSubset ) const
197 // TODO(F1): Split up poly-polygon into polygons, or even
198 // line segments, when subsets are requested.
200 // polygon only contains a single action, fail if subset
201 // requests different range
202 if( rSubset.mnSubsetBegin != 0 ||
203 rSubset.mnSubsetEnd != 1 )
204 return false;
206 return CachedPrimitiveBase::render( rTransformation );
209 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
211 rendering::RenderState aLocalState( maState );
212 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
214 return tools::calcDevicePixelBounds(
215 maBounds,
216 mpCanvas->getViewState(),
217 aLocalState );
220 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
221 const Subset& rSubset ) const
223 // TODO(F1): Split up poly-polygon into polygons, or even
224 // line segments, when subsets are requested.
226 // polygon only contains a single action, empty bounds
227 // if subset requests different range
228 if( rSubset.mnSubsetBegin != 0 ||
229 rSubset.mnSubsetEnd != 1 )
230 return ::basegfx::B2DRange();
232 return getBounds( rTransformation );
235 sal_Int32 PolyPolyAction::getActionCount() const
237 // TODO(F1): Split up poly-polygon into polygons, or even
238 // line segments, when subsets are requested.
239 return 1;
243 // -------------------------------------------------------------------------------
245 class TexturedPolyPolyAction : public CachedPrimitiveBase
247 public:
248 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
249 const CanvasSharedPtr& rCanvas,
250 const OutDevState& rState,
251 const rendering::Texture& rTexture );
253 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
254 const Subset& rSubset ) const;
256 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
257 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
258 const Subset& rSubset ) const;
260 virtual sal_Int32 getActionCount() const;
262 private:
263 using Action::render;
264 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
265 const ::basegfx::B2DHomMatrix& rTransformation ) const;
267 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
268 const ::basegfx::B2DRectangle maBounds;
269 const CanvasSharedPtr mpCanvas;
271 // stroke color is now implicit: the maState.DeviceColor member
272 rendering::RenderState maState;
273 const rendering::Texture maTexture;
276 TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
277 const CanvasSharedPtr& rCanvas,
278 const OutDevState& rState,
279 const rendering::Texture& rTexture ) :
280 CachedPrimitiveBase( rCanvas, true ),
281 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
282 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
283 mpCanvas( rCanvas ),
284 maState(),
285 maTexture( rTexture )
287 tools::initRenderState(maState,rState);
290 bool TexturedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
291 const ::basegfx::B2DHomMatrix& rTransformation ) const
293 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
294 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
296 rendering::RenderState aLocalState( maState );
297 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
299 uno::Sequence< rendering::Texture > aSeq(1);
300 aSeq[0] = maTexture;
302 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
303 mpCanvas->getViewState(),
304 aLocalState,
305 aSeq );
306 return true;
309 bool TexturedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
310 const Subset& rSubset ) const
312 // TODO(F1): Split up poly-polygon into polygons, or even
313 // line segments, when subsets are requested.
315 // polygon only contains a single action, fail if subset
316 // requests different range
317 if( rSubset.mnSubsetBegin != 0 ||
318 rSubset.mnSubsetEnd != 1 )
319 return false;
321 return CachedPrimitiveBase::render( rTransformation );
324 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
326 rendering::RenderState aLocalState( maState );
327 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
329 return tools::calcDevicePixelBounds(
330 maBounds,
331 mpCanvas->getViewState(),
332 aLocalState );
335 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
336 const Subset& rSubset ) const
338 // TODO(F1): Split up poly-polygon into polygons, or even
339 // line segments, when subsets are requested.
341 // polygon only contains a single action, empty bounds
342 // if subset requests different range
343 if( rSubset.mnSubsetBegin != 0 ||
344 rSubset.mnSubsetEnd != 1 )
345 return ::basegfx::B2DRange();
347 return getBounds( rTransformation );
350 sal_Int32 TexturedPolyPolyAction::getActionCount() const
352 // TODO(F1): Split up poly-polygon into polygons, or even
353 // line segments, when subsets are requested.
354 return 1;
357 // -------------------------------------------------------------------------------
359 class StrokedPolyPolyAction : public CachedPrimitiveBase
361 public:
362 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
363 const CanvasSharedPtr& rCanvas,
364 const OutDevState& rState,
365 const rendering::StrokeAttributes& rStrokeAttributes );
367 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
368 const Subset& rSubset ) const;
370 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
371 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
372 const Subset& rSubset ) const;
374 virtual sal_Int32 getActionCount() const;
376 private:
377 using Action::render;
378 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
379 const ::basegfx::B2DHomMatrix& rTransformation ) const;
381 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
382 const ::basegfx::B2DRectangle maBounds;
383 const CanvasSharedPtr mpCanvas;
384 rendering::RenderState maState;
385 const rendering::StrokeAttributes maStrokeAttributes;
388 StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
389 const CanvasSharedPtr& rCanvas,
390 const OutDevState& rState,
391 const rendering::StrokeAttributes& rStrokeAttributes ) :
392 CachedPrimitiveBase( rCanvas, false ),
393 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
394 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
395 mpCanvas( rCanvas ),
396 maState(),
397 maStrokeAttributes( rStrokeAttributes )
399 tools::initRenderState(maState,rState);
400 maState.DeviceColor = rState.lineColor;
403 bool StrokedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
404 const ::basegfx::B2DHomMatrix& rTransformation ) const
406 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
407 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
409 rendering::RenderState aLocalState( maState );
410 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
412 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
413 mpCanvas->getViewState(),
414 aLocalState,
415 maStrokeAttributes );
416 return true;
419 bool StrokedPolyPolyAction::renderSubset( 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, fail if subset
426 // requests different range
427 if( rSubset.mnSubsetBegin != 0 ||
428 rSubset.mnSubsetEnd != 1 )
429 return false;
431 return CachedPrimitiveBase::render( rTransformation );
434 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
436 rendering::RenderState aLocalState( maState );
437 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
439 return tools::calcDevicePixelBounds(
440 maBounds,
441 mpCanvas->getViewState(),
442 aLocalState );
445 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
446 const Subset& rSubset ) const
448 // TODO(F1): Split up poly-polygon into polygons, or even
449 // line segments, when subsets are requested.
451 // polygon only contains a single action, empty bounds
452 // if subset requests different range
453 if( rSubset.mnSubsetBegin != 0 ||
454 rSubset.mnSubsetEnd != 1 )
455 return ::basegfx::B2DRange();
457 return getBounds( rTransformation );
460 sal_Int32 StrokedPolyPolyAction::getActionCount() const
462 // TODO(F1): Split up poly-polygon into polygons, or even
463 // line segments, when subsets are requested.
464 return 1;
468 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
469 const CanvasSharedPtr& rCanvas,
470 const OutDevState& rState )
472 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
473 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
474 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
475 rState.isFillColorSet,
476 rState.isLineColorSet ) );
479 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
480 const CanvasSharedPtr& rCanvas,
481 const OutDevState& rState,
482 const rendering::Texture& rTexture )
484 return ActionSharedPtr( new TexturedPolyPolyAction( rPoly, rCanvas, rState, rTexture ) );
487 ActionSharedPtr PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
488 const CanvasSharedPtr& rCanvas,
489 const OutDevState& rState )
491 OSL_ENSURE( rState.isLineColorSet,
492 "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
494 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
495 false,
496 rState.isLineColorSet ) );
499 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
500 const CanvasSharedPtr& rCanvas,
501 const OutDevState& rState,
502 const rendering::StrokeAttributes& rStrokeAttributes )
504 OSL_ENSURE( rState.isLineColorSet,
505 "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
506 return ActionSharedPtr( new StrokedPolyPolyAction( rPoly, rCanvas, rState, rStrokeAttributes ) );
509 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
510 const CanvasSharedPtr& rCanvas,
511 const OutDevState& rState,
512 int nTransparency )
514 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
515 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
516 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
517 rState.isFillColorSet,
518 rState.isLineColorSet,
519 nTransparency ) );
525 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */