1*25b11142SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*25b11142SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*25b11142SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*25b11142SAndrew Rist  * distributed with this work for additional information
6*25b11142SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*25b11142SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*25b11142SAndrew Rist  * "License"); you may not use this file except in compliance
9*25b11142SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*25b11142SAndrew Rist  *
11*25b11142SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*25b11142SAndrew Rist  *
13*25b11142SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*25b11142SAndrew Rist  * software distributed under the License is distributed on an
15*25b11142SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*25b11142SAndrew Rist  * KIND, either express or implied.  See the License for the
17*25b11142SAndrew Rist  * specific language governing permissions and limitations
18*25b11142SAndrew Rist  * under the License.
19*25b11142SAndrew Rist  *
20*25b11142SAndrew Rist  *************************************************************/
21*25b11142SAndrew Rist 
22*25b11142SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_cppcanvas.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <rtl/logfile.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <com/sun/star/rendering/XCanvas.hpp>
30cdf0e10cSrcweir #include <com/sun/star/rendering/TexturingMode.hpp>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <tools/gen.hxx>
33cdf0e10cSrcweir #include <vcl/canvastools.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <basegfx/range/b2drectangle.hxx>
36cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
37cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
38cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
39cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
40cdf0e10cSrcweir #include <canvas/canvastools.hxx>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <boost/utility.hpp>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir #include "cachedprimitivebase.hxx"
45cdf0e10cSrcweir #include "polypolyaction.hxx"
46cdf0e10cSrcweir #include "outdevstate.hxx"
47cdf0e10cSrcweir #include "mtftools.hxx"
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 
50cdf0e10cSrcweir using namespace ::com::sun::star;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir namespace cppcanvas
53cdf0e10cSrcweir {
54cdf0e10cSrcweir     namespace internal
55cdf0e10cSrcweir     {
56cdf0e10cSrcweir         namespace
57cdf0e10cSrcweir         {
58cdf0e10cSrcweir             class PolyPolyAction : public CachedPrimitiveBase
59cdf0e10cSrcweir             {
60cdf0e10cSrcweir             public:
61cdf0e10cSrcweir                 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
62cdf0e10cSrcweir                                 const CanvasSharedPtr&,
63cdf0e10cSrcweir                                 const OutDevState&,
64cdf0e10cSrcweir                                 bool bFill,
65cdf0e10cSrcweir                                 bool bStroke );
66cdf0e10cSrcweir                 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
67cdf0e10cSrcweir                                 const CanvasSharedPtr&,
68cdf0e10cSrcweir                                 const OutDevState&,
69cdf0e10cSrcweir                                 bool bFill,
70cdf0e10cSrcweir                                 bool bStroke,
71cdf0e10cSrcweir                                 int nTransparency );
72cdf0e10cSrcweir 
73cdf0e10cSrcweir                 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
74cdf0e10cSrcweir                                      const Subset&					rSubset ) const;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
77cdf0e10cSrcweir                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
78cdf0e10cSrcweir                                                        const Subset&					rSubset ) const;
79cdf0e10cSrcweir 
80cdf0e10cSrcweir                 virtual sal_Int32 getActionCount() const;
81cdf0e10cSrcweir 
82cdf0e10cSrcweir             private:
83cdf0e10cSrcweir                 using Action::render;
84cdf0e10cSrcweir                 virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
85cdf0e10cSrcweir                                      const ::basegfx::B2DHomMatrix&                 rTransformation ) const;
86cdf0e10cSrcweir 
87cdf0e10cSrcweir                 const uno::Reference< rendering::XPolyPolygon2D > 	mxPolyPoly;
88cdf0e10cSrcweir                 const ::basegfx::B2DRange							maBounds;
89cdf0e10cSrcweir                 const CanvasSharedPtr								mpCanvas;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir             	// stroke color is now implicit: the maState.DeviceColor member
92cdf0e10cSrcweir                 rendering::RenderState								maState;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir                 uno::Sequence< double >								maFillColor;
95cdf0e10cSrcweir             };
96cdf0e10cSrcweir 
PolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,bool bFill,bool bStroke)97cdf0e10cSrcweir             PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon&	rPolyPoly,
98cdf0e10cSrcweir                                             const CanvasSharedPtr&              rCanvas,
99cdf0e10cSrcweir                                             const OutDevState&                  rState,
100cdf0e10cSrcweir                                             bool                                bFill,
101cdf0e10cSrcweir                                             bool                                bStroke ) :
102cdf0e10cSrcweir                 CachedPrimitiveBase( rCanvas, false ),
103cdf0e10cSrcweir                 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
104cdf0e10cSrcweir                 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
105cdf0e10cSrcweir                 mpCanvas( rCanvas ),
106cdf0e10cSrcweir                 maState(),
107cdf0e10cSrcweir                 maFillColor()
108cdf0e10cSrcweir             {
109cdf0e10cSrcweir                 tools::initRenderState(maState,rState);
110cdf0e10cSrcweir 
111cdf0e10cSrcweir                 if( bFill )
112cdf0e10cSrcweir                     maFillColor = rState.fillColor;
113cdf0e10cSrcweir 
114cdf0e10cSrcweir                 if( bStroke )
115cdf0e10cSrcweir                     maState.DeviceColor = rState.lineColor;
116cdf0e10cSrcweir             }
117cdf0e10cSrcweir 
PolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,bool bFill,bool bStroke,int nTransparency)118cdf0e10cSrcweir             PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon&	rPolyPoly,
119cdf0e10cSrcweir                                             const CanvasSharedPtr&              rCanvas,
120cdf0e10cSrcweir                                             const OutDevState&                  rState,
121cdf0e10cSrcweir                                             bool                                bFill,
122cdf0e10cSrcweir                                             bool                                bStroke,
123cdf0e10cSrcweir                                             int                                 nTransparency ) :
124cdf0e10cSrcweir                 CachedPrimitiveBase( rCanvas, false ),
125cdf0e10cSrcweir                 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
126cdf0e10cSrcweir                 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
127cdf0e10cSrcweir                 mpCanvas( rCanvas ),
128cdf0e10cSrcweir                 maState(),
129cdf0e10cSrcweir                 maFillColor()
130cdf0e10cSrcweir             {
131cdf0e10cSrcweir                 tools::initRenderState(maState,rState);
132cdf0e10cSrcweir 
133cdf0e10cSrcweir                 if( bFill )
134cdf0e10cSrcweir                 {
135cdf0e10cSrcweir                     maFillColor = rState.fillColor;
136cdf0e10cSrcweir 
137cdf0e10cSrcweir                     if( maFillColor.getLength() < 4 )
138cdf0e10cSrcweir                         maFillColor.realloc( 4 );
139cdf0e10cSrcweir 
140cdf0e10cSrcweir                     // TODO(F1): Color management
141cdf0e10cSrcweir                     // adapt fill color transparency
142cdf0e10cSrcweir                     maFillColor[3] = 1.0 - nTransparency / 100.0;
143cdf0e10cSrcweir                 }
144cdf0e10cSrcweir 
145cdf0e10cSrcweir                 if( bStroke )
146cdf0e10cSrcweir                 {
147cdf0e10cSrcweir                     maState.DeviceColor = rState.lineColor;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir                     if( maState.DeviceColor.getLength() < 4 )
150cdf0e10cSrcweir                         maState.DeviceColor.realloc( 4 );
151cdf0e10cSrcweir 
152cdf0e10cSrcweir                     // TODO(F1): Color management
153cdf0e10cSrcweir                     // adapt fill color transparency
154cdf0e10cSrcweir                     maState.DeviceColor[3] = 1.0 - nTransparency / 100.0;
155cdf0e10cSrcweir                 }
156cdf0e10cSrcweir             }
157cdf0e10cSrcweir 
render(uno::Reference<rendering::XCachedPrimitive> & rCachedPrimitive,const::basegfx::B2DHomMatrix & rTransformation) const158cdf0e10cSrcweir             bool PolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
159cdf0e10cSrcweir                                          const ::basegfx::B2DHomMatrix&                 rTransformation ) const
160cdf0e10cSrcweir             {
161cdf0e10cSrcweir                 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" );
162cdf0e10cSrcweir                 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
163cdf0e10cSrcweir 
164cdf0e10cSrcweir                 rendering::RenderState aLocalState( maState );
165cdf0e10cSrcweir                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
166cdf0e10cSrcweir 
167cdf0e10cSrcweir #ifdef SPECIAL_DEBUG
168cdf0e10cSrcweir                 aLocalState.Clip.clear();
169cdf0e10cSrcweir                 aLocalState.DeviceColor =
170cdf0e10cSrcweir                     ::vcl::unotools::colorToDoubleSequence( mpCanvas->getUNOCanvas()->getDevice(),
171cdf0e10cSrcweir                                                             ::Color( 0x80FF0000 ) );
172cdf0e10cSrcweir 
173cdf0e10cSrcweir                 if( maState.Clip.is() )
174cdf0e10cSrcweir                     mpCanvas->getUNOCanvas()->fillPolyPolygon( maState.Clip,
175cdf0e10cSrcweir                                                                mpCanvas->getViewState(),
176cdf0e10cSrcweir                                                                aLocalState );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir                 aLocalState.DeviceColor = maState.DeviceColor;
179cdf0e10cSrcweir #endif
180cdf0e10cSrcweir 
181cdf0e10cSrcweir                 if( maFillColor.getLength() )
182cdf0e10cSrcweir                 {
183cdf0e10cSrcweir                     // TODO(E3): Use DBO's finalizer here,
184cdf0e10cSrcweir                     // fillPolyPolygon() might throw
185cdf0e10cSrcweir                     const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
186cdf0e10cSrcweir                     aLocalState.DeviceColor = maFillColor;
187cdf0e10cSrcweir 
188cdf0e10cSrcweir                     rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
189cdf0e10cSrcweir                                                                                   mpCanvas->getViewState(),
190cdf0e10cSrcweir                                                                                   aLocalState );
191cdf0e10cSrcweir 
192cdf0e10cSrcweir                     aLocalState.DeviceColor = aTmpColor;
193cdf0e10cSrcweir                 }
194cdf0e10cSrcweir 
195cdf0e10cSrcweir                 if( aLocalState.DeviceColor.getLength() )
196cdf0e10cSrcweir                 {
197cdf0e10cSrcweir                     rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
198cdf0e10cSrcweir                                                                                   mpCanvas->getViewState(),
199cdf0e10cSrcweir                                                                                   aLocalState );
200cdf0e10cSrcweir                 }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir                 return true;
203cdf0e10cSrcweir             }
204cdf0e10cSrcweir 
render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const205cdf0e10cSrcweir             bool PolyPolyAction::render( const ::basegfx::B2DHomMatrix&	rTransformation,
206cdf0e10cSrcweir                                          const Subset&					rSubset ) const
207cdf0e10cSrcweir             {
208cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
209cdf0e10cSrcweir                 // line segments, when subsets are requested.
210cdf0e10cSrcweir 
211cdf0e10cSrcweir                 // polygon only contains a single action, fail if subset
212cdf0e10cSrcweir                 // requests different range
213cdf0e10cSrcweir                 if( rSubset.mnSubsetBegin != 0 ||
214cdf0e10cSrcweir                     rSubset.mnSubsetEnd != 1 )
215cdf0e10cSrcweir                     return false;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir                 return CachedPrimitiveBase::render( rTransformation );
218cdf0e10cSrcweir             }
219cdf0e10cSrcweir 
getBounds(const::basegfx::B2DHomMatrix & rTransformation) const220cdf0e10cSrcweir             ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation ) const
221cdf0e10cSrcweir             {
222cdf0e10cSrcweir                 rendering::RenderState aLocalState( maState );
223cdf0e10cSrcweir                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
224cdf0e10cSrcweir 
225cdf0e10cSrcweir                 return tools::calcDevicePixelBounds(
226cdf0e10cSrcweir                     maBounds,
227cdf0e10cSrcweir                     mpCanvas->getViewState(),
228cdf0e10cSrcweir                     aLocalState );
229cdf0e10cSrcweir             }
230cdf0e10cSrcweir 
getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const231cdf0e10cSrcweir             ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
232cdf0e10cSrcweir                                                            const Subset&					rSubset ) const
233cdf0e10cSrcweir             {
234cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
235cdf0e10cSrcweir                 // line segments, when subsets are requested.
236cdf0e10cSrcweir 
237cdf0e10cSrcweir                 // polygon only contains a single action, empty bounds
238cdf0e10cSrcweir                 // if subset requests different range
239cdf0e10cSrcweir                 if( rSubset.mnSubsetBegin != 0 ||
240cdf0e10cSrcweir                     rSubset.mnSubsetEnd != 1 )
241cdf0e10cSrcweir                     return ::basegfx::B2DRange();
242cdf0e10cSrcweir 
243cdf0e10cSrcweir                 return getBounds( rTransformation );
244cdf0e10cSrcweir             }
245cdf0e10cSrcweir 
getActionCount() const246cdf0e10cSrcweir             sal_Int32 PolyPolyAction::getActionCount() const
247cdf0e10cSrcweir             {
248cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
249cdf0e10cSrcweir                 // line segments, when subsets are requested.
250cdf0e10cSrcweir                 return 1;
251cdf0e10cSrcweir             }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 
254cdf0e10cSrcweir             // -------------------------------------------------------------------------------
255cdf0e10cSrcweir 
256cdf0e10cSrcweir             class TexturedPolyPolyAction : public CachedPrimitiveBase
257cdf0e10cSrcweir             {
258cdf0e10cSrcweir             public:
259cdf0e10cSrcweir                 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
260cdf0e10cSrcweir                                         const CanvasSharedPtr&		     rCanvas,
261cdf0e10cSrcweir                                         const OutDevState&			     rState,
262cdf0e10cSrcweir                                         const rendering::Texture& 	     rTexture );
263cdf0e10cSrcweir 
264cdf0e10cSrcweir                 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
265cdf0e10cSrcweir                                      const Subset&					rSubset ) const;
266cdf0e10cSrcweir 
267cdf0e10cSrcweir                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
268cdf0e10cSrcweir                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
269cdf0e10cSrcweir                                                        const Subset&					rSubset ) const;
270cdf0e10cSrcweir 
271cdf0e10cSrcweir                 virtual sal_Int32 getActionCount() const;
272cdf0e10cSrcweir 
273cdf0e10cSrcweir             private:
274cdf0e10cSrcweir                 using Action::render;
275cdf0e10cSrcweir                 virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
276cdf0e10cSrcweir                                      const ::basegfx::B2DHomMatrix&                 rTransformation ) const;
277cdf0e10cSrcweir 
278cdf0e10cSrcweir                 const uno::Reference< rendering::XPolyPolygon2D >	mxPolyPoly;
279cdf0e10cSrcweir                 const ::basegfx::B2DRectangle						maBounds;
280cdf0e10cSrcweir                 const CanvasSharedPtr								mpCanvas;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir             	// stroke color is now implicit: the maState.DeviceColor member
283cdf0e10cSrcweir                 rendering::RenderState								maState;
284cdf0e10cSrcweir                 const rendering::Texture							maTexture;
285cdf0e10cSrcweir             };
286cdf0e10cSrcweir 
TexturedPolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::Texture & rTexture)287cdf0e10cSrcweir             TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
288cdf0e10cSrcweir                                                             const CanvasSharedPtr&		     rCanvas,
289cdf0e10cSrcweir                                                             const OutDevState& 			     rState,
290cdf0e10cSrcweir                                                             const rendering::Texture& 	     rTexture ) :
291cdf0e10cSrcweir                 CachedPrimitiveBase( rCanvas, true ),
292cdf0e10cSrcweir                 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
293cdf0e10cSrcweir                 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
294cdf0e10cSrcweir                 mpCanvas( rCanvas ),
295cdf0e10cSrcweir                 maState(),
296cdf0e10cSrcweir                 maTexture( rTexture )
297cdf0e10cSrcweir             {
298cdf0e10cSrcweir                 tools::initRenderState(maState,rState);
299cdf0e10cSrcweir             }
300cdf0e10cSrcweir 
render(uno::Reference<rendering::XCachedPrimitive> & rCachedPrimitive,const::basegfx::B2DHomMatrix & rTransformation) const301cdf0e10cSrcweir             bool TexturedPolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
302cdf0e10cSrcweir                                                  const ::basegfx::B2DHomMatrix&                 rTransformation ) const
303cdf0e10cSrcweir             {
304cdf0e10cSrcweir                 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" );
305cdf0e10cSrcweir                 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
306cdf0e10cSrcweir 
307cdf0e10cSrcweir                 rendering::RenderState aLocalState( maState );
308cdf0e10cSrcweir                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
309cdf0e10cSrcweir 
310cdf0e10cSrcweir                 uno::Sequence< rendering::Texture > aSeq(1);
311cdf0e10cSrcweir                 aSeq[0] = maTexture;
312cdf0e10cSrcweir 
313cdf0e10cSrcweir                 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
314cdf0e10cSrcweir                                                                                       mpCanvas->getViewState(),
315cdf0e10cSrcweir                                                                                       aLocalState,
316cdf0e10cSrcweir                                                                                       aSeq );
317cdf0e10cSrcweir                 return true;
318cdf0e10cSrcweir             }
319cdf0e10cSrcweir 
render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const320cdf0e10cSrcweir             bool TexturedPolyPolyAction::render( const ::basegfx::B2DHomMatrix&	rTransformation,
321cdf0e10cSrcweir                                                  const Subset&					rSubset ) const
322cdf0e10cSrcweir             {
323cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
324cdf0e10cSrcweir                 // line segments, when subsets are requested.
325cdf0e10cSrcweir 
326cdf0e10cSrcweir                 // polygon only contains a single action, fail if subset
327cdf0e10cSrcweir                 // requests different range
328cdf0e10cSrcweir                 if( rSubset.mnSubsetBegin != 0 ||
329cdf0e10cSrcweir                     rSubset.mnSubsetEnd != 1 )
330cdf0e10cSrcweir                     return false;
331cdf0e10cSrcweir 
332cdf0e10cSrcweir                 return CachedPrimitiveBase::render( rTransformation );
333cdf0e10cSrcweir             }
334cdf0e10cSrcweir 
getBounds(const::basegfx::B2DHomMatrix & rTransformation) const335cdf0e10cSrcweir             ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation ) const
336cdf0e10cSrcweir             {
337cdf0e10cSrcweir                 rendering::RenderState aLocalState( maState );
338cdf0e10cSrcweir                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
339cdf0e10cSrcweir 
340cdf0e10cSrcweir                 return tools::calcDevicePixelBounds(
341cdf0e10cSrcweir                     maBounds,
342cdf0e10cSrcweir                     mpCanvas->getViewState(),
343cdf0e10cSrcweir                     aLocalState );
344cdf0e10cSrcweir             }
345cdf0e10cSrcweir 
getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const346cdf0e10cSrcweir             ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
347cdf0e10cSrcweir                                                                    const Subset&					rSubset ) const
348cdf0e10cSrcweir             {
349cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
350cdf0e10cSrcweir                 // line segments, when subsets are requested.
351cdf0e10cSrcweir 
352cdf0e10cSrcweir                 // polygon only contains a single action, empty bounds
353cdf0e10cSrcweir                 // if subset requests different range
354cdf0e10cSrcweir                 if( rSubset.mnSubsetBegin != 0 ||
355cdf0e10cSrcweir                     rSubset.mnSubsetEnd != 1 )
356cdf0e10cSrcweir                     return ::basegfx::B2DRange();
357cdf0e10cSrcweir 
358cdf0e10cSrcweir                 return getBounds( rTransformation );
359cdf0e10cSrcweir             }
360cdf0e10cSrcweir 
getActionCount() const361cdf0e10cSrcweir             sal_Int32 TexturedPolyPolyAction::getActionCount() const
362cdf0e10cSrcweir             {
363cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
364cdf0e10cSrcweir                 // line segments, when subsets are requested.
365cdf0e10cSrcweir                 return 1;
366cdf0e10cSrcweir             }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir             // -------------------------------------------------------------------------------
369cdf0e10cSrcweir 
370cdf0e10cSrcweir             class StrokedPolyPolyAction : public CachedPrimitiveBase
371cdf0e10cSrcweir             {
372cdf0e10cSrcweir             public:
373cdf0e10cSrcweir                 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon&     rPoly,
374cdf0e10cSrcweir                                        const CanvasSharedPtr&				rCanvas,
375cdf0e10cSrcweir                                        const OutDevState&					rState,
376cdf0e10cSrcweir                                        const rendering::StrokeAttributes&	rStrokeAttributes );
377cdf0e10cSrcweir 
378cdf0e10cSrcweir                 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
379cdf0e10cSrcweir                                      const Subset&					rSubset ) const;
380cdf0e10cSrcweir 
381cdf0e10cSrcweir                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
382cdf0e10cSrcweir                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
383cdf0e10cSrcweir                                                        const Subset&					rSubset ) const;
384cdf0e10cSrcweir 
385cdf0e10cSrcweir                 virtual sal_Int32 getActionCount() const;
386cdf0e10cSrcweir 
387cdf0e10cSrcweir             private:
388cdf0e10cSrcweir                 using Action::render;
389cdf0e10cSrcweir                 virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
390cdf0e10cSrcweir                                      const ::basegfx::B2DHomMatrix&                 rTransformation ) const;
391cdf0e10cSrcweir 
392cdf0e10cSrcweir                 const uno::Reference< rendering::XPolyPolygon2D >	mxPolyPoly;
393cdf0e10cSrcweir                 const ::basegfx::B2DRectangle						maBounds;
394cdf0e10cSrcweir                 const CanvasSharedPtr								mpCanvas;
395cdf0e10cSrcweir                 rendering::RenderState								maState;
396cdf0e10cSrcweir                 const rendering::StrokeAttributes					maStrokeAttributes;
397cdf0e10cSrcweir             };
398cdf0e10cSrcweir 
StrokedPolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::StrokeAttributes & rStrokeAttributes)399cdf0e10cSrcweir             StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon&      rPolyPoly,
400cdf0e10cSrcweir                                                           const CanvasSharedPtr&				rCanvas,
401cdf0e10cSrcweir                                                           const OutDevState& 					rState,
402cdf0e10cSrcweir                                                           const rendering::StrokeAttributes&	rStrokeAttributes ) :
403cdf0e10cSrcweir                 CachedPrimitiveBase( rCanvas, false ),
404cdf0e10cSrcweir                 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
405cdf0e10cSrcweir                 maBounds( ::basegfx::tools::getRange(rPolyPoly) ),
406cdf0e10cSrcweir                 mpCanvas( rCanvas ),
407cdf0e10cSrcweir                 maState(),
408cdf0e10cSrcweir                 maStrokeAttributes( rStrokeAttributes )
409cdf0e10cSrcweir             {
410cdf0e10cSrcweir                 tools::initRenderState(maState,rState);
411cdf0e10cSrcweir                 maState.DeviceColor = rState.lineColor;
412cdf0e10cSrcweir             }
413cdf0e10cSrcweir 
render(uno::Reference<rendering::XCachedPrimitive> & rCachedPrimitive,const::basegfx::B2DHomMatrix & rTransformation) const414cdf0e10cSrcweir             bool StrokedPolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
415cdf0e10cSrcweir                                                 const ::basegfx::B2DHomMatrix&                 rTransformation ) const
416cdf0e10cSrcweir             {
417cdf0e10cSrcweir                 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" );
418cdf0e10cSrcweir                 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this );
419cdf0e10cSrcweir 
420cdf0e10cSrcweir                 rendering::RenderState aLocalState( maState );
421cdf0e10cSrcweir                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
422cdf0e10cSrcweir 
423cdf0e10cSrcweir                 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
424cdf0e10cSrcweir                                                                                 mpCanvas->getViewState(),
425cdf0e10cSrcweir                                                                                 aLocalState,
426cdf0e10cSrcweir                                                                                 maStrokeAttributes );
427cdf0e10cSrcweir                 return true;
428cdf0e10cSrcweir             }
429cdf0e10cSrcweir 
render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const430cdf0e10cSrcweir             bool StrokedPolyPolyAction::render( const ::basegfx::B2DHomMatrix&	rTransformation,
431cdf0e10cSrcweir                                                 const Subset&					rSubset ) const
432cdf0e10cSrcweir             {
433cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
434cdf0e10cSrcweir                 // line segments, when subsets are requested.
435cdf0e10cSrcweir 
436cdf0e10cSrcweir                 // polygon only contains a single action, fail if subset
437cdf0e10cSrcweir                 // requests different range
438cdf0e10cSrcweir                 if( rSubset.mnSubsetBegin != 0 ||
439cdf0e10cSrcweir                     rSubset.mnSubsetEnd != 1 )
440cdf0e10cSrcweir                     return false;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir                 return CachedPrimitiveBase::render( rTransformation );
443cdf0e10cSrcweir             }
444cdf0e10cSrcweir 
getBounds(const::basegfx::B2DHomMatrix & rTransformation) const445cdf0e10cSrcweir             ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation ) const
446cdf0e10cSrcweir             {
447cdf0e10cSrcweir                 rendering::RenderState aLocalState( maState );
448cdf0e10cSrcweir                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
449cdf0e10cSrcweir 
450cdf0e10cSrcweir                 return tools::calcDevicePixelBounds(
451cdf0e10cSrcweir                     maBounds,
452cdf0e10cSrcweir                     mpCanvas->getViewState(),
453cdf0e10cSrcweir                     aLocalState );
454cdf0e10cSrcweir             }
455cdf0e10cSrcweir 
getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const456cdf0e10cSrcweir             ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
457cdf0e10cSrcweir                                                                   const Subset&					rSubset ) const
458cdf0e10cSrcweir             {
459cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
460cdf0e10cSrcweir                 // line segments, when subsets are requested.
461cdf0e10cSrcweir 
462cdf0e10cSrcweir                 // polygon only contains a single action, empty bounds
463cdf0e10cSrcweir                 // if subset requests different range
464cdf0e10cSrcweir                 if( rSubset.mnSubsetBegin != 0 ||
465cdf0e10cSrcweir                     rSubset.mnSubsetEnd != 1 )
466cdf0e10cSrcweir                     return ::basegfx::B2DRange();
467cdf0e10cSrcweir 
468cdf0e10cSrcweir                 return getBounds( rTransformation );
469cdf0e10cSrcweir             }
470cdf0e10cSrcweir 
getActionCount() const471cdf0e10cSrcweir             sal_Int32 StrokedPolyPolyAction::getActionCount() const
472cdf0e10cSrcweir             {
473cdf0e10cSrcweir                 // TODO(F1): Split up poly-polygon into polygons, or even
474cdf0e10cSrcweir                 // line segments, when subsets are requested.
475cdf0e10cSrcweir                 return 1;
476cdf0e10cSrcweir             }
477cdf0e10cSrcweir         }
478cdf0e10cSrcweir 
createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState)479cdf0e10cSrcweir         ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
480cdf0e10cSrcweir                                                                      const CanvasSharedPtr&           rCanvas,
481cdf0e10cSrcweir                                                                      const OutDevState&               rState	)
482cdf0e10cSrcweir         {
483cdf0e10cSrcweir             OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
484cdf0e10cSrcweir                         "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
485cdf0e10cSrcweir             return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
486cdf0e10cSrcweir                                                         rState.isFillColorSet,
487cdf0e10cSrcweir                                                         rState.isLineColorSet ) );
488cdf0e10cSrcweir         }
489cdf0e10cSrcweir 
createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::Texture & rTexture)490cdf0e10cSrcweir         ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon&   rPoly,
491cdf0e10cSrcweir                                                                      const CanvasSharedPtr&             rCanvas,
492cdf0e10cSrcweir                                                                      const OutDevState&                 rState,
493cdf0e10cSrcweir                                                                      const rendering::Texture&          rTexture )
494cdf0e10cSrcweir         {
495cdf0e10cSrcweir             return ActionSharedPtr( new TexturedPolyPolyAction( rPoly, rCanvas, rState, rTexture ) );
496cdf0e10cSrcweir         }
497cdf0e10cSrcweir 
createLinePolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState)498cdf0e10cSrcweir         ActionSharedPtr PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
499cdf0e10cSrcweir                                                                          const CanvasSharedPtr&           rCanvas,
500cdf0e10cSrcweir                                                                          const OutDevState&               rState )
501cdf0e10cSrcweir         {
502cdf0e10cSrcweir             OSL_ENSURE( rState.isLineColorSet,
503cdf0e10cSrcweir                         "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
504cdf0e10cSrcweir 
505cdf0e10cSrcweir             return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
506cdf0e10cSrcweir                                                         false,
507cdf0e10cSrcweir                                                         rState.isLineColorSet ) );
508cdf0e10cSrcweir         }
509cdf0e10cSrcweir 
createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::StrokeAttributes & rStrokeAttributes)510cdf0e10cSrcweir         ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon&   rPoly,
511cdf0e10cSrcweir                                                                      const CanvasSharedPtr&				rCanvas,
512cdf0e10cSrcweir                                                                      const OutDevState&					rState,
513cdf0e10cSrcweir                                                                      const rendering::StrokeAttributes& rStrokeAttributes )
514cdf0e10cSrcweir         {
515cdf0e10cSrcweir             OSL_ENSURE( rState.isLineColorSet,
516cdf0e10cSrcweir                         "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
517cdf0e10cSrcweir             return ActionSharedPtr( new StrokedPolyPolyAction( rPoly, rCanvas, rState, rStrokeAttributes ) );
518cdf0e10cSrcweir         }
519cdf0e10cSrcweir 
createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,int nTransparency)520cdf0e10cSrcweir         ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
521cdf0e10cSrcweir                                                                      const CanvasSharedPtr&           rCanvas,
522cdf0e10cSrcweir                                                                      const OutDevState&               rState,
523cdf0e10cSrcweir                                                                      int                              nTransparency 	)
524cdf0e10cSrcweir         {
525cdf0e10cSrcweir             OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
526cdf0e10cSrcweir                         "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
527cdf0e10cSrcweir             return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState,
528cdf0e10cSrcweir                                                         rState.isFillColorSet,
529cdf0e10cSrcweir                                                         rState.isLineColorSet,
530cdf0e10cSrcweir                                                         nTransparency ) );
531cdf0e10cSrcweir         }
532cdf0e10cSrcweir 
533cdf0e10cSrcweir     }
534cdf0e10cSrcweir }
535