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