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