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 <tools/gen.hxx>
28 
29 #include <canvas/debug.hxx>
30 #include <canvas/verbosetrace.hxx>
31 #include <canvas/canvastools.hxx>
32 
33 #include <rtl/logfile.hxx>
34 
35 #include <com/sun/star/rendering/XBitmap.hpp>
36 #include <com/sun/star/rendering/XCanvas.hpp>
37 
38 #include <rtl/math.hxx>
39 
40 #include <vcl/metaact.hxx>
41 #include <vcl/bitmapex.hxx>
42 #include <vcl/canvastools.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/outdev.hxx>
45 #include <vcl/virdev.hxx>
46 #include <vcl/virdev.hxx>
47 #include <vcl/gdimtf.hxx>
48 #include <vcl/gradient.hxx>
49 
50 #include <canvas/canvastools.hxx>
51 
52 #include <basegfx/range/b2drange.hxx>
53 #include <basegfx/point/b2dpoint.hxx>
54 #include <basegfx/vector/b2dsize.hxx>
55 #include <basegfx/numeric/ftools.hxx>
56 #include <basegfx/matrix/b2dhommatrix.hxx>
57 #include <basegfx/tuple/b2dtuple.hxx>
58 #include <basegfx/tools/canvastools.hxx>
59 
60 #include <boost/utility.hpp>
61 
62 #include "transparencygroupaction.hxx"
63 #include "outdevstate.hxx"
64 #include "mtftools.hxx"
65 #include "cppcanvas/vclfactory.hxx"
66 
67 
68 using namespace ::com::sun::star;
69 
70 namespace cppcanvas
71 {
72     namespace internal
73     {
74 		// free support functions
75 		// ======================
76         namespace
77         {
78             class TransparencyGroupAction : public Action, private ::boost::noncopyable
79             {
80             public:
81                 /** Create new transparency group action.
82 
83         	    	@param rGroupMtf
84                     Metafile that groups all actions to be rendered
85                     transparent
86 
87                     @param rParms
88                     Render parameters
89 
90                     @param rDstPoint
91                     Left, top edge of destination, in current state
92                     coordinate system
93 
94                     @param rDstSize
95                     Size of the transparency group object, in current
96                     state coordinate system.
97 
98                     @param nAlpha
99                     Alpha value, must be in the range [0,1]
100                 */
101                 TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
102                                          const Renderer::Parameters& 	rParms,
103                                          const ::basegfx::B2DPoint& 	rDstPoint,
104                                          const ::basegfx::B2DVector& 	rDstSize,
105                                          double 						nAlpha,
106                                          const CanvasSharedPtr&			rCanvas,
107                                          const OutDevState& 			rState );
108 
109                 /** Create new transparency group action.
110 
111 	            	@param rGroupMtf
112                     Metafile that groups all actions to be rendered
113                     transparent.
114 
115                     @param rAlphaGradient
116                     VCL gradient, to be rendered into the action's alpha
117                     channel.
118 
119                     @param rParms
120                     Render parameters
121 
122                     @param rDstPoint
123                     Left, top edge of destination, in current state
124                     coordinate system
125 
126                     @param rDstSize
127                     Size of the transparency group object, in current
128                     state coordinate system.
129                 */
130                 TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
131                                          GradientAutoPtr&				rAlphaGradient,
132                                          const Renderer::Parameters& 	rParms,
133                                          const ::basegfx::B2DPoint& 	rDstPoint,
134                                          const ::basegfx::B2DVector& 	rDstSize,
135                                          const CanvasSharedPtr&			rCanvas,
136                                          const OutDevState& 			rState );
137 
138                 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation ) const;
139                 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
140                                      const Subset&					rSubset ) const;
141 
142                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
143                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
144                                                        const Subset&					rSubset ) const;
145 
146                 virtual sal_Int32 getActionCount() const;
147 
148             private:
149                 MtfAutoPtr											mpGroupMtf;
150                 GradientAutoPtr										mpAlphaGradient;
151 
152                 const Renderer::Parameters 							maParms;
153 
154                 const ::basegfx::B2DSize 							maDstSize;
155 
156                 mutable uno::Reference< rendering::XBitmap > 		mxBufferBitmap; // contains last rendered version
157                 mutable ::basegfx::B2DHomMatrix						maLastTransformation; // contains last active transformation
158                 mutable Subset										maLastSubset; // contains last effective subset
159 
160                 // transformation for
161                 // mxBufferBitmap content
162                 CanvasSharedPtr										mpCanvas;
163                 rendering::RenderState								maState;
164                 const double										mnAlpha;
165             };
166 
167 
168             /** Setup transformation such that the next render call is
169                 moved rPoint away, and scaled according to the ratio
170                 given by src and dst size.
171             */
implSetupTransform(rendering::RenderState & rRenderState,const::basegfx::B2DPoint & rDstPoint)172             void implSetupTransform( rendering::RenderState& 	rRenderState,
173                                      const ::basegfx::B2DPoint&	rDstPoint	)
174             {
175                 ::basegfx::B2DHomMatrix	aLocalTransformation;
176 
177                 aLocalTransformation.translate( rDstPoint.getX(),
178                                                 rDstPoint.getY() );
179                 ::canvas::tools::appendToRenderState( rRenderState,
180                                                       aLocalTransformation );
181             }
182 
TransparencyGroupAction(MtfAutoPtr & rGroupMtf,const Renderer::Parameters & rParms,const::basegfx::B2DPoint & rDstPoint,const::basegfx::B2DVector & rDstSize,double nAlpha,const CanvasSharedPtr & rCanvas,const OutDevState & rState)183             TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
184                                                               const Renderer::Parameters& 	rParms,
185                                                               const ::basegfx::B2DPoint& 	rDstPoint,
186                                                               const ::basegfx::B2DVector& 	rDstSize,
187                                                               double 						nAlpha,
188                                                               const CanvasSharedPtr&		rCanvas,
189                                                               const OutDevState& 			rState ) :
190                 mpGroupMtf( rGroupMtf ),
191                 mpAlphaGradient(),
192                 maParms( rParms ),
193                 maDstSize( rDstSize ),
194                 mxBufferBitmap(),
195                 maLastTransformation(),
196                 mpCanvas( rCanvas ),
197                 maState(),
198                 mnAlpha( nAlpha )
199             {
200                 tools::initRenderState(maState,rState);
201                 implSetupTransform( maState, rDstPoint );
202 
203                 // correct clip (which is relative to original transform)
204                 tools::modifyClip( maState,
205                                    rState,
206                                    rCanvas,
207                                    rDstPoint,
208                                    NULL,
209                                    NULL );
210 
211                 maLastSubset.mnSubsetBegin = 0;
212                 maLastSubset.mnSubsetEnd = -1;
213             }
214 
TransparencyGroupAction(MtfAutoPtr & rGroupMtf,GradientAutoPtr & rAlphaGradient,const Renderer::Parameters & rParms,const::basegfx::B2DPoint & rDstPoint,const::basegfx::B2DVector & rDstSize,const CanvasSharedPtr & rCanvas,const OutDevState & rState)215             TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
216                                                               GradientAutoPtr&				rAlphaGradient,
217                                                               const Renderer::Parameters& 	rParms,
218                                                               const ::basegfx::B2DPoint& 	rDstPoint,
219                                                               const ::basegfx::B2DVector& 	rDstSize,
220                                                               const CanvasSharedPtr&		rCanvas,
221                                                               const OutDevState& 			rState ) :
222                 mpGroupMtf( rGroupMtf ),
223                 mpAlphaGradient( rAlphaGradient ),
224                 maParms( rParms ),
225                 maDstSize( rDstSize ),
226                 mxBufferBitmap(),
227                 maLastTransformation(),
228                 mpCanvas( rCanvas ),
229                 maState(),
230                 mnAlpha( 1.0 )
231             {
232                 tools::initRenderState(maState,rState);
233                 implSetupTransform( maState, rDstPoint );
234 
235                 // correct clip (which is relative to original transform)
236                 tools::modifyClip( maState,
237                                    rState,
238                                    rCanvas,
239                                    rDstPoint,
240                                    NULL,
241                                    NULL );
242 
243                 maLastSubset.mnSubsetBegin = 0;
244                 maLastSubset.mnSubsetEnd = -1;
245             }
246 
247             // TODO(P3): The whole float transparency handling is a mess,
248             // this should be refactored. What's more, the old idea of
249             // having only internal 'metaactions', and not the original
250             // GDIMetaFile now looks a lot less attractive. Try to move
251             // into the direction of having a direct GDIMetaFile2XCanvas
252             // renderer, and maybe a separate metafile XCanvas
253             // implementation.
render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const254             bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix&	rTransformation,
255                                                   const Subset&						rSubset ) const
256             {
257                 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" );
258                 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this );
259 
260                 // determine overall transformation matrix (render, view,
261                 // and passed transformation)
262                 ::basegfx::B2DHomMatrix aTransform;
263                 ::canvas::tools::getRenderStateTransform( aTransform, maState );
264                 aTransform = rTransformation * aTransform;
265 
266                 ::basegfx::B2DHomMatrix aTotalTransform;
267                 ::canvas::tools::getViewStateTransform( aTotalTransform, mpCanvas->getViewState() );
268                 aTotalTransform = aTotalTransform * aTransform;
269 
270                 // since pure translational changes to the transformation
271                 // does not matter, remove them before comparing
272                 aTotalTransform.set( 0, 2, 0.0 );
273                 aTotalTransform.set( 1, 2, 0.0 );
274 
275                 // if there's no buffer bitmap, or as soon as the
276                 // total transformation changes, we've got to
277                 // re-render the bitmap
278                 if( !mxBufferBitmap.is() ||
279                     aTotalTransform != maLastTransformation ||
280                     rSubset.mnSubsetBegin != maLastSubset.mnSubsetBegin ||
281                     rSubset.mnSubsetEnd != maLastSubset.mnSubsetEnd )
282                 {
283                     DBG_TESTSOLARMUTEX();
284 
285                     // determine total scaling factor of the
286                     // transformation matrix - need to make the bitmap
287                     // large enough
288                     ::basegfx::B2DTuple aScale;
289                     ::basegfx::B2DTuple aTranslate;
290                     double				nRotate;
291                     double				nShearX;
292                     if( !aTotalTransform.decompose( aScale,
293                                                     aTranslate,
294                                                     nRotate,
295                                                     nShearX ) )
296                     {
297                         OSL_ENSURE( false,
298                                     "TransparencyGroupAction::render(): non-decomposable transformation" );
299                         return false;
300                     }
301 
302                     // output size of metafile
303                     ::Size aOutputSizePixel( ::basegfx::fround( aScale.getX() * maDstSize.getX() ),
304                                              ::basegfx::fround( aScale.getY() * maDstSize.getY() ) );
305 
306                     // pixel size of cache bitmap: round up to nearest int
307                     ::Size aBitmapSizePixel( static_cast<sal_Int32>( aScale.getX() * maDstSize.getX() )+1,
308                                              static_cast<sal_Int32>( aScale.getY() * maDstSize.getY() )+1 );
309 
310                     ::Point aEmptyPoint;
311 
312                     // render our content into an appropriately sized
313                     // VirtualDevice with alpha channel
314                     VirtualDevice aVDev(
315                         *::Application::GetDefaultDevice(), 0, 0 );
316                     aVDev.SetOutputSizePixel( aBitmapSizePixel );
317                     aVDev.SetMapMode();
318 
319                     if( rSubset.mnSubsetBegin != 0 ||
320                         rSubset.mnSubsetEnd != -1 )
321                     {
322                         // true subset - extract referenced
323                         // metaactions from mpGroupMtf
324                         GDIMetaFile aMtf;
325                         MetaAction* pCurrAct;
326                         int 		nCurrActionIndex;
327 
328                         // extract subset actions
329                         for( nCurrActionIndex=0,
330                                  pCurrAct=mpGroupMtf->FirstAction();
331                              pCurrAct;
332                              ++nCurrActionIndex, pCurrAct = mpGroupMtf->NextAction() )
333                         {
334                             switch( pCurrAct->GetType() )
335                             {
336                                 case META_PUSH_ACTION:
337                                 case META_POP_ACTION:
338                                 case META_CLIPREGION_ACTION:
339                                 case META_ISECTRECTCLIPREGION_ACTION:
340                                 case META_ISECTREGIONCLIPREGION_ACTION:
341                                 case META_MOVECLIPREGION_ACTION:
342                                 case META_LINECOLOR_ACTION:
343                                 case META_FILLCOLOR_ACTION:
344                                 case META_TEXTCOLOR_ACTION:
345                                 case META_TEXTFILLCOLOR_ACTION:
346                                 case META_TEXTLINECOLOR_ACTION:
347                                 case META_TEXTALIGN_ACTION:
348                                 case META_FONT_ACTION:
349                                 case META_RASTEROP_ACTION:
350                                 case META_REFPOINT_ACTION:
351                                 case META_LAYOUTMODE_ACTION:
352                                     // state-changing action - copy as-is
353                                     aMtf.AddAction( pCurrAct->Clone() );
354                                     break;
355 
356                                 case META_GRADIENT_ACTION:
357                                 case META_HATCH_ACTION:
358                                 case META_EPS_ACTION:
359                                 case META_COMMENT_ACTION:
360                                 case META_POINT_ACTION:
361                                 case META_PIXEL_ACTION:
362                                 case META_LINE_ACTION:
363                                 case META_RECT_ACTION:
364                                 case META_ROUNDRECT_ACTION:
365                                 case META_ELLIPSE_ACTION:
366                                 case META_ARC_ACTION:
367                                 case META_PIE_ACTION:
368                                 case META_CHORD_ACTION:
369                                 case META_POLYLINE_ACTION:
370                                 case META_POLYGON_ACTION:
371                                 case META_POLYPOLYGON_ACTION:
372                                 case META_BMP_ACTION:
373                                 case META_BMPSCALE_ACTION:
374                                 case META_BMPSCALEPART_ACTION:
375                                 case META_BMPEX_ACTION:
376                                 case META_BMPEXSCALE_ACTION:
377                                 case META_BMPEXSCALEPART_ACTION:
378                                 case META_MASK_ACTION:
379                                 case META_MASKSCALE_ACTION:
380                                 case META_MASKSCALEPART_ACTION:
381                                 case META_GRADIENTEX_ACTION:
382                                 case META_WALLPAPER_ACTION:
383                                 case META_TRANSPARENT_ACTION:
384                                 case META_FLOATTRANSPARENT_ACTION:
385                                 case META_TEXT_ACTION:
386                                 case META_TEXTARRAY_ACTION:
387                                 case META_TEXTLINE_ACTION:
388                                 case META_TEXTRECT_ACTION:
389                                 case META_STRETCHTEXT_ACTION:
390                                     // output-generating action - only
391                                     // copy, if we're within the
392                                     // requested subset
393                                     if( rSubset.mnSubsetBegin <= nCurrActionIndex &&
394                                         rSubset.mnSubsetEnd > nCurrActionIndex )
395                                     {
396                                         aMtf.AddAction( pCurrAct->Clone() );
397                                     }
398                                     break;
399 
400                                 default:
401                                     OSL_ENSURE( false,
402                                                 "Unknown meta action type encountered" );
403                                     break;
404                             }
405                         }
406 
407                         aVDev.DrawTransparent( aMtf,
408                                                aEmptyPoint,
409                                                aOutputSizePixel,
410                                                *mpAlphaGradient );
411                     }
412                     else
413                     {
414                         // no subsetting - render whole mtf
415                         aVDev.DrawTransparent( *mpGroupMtf,
416                                                aEmptyPoint,
417                                                aOutputSizePixel,
418                                                *mpAlphaGradient );
419                     }
420 
421 
422                     // update buffered bitmap and transformation
423                     BitmapSharedPtr aBmp( VCLFactory::getInstance().createBitmap(
424                                               mpCanvas,
425                                               aVDev.GetBitmapEx(
426                                                   aEmptyPoint,
427                                                   aBitmapSizePixel ) ) );
428                     mxBufferBitmap = aBmp->getUNOBitmap();
429                     maLastTransformation = aTotalTransform;
430                     maLastSubset = rSubset;
431                 }
432 
433                 // determine target transformation (we can't simply pass
434                 // aTotalTransform as assembled above, since we must take
435                 // the canvas' view state as is, it might contain clipping
436                 // (which, in turn, is relative to the view
437                 // transformation))
438 
439                 // given that aTotalTransform is the identity
440                 // transformation, we could simply render our bitmap
441                 // as-is. Now, since the mxBufferBitmap content already
442                 // accounts for scale changes in the overall
443                 // transformation, we must factor this out
444                 // before. Generally, the transformation matrix should be
445                 // structured like this:
446                 // Translation*Rotation*Shear*Scale. Thus, to neutralize
447                 // the contained scaling, we've got to right-multiply with
448                 // the inverse.
449                 ::basegfx::B2ISize aBmpSize(
450                     ::basegfx::unotools::b2ISizeFromIntegerSize2D( mxBufferBitmap->getSize() ) );
451 
452                 ::basegfx::B2DHomMatrix aScaleCorrection;
453                 aScaleCorrection.scale( (double)maDstSize.getX() / aBmpSize.getX(),
454                                         (double)maDstSize.getY() / aBmpSize.getY() );
455                 aTransform = aTransform * aScaleCorrection;
456 
457                 rendering::RenderState aLocalState( maState );
458                 ::canvas::tools::setRenderStateTransform(aLocalState, aTransform);
459 
460 #ifdef SPECIAL_DEBUG
461                 aLocalState.Clip.clear();
462                 aLocalState.DeviceColor =
463                     ::vcl::unotools::colorToDoubleSequence(
464                         ::Color( 0x80FF0000 ),
465                         mpCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
466 
467                 if( maState.Clip.is() )
468                     mpCanvas->getUNOCanvas()->fillPolyPolygon( maState.Clip,
469                                                                mpCanvas->getViewState(),
470                                                                aLocalState );
471 
472                 aLocalState.DeviceColor = maState.DeviceColor;
473 #endif
474 
475                 if( ::rtl::math::approxEqual(mnAlpha, 1.0) )
476                 {
477                     // no further alpha changes necessary -> draw directly
478                     mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
479                                                           mpCanvas->getViewState(),
480                                                           aLocalState );
481                 }
482                 else
483                 {
484                     // add alpha modulation value to DeviceColor
485                     uno::Sequence<rendering::ARGBColor> aCols(1);
486                     aCols[0] = rendering::ARGBColor( mnAlpha, 1.0, 1.0, 1.0);
487                     aLocalState.DeviceColor =
488                         mpCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace()->convertFromARGB(
489                             aCols);
490 
491                     mpCanvas->getUNOCanvas()->drawBitmapModulated( mxBufferBitmap,
492                                                                    mpCanvas->getViewState(),
493                                                                    aLocalState );
494                 }
495 
496                 return true;
497             }
498 
499             // TODO(P3): The whole float transparency handling is a mess,
500             // this should be refactored. What's more, the old idea of
501             // having only internal 'metaactions', and not the original
502             // GDIMetaFile now looks a lot less attractive. Try to move
503             // into the direction of having a direct GDIMetaFile2XCanvas
504             // renderer, and maybe a separate metafile XCanvas
505             // implementation.
render(const::basegfx::B2DHomMatrix & rTransformation) const506             bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
507             {
508                 Subset aSubset;
509 
510                 aSubset.mnSubsetBegin = 0;
511                 aSubset.mnSubsetEnd   = -1;
512 
513                 return render( rTransformation, aSubset );
514             }
515 
getBounds(const::basegfx::B2DHomMatrix & rTransformation) const516             ::basegfx::B2DRange TransparencyGroupAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation ) const
517             {
518                 rendering::RenderState aLocalState( maState );
519                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
520 
521                 return tools::calcDevicePixelBounds(
522                     ::basegfx::B2DRange( 0,0,
523                                          maDstSize.getX(),
524                                          maDstSize.getY() ),
525                     mpCanvas->getViewState(),
526                     aLocalState );
527             }
528 
getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const529             ::basegfx::B2DRange TransparencyGroupAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
530                                                                     const Subset&					rSubset ) const
531             {
532                 // TODO(F3): Currently, the bounds for
533                 // TransparencyGroupAction subsets equal those of the
534                 // full set, although this action is able to render
535                 // true subsets.
536 
537                 // polygon only contains a single action, empty bounds
538                 // if subset requests different range
539                 if( rSubset.mnSubsetBegin != 0 ||
540                     rSubset.mnSubsetEnd != 1 )
541                     return ::basegfx::B2DRange();
542 
543                 return getBounds( rTransformation );
544             }
545 
getActionCount() const546             sal_Int32 TransparencyGroupAction::getActionCount() const
547             {
548                 return mpGroupMtf.get() ? mpGroupMtf->GetActionCount() : 0;
549             }
550 
551         }
552 
createTransparencyGroupAction(MtfAutoPtr & rGroupMtf,const Renderer::Parameters & rParms,const::basegfx::B2DPoint & rDstPoint,const::basegfx::B2DVector & rDstSize,double nAlpha,const CanvasSharedPtr & rCanvas,const OutDevState & rState)553         ActionSharedPtr TransparencyGroupActionFactory::createTransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
554                                                                                        const Renderer::Parameters&	rParms,
555                                                                                        const ::basegfx::B2DPoint& 	rDstPoint,
556                                                                                        const ::basegfx::B2DVector& 	rDstSize,
557                                                                                        double 						nAlpha,
558                                                                                        const CanvasSharedPtr&		rCanvas,
559                                                                                        const OutDevState& 			rState )
560         {
561             return ActionSharedPtr( new TransparencyGroupAction(rGroupMtf,
562                                                                 rParms,
563                                                                 rDstPoint,
564                                                                 rDstSize,
565                                                                 nAlpha,
566                                                                 rCanvas,
567                                                                 rState ) );
568         }
569 
createTransparencyGroupAction(MtfAutoPtr & rGroupMtf,GradientAutoPtr & rAlphaGradient,const Renderer::Parameters & rParms,const::basegfx::B2DPoint & rDstPoint,const::basegfx::B2DVector & rDstSize,const CanvasSharedPtr & rCanvas,const OutDevState & rState)570         ActionSharedPtr TransparencyGroupActionFactory::createTransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
571                                                                                        GradientAutoPtr&				rAlphaGradient,
572                                                                                        const Renderer::Parameters&	rParms,
573                                                                                        const ::basegfx::B2DPoint& 	rDstPoint,
574                                                                                        const ::basegfx::B2DVector&  rDstSize,
575                                                                                        const CanvasSharedPtr&		rCanvas,
576                                                                                        const OutDevState& 			rState )
577         {
578             return ActionSharedPtr( new TransparencyGroupAction(rGroupMtf,
579                                                                 rAlphaGradient,
580                                                                 rParms,
581                                                                 rDstPoint,
582                                                                 rDstSize,
583                                                                 rCanvas,
584                                                                 rState ) );
585         }
586 
587     }
588 }
589