update dev300-m58
[ooovba.git] / cppcanvas / source / mtfrenderer / polypolyaction.cxx
blob3eb6359ed5fc428ac451946bb2f58199f74040d3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: polypolyaction.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppcanvas.hxx"
34 #include <rtl/logfile.hxx>
36 #include <com/sun/star/rendering/XCanvas.hpp>
37 #include <com/sun/star/rendering/TexturingMode.hpp>
39 #include <tools/gen.hxx>
40 #include <vcl/canvastools.hxx>
42 #include <basegfx/range/b2drectangle.hxx>
43 #include <basegfx/tools/canvastools.hxx>
44 #include <basegfx/polygon/b2dpolypolygon.hxx>
45 #include <basegfx/polygon/b2dpolypolygontools.hxx>
46 #include <basegfx/matrix/b2dhommatrix.hxx>
47 #include <canvas/canvastools.hxx>
49 #include <boost/utility.hpp>
51 #include "cachedprimitivebase.hxx"
52 #include "polypolyaction.hxx"
53 #include "outdevstate.hxx"
54 #include "mtftools.hxx"
57 using namespace ::com::sun::star;
59 namespace cppcanvas
61 namespace internal
63 namespace
65 class PolyPolyAction : public CachedPrimitiveBase
67 public:
68 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
69 const CanvasSharedPtr&,
70 const OutDevState&,
71 bool bFill,
72 bool bStroke );
73 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
74 const CanvasSharedPtr&,
75 const OutDevState&,
76 bool bFill,
77 bool bStroke,
78 int nTransparency );
80 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
81 const Subset& rSubset ) const;
83 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
84 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
85 const Subset& rSubset ) const;
87 virtual sal_Int32 getActionCount() const;
89 private:
90 using Action::render;
91 virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
92 const ::basegfx::B2DHomMatrix& rTransformation ) const;
94 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
95 const ::basegfx::B2DRange maBounds;
96 const CanvasSharedPtr mpCanvas;
98 // stroke color is now implicit: the maState.DeviceColor member
99 rendering::RenderState maState;
101 uno::Sequence< double > maFillColor;
104 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
105 const CanvasSharedPtr& rCanvas,
106 const OutDevState& rState,
107 bool bFill,
108 bool bStroke ) :
109 CachedPrimitiveBase( rCanvas, false ),
110 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
111 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
112 mpCanvas( rCanvas ),
113 maState(),
114 maFillColor()
116 tools::initRenderState(maState,rState);
118 if( bFill )
119 maFillColor = rState.fillColor;
121 if( bStroke )
122 maState.DeviceColor = rState.lineColor;
125 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
126 const CanvasSharedPtr& rCanvas,
127 const OutDevState& rState,
128 bool bFill,
129 bool bStroke,
130 int nTransparency ) :
131 CachedPrimitiveBase( rCanvas, false ),
132 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
133 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
134 mpCanvas( rCanvas ),
135 maState(),
136 maFillColor()
138 tools::initRenderState(maState,rState);
140 if( bFill )
142 maFillColor = rState.fillColor;
144 if( maFillColor.getLength() < 4 )
145 maFillColor.realloc( 4 );
147 // TODO(F1): Color management
148 // adapt fill color transparency
149 maFillColor[3] = 1.0 - nTransparency / 100.0;
152 if( bStroke )
154 maState.DeviceColor = rState.lineColor;
156 if( maState.DeviceColor.getLength() < 4 )
157 maState.DeviceColor.realloc( 4 );
159 // TODO(F1): Color management
160 // adapt fill color transparency
161 maState.DeviceColor[3] = 1.0 - nTransparency / 100.0;
165 bool PolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
166 const ::basegfx::B2DHomMatrix& rTransformation ) const
168 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" );
169 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
171 rendering::RenderState aLocalState( maState );
172 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
174 #ifdef SPECIAL_DEBUG
175 aLocalState.Clip.clear();
176 aLocalState.DeviceColor =
177 ::vcl::unotools::colorToDoubleSequence( mpCanvas->getUNOCanvas()->getDevice(),
178 ::Color( 0x80FF0000 ) );
180 if( maState.Clip.is() )
181 mpCanvas->getUNOCanvas()->fillPolyPolygon( maState.Clip,
182 mpCanvas->getViewState(),
183 aLocalState );
185 aLocalState.DeviceColor = maState.DeviceColor;
186 #endif
188 if( maFillColor.getLength() )
190 // TODO(E3): Use DBO's finalizer here,
191 // fillPolyPolygon() might throw
192 const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
193 aLocalState.DeviceColor = maFillColor;
195 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
196 mpCanvas->getViewState(),
197 aLocalState );
199 aLocalState.DeviceColor = aTmpColor;
202 if( aLocalState.DeviceColor.getLength() )
204 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
205 mpCanvas->getViewState(),
206 aLocalState );
209 return true;
212 bool PolyPolyAction::render( const ::basegfx::B2DHomMatrix& rTransformation,
213 const Subset& rSubset ) const
215 // TODO(F1): Split up poly-polygon into polygons, or even
216 // line segments, when subsets are requested.
218 // polygon only contains a single action, fail if subset
219 // requests different range
220 if( rSubset.mnSubsetBegin != 0 ||
221 rSubset.mnSubsetEnd != 1 )
222 return false;
224 return CachedPrimitiveBase::render( rTransformation );
227 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
229 rendering::RenderState aLocalState( maState );
230 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
232 return tools::calcDevicePixelBounds(
233 maBounds,
234 mpCanvas->getViewState(),
235 aLocalState );
238 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
239 const Subset& rSubset ) const
241 // TODO(F1): Split up poly-polygon into polygons, or even
242 // line segments, when subsets are requested.
244 // polygon only contains a single action, empty bounds
245 // if subset requests different range
246 if( rSubset.mnSubsetBegin != 0 ||
247 rSubset.mnSubsetEnd != 1 )
248 return ::basegfx::B2DRange();
250 return getBounds( rTransformation );
253 sal_Int32 PolyPolyAction::getActionCount() const
255 // TODO(F1): Split up poly-polygon into polygons, or even
256 // line segments, when subsets are requested.
257 return 1;
261 // -------------------------------------------------------------------------------
263 class TexturedPolyPolyAction : public CachedPrimitiveBase
265 public:
266 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
267 const CanvasSharedPtr& rCanvas,
268 const OutDevState& rState,
269 const rendering::Texture& rTexture );
271 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
272 const Subset& rSubset ) const;
274 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
275 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
276 const Subset& rSubset ) const;
278 virtual sal_Int32 getActionCount() const;
280 private:
281 using Action::render;
282 virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
283 const ::basegfx::B2DHomMatrix& rTransformation ) const;
285 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
286 const ::basegfx::B2DRectangle maBounds;
287 const CanvasSharedPtr mpCanvas;
289 // stroke color is now implicit: the maState.DeviceColor member
290 rendering::RenderState maState;
291 const rendering::Texture maTexture;
294 TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
295 const CanvasSharedPtr& rCanvas,
296 const OutDevState& rState,
297 const rendering::Texture& rTexture ) :
298 CachedPrimitiveBase( rCanvas, true ),
299 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
300 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
301 mpCanvas( rCanvas ),
302 maState(),
303 maTexture( rTexture )
305 tools::initRenderState(maState,rState);
308 bool TexturedPolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
309 const ::basegfx::B2DHomMatrix& rTransformation ) const
311 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" );
312 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
314 rendering::RenderState aLocalState( maState );
315 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
317 uno::Sequence< rendering::Texture > aSeq(1);
318 aSeq[0] = maTexture;
320 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
321 mpCanvas->getViewState(),
322 aLocalState,
323 aSeq );
324 return true;
327 bool TexturedPolyPolyAction::render( const ::basegfx::B2DHomMatrix& rTransformation,
328 const Subset& rSubset ) const
330 // TODO(F1): Split up poly-polygon into polygons, or even
331 // line segments, when subsets are requested.
333 // polygon only contains a single action, fail if subset
334 // requests different range
335 if( rSubset.mnSubsetBegin != 0 ||
336 rSubset.mnSubsetEnd != 1 )
337 return false;
339 return CachedPrimitiveBase::render( rTransformation );
342 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
344 rendering::RenderState aLocalState( maState );
345 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
347 return tools::calcDevicePixelBounds(
348 maBounds,
349 mpCanvas->getViewState(),
350 aLocalState );
353 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
354 const Subset& rSubset ) const
356 // TODO(F1): Split up poly-polygon into polygons, or even
357 // line segments, when subsets are requested.
359 // polygon only contains a single action, empty bounds
360 // if subset requests different range
361 if( rSubset.mnSubsetBegin != 0 ||
362 rSubset.mnSubsetEnd != 1 )
363 return ::basegfx::B2DRange();
365 return getBounds( rTransformation );
368 sal_Int32 TexturedPolyPolyAction::getActionCount() const
370 // TODO(F1): Split up poly-polygon into polygons, or even
371 // line segments, when subsets are requested.
372 return 1;
375 // -------------------------------------------------------------------------------
377 class StrokedPolyPolyAction : public CachedPrimitiveBase
379 public:
380 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
381 const CanvasSharedPtr& rCanvas,
382 const OutDevState& rState,
383 const rendering::StrokeAttributes& rStrokeAttributes );
385 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
386 const Subset& rSubset ) const;
388 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
389 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
390 const Subset& rSubset ) const;
392 virtual sal_Int32 getActionCount() const;
394 private:
395 using Action::render;
396 virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
397 const ::basegfx::B2DHomMatrix& rTransformation ) const;
399 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
400 const ::basegfx::B2DRectangle maBounds;
401 const CanvasSharedPtr mpCanvas;
402 rendering::RenderState maState;
403 const rendering::StrokeAttributes maStrokeAttributes;
406 StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
407 const CanvasSharedPtr& rCanvas,
408 const OutDevState& rState,
409 const rendering::StrokeAttributes& rStrokeAttributes ) :
410 CachedPrimitiveBase( rCanvas, false ),
411 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
412 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
413 mpCanvas( rCanvas ),
414 maState(),
415 maStrokeAttributes( rStrokeAttributes )
417 tools::initRenderState(maState,rState);
418 maState.DeviceColor = rState.lineColor;
421 bool StrokedPolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
422 const ::basegfx::B2DHomMatrix& rTransformation ) const
424 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" );
425 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
427 rendering::RenderState aLocalState( maState );
428 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
430 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
431 mpCanvas->getViewState(),
432 aLocalState,
433 maStrokeAttributes );
434 return true;
437 bool StrokedPolyPolyAction::render( const ::basegfx::B2DHomMatrix& rTransformation,
438 const Subset& rSubset ) const
440 // TODO(F1): Split up poly-polygon into polygons, or even
441 // line segments, when subsets are requested.
443 // polygon only contains a single action, fail if subset
444 // requests different range
445 if( rSubset.mnSubsetBegin != 0 ||
446 rSubset.mnSubsetEnd != 1 )
447 return false;
449 return CachedPrimitiveBase::render( rTransformation );
452 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
454 rendering::RenderState aLocalState( maState );
455 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
457 return tools::calcDevicePixelBounds(
458 maBounds,
459 mpCanvas->getViewState(),
460 aLocalState );
463 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
464 const Subset& rSubset ) const
466 // TODO(F1): Split up poly-polygon into polygons, or even
467 // line segments, when subsets are requested.
469 // polygon only contains a single action, empty bounds
470 // if subset requests different range
471 if( rSubset.mnSubsetBegin != 0 ||
472 rSubset.mnSubsetEnd != 1 )
473 return ::basegfx::B2DRange();
475 return getBounds( rTransformation );
478 sal_Int32 StrokedPolyPolyAction::getActionCount() const
480 // TODO(F1): Split up poly-polygon into polygons, or even
481 // line segments, when subsets are requested.
482 return 1;
486 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
487 const CanvasSharedPtr& rCanvas,
488 const OutDevState& rState )
490 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
491 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
492 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
493 rState.isFillColorSet,
494 rState.isLineColorSet ) );
497 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
498 const CanvasSharedPtr& rCanvas,
499 const OutDevState& rState,
500 const rendering::Texture& rTexture )
502 return ActionSharedPtr( new TexturedPolyPolyAction( rPoly, rCanvas, rState, rTexture ) );
505 ActionSharedPtr PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
506 const CanvasSharedPtr& rCanvas,
507 const OutDevState& rState )
509 OSL_ENSURE( rState.isLineColorSet,
510 "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
512 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
513 false,
514 rState.isLineColorSet ) );
517 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
518 const CanvasSharedPtr& rCanvas,
519 const OutDevState& rState,
520 const rendering::StrokeAttributes& rStrokeAttributes )
522 OSL_ENSURE( rState.isLineColorSet,
523 "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
524 return ActionSharedPtr( new StrokedPolyPolyAction( rPoly, rCanvas, rState, rStrokeAttributes ) );
527 ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
528 const CanvasSharedPtr& rCanvas,
529 const OutDevState& rState,
530 int nTransparency )
532 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
533 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
534 return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
535 rState.isFillColorSet,
536 rState.isLineColorSet,
537 nTransparency ) );