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 #include <com/sun/star/rendering/XBitmap.hpp>
29 #include <com/sun/star/rendering/RepaintResult.hpp>
30 #include <com/sun/star/rendering/XCachedPrimitive.hpp>
31 #include <vcl/bitmapex.hxx>
32 #include <tools/gen.hxx>
33 #include <vcl/canvastools.hxx>
34 #include <canvas/canvastools.hxx>
35 #include <basegfx/matrix/b2dhommatrix.hxx>
36 #include <basegfx/vector/b2dsize.hxx>
37 #include <basegfx/point/b2dpoint.hxx>
38 #include <basegfx/range/b2drange.hxx>
39 #include <basegfx/tools/canvastools.hxx>
40 #include <boost/utility.hpp>
41 #include "cachedprimitivebase.hxx"
42 #include "bitmapaction.hxx"
43 #include "outdevstate.hxx"
44 #include "mtftools.hxx"
45 #include <basegfx/matrix/b2dhommatrixtools.hxx>
46 
47 
48 using namespace ::com::sun::star;
49 
50 namespace cppcanvas
51 {
52     namespace internal
53     {
54         namespace
55         {
56 
57             class BitmapAction : public CachedPrimitiveBase
58             {
59             public:
60                 BitmapAction( const ::BitmapEx&,
61                               const ::basegfx::B2DPoint& rDstPoint,
62                               const CanvasSharedPtr&,
63                               const OutDevState& );
64                 BitmapAction( const ::BitmapEx&,
65                               const ::basegfx::B2DPoint&  rDstPoint,
66                               const ::basegfx::B2DVector& rDstSize,
67                               const CanvasSharedPtr&,
68                               const OutDevState& );
69 
70                 virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
71                                      const Subset&					rSubset ) const;
72 
73                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
74                 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
75                                                        const Subset&					rSubset ) const;
76 
77                 virtual sal_Int32 getActionCount() const;
78 
79             private:
80                 using Action::render;
81                 virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
82                                      const ::basegfx::B2DHomMatrix&                 rTransformation ) const;
83 
84                 uno::Reference< rendering::XBitmap > 					mxBitmap;
85                 CanvasSharedPtr											mpCanvas;
86                 rendering::RenderState									maState;
87             };
88 
89 
BitmapAction(const::BitmapEx & rBmpEx,const::basegfx::B2DPoint & rDstPoint,const CanvasSharedPtr & rCanvas,const OutDevState & rState)90             BitmapAction::BitmapAction( const ::BitmapEx&		   rBmpEx,
91                                         const ::basegfx::B2DPoint& rDstPoint,
92                                         const CanvasSharedPtr&     rCanvas,
93                                         const OutDevState&         rState ) :
94                 CachedPrimitiveBase( rCanvas, true ),
95                 mxBitmap( ::vcl::unotools::xBitmapFromBitmapEx( rCanvas->getUNOCanvas()->getDevice(),
96                                                                 rBmpEx ) ),
97                 mpCanvas( rCanvas ),
98                 maState()
99             {
100                 tools::initRenderState(maState,rState);
101 
102                 // Setup transformation such that the next render call is
103                 // moved rPoint away.
104 				const basegfx::B2DHomMatrix	aLocalTransformation(basegfx::tools::createTranslateB2DHomMatrix(rDstPoint));
105                 ::canvas::tools::appendToRenderState( maState,
106                                                       aLocalTransformation );
107 
108                 // correct clip (which is relative to original transform)
109                 tools::modifyClip( maState,
110                                    rState,
111                                    rCanvas,
112                                    rDstPoint,
113                                    NULL,
114                                    NULL );
115             }
116 
BitmapAction(const::BitmapEx & rBmpEx,const::basegfx::B2DPoint & rDstPoint,const::basegfx::B2DVector & rDstSize,const CanvasSharedPtr & rCanvas,const OutDevState & rState)117             BitmapAction::BitmapAction( const ::BitmapEx&		    rBmpEx,
118                                         const ::basegfx::B2DPoint&  rDstPoint,
119                                         const ::basegfx::B2DVector& rDstSize,
120                                         const CanvasSharedPtr&      rCanvas,
121                                         const OutDevState&          rState 		) :
122                 CachedPrimitiveBase( rCanvas, true ),
123                 mxBitmap( ::vcl::unotools::xBitmapFromBitmapEx( rCanvas->getUNOCanvas()->getDevice(),
124                                                                 rBmpEx ) ),
125                 mpCanvas( rCanvas ),
126                 maState()
127             {
128                 tools::initRenderState(maState,rState);
129 
130                 // Setup transformation such that the next render call is
131                 // moved rPoint away, and scaled according to the ratio
132                 // given by src and dst size.
133                 const ::Size aBmpSize( rBmpEx.GetSizePixel() );
134 
135                 const ::basegfx::B2DVector aScale( rDstSize.getX() / aBmpSize.Width(),
136                                                    rDstSize.getY() / aBmpSize.Height() );
137 				const basegfx::B2DHomMatrix	aLocalTransformation(basegfx::tools::createScaleTranslateB2DHomMatrix(
138 					aScale, rDstPoint));
139                 ::canvas::tools::appendToRenderState( maState, aLocalTransformation );
140 
141                 // correct clip (which is relative to original transform)
142                 tools::modifyClip( maState,
143                                    rState,
144                                    rCanvas,
145                                    rDstPoint,
146                                    &aScale,
147                                    NULL );
148             }
149 
render(uno::Reference<rendering::XCachedPrimitive> & rCachedPrimitive,const::basegfx::B2DHomMatrix & rTransformation) const150             bool BitmapAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
151                                        const ::basegfx::B2DHomMatrix&                 rTransformation ) const
152             {
153                 RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::BitmapAction::render()" );
154                 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::BitmapAction: 0x%X", this );
155 
156                 rendering::RenderState aLocalState( maState );
157                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
158 
159                 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawBitmap( mxBitmap,
160                                                                          mpCanvas->getViewState(),
161                                                                          aLocalState );
162 
163                 return true;
164             }
165 
render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const166             bool BitmapAction::render( const ::basegfx::B2DHomMatrix&	rTransformation,
167                                        const Subset&					rSubset ) const
168             {
169                 // bitmap only contains a single action, fail if subset
170                 // requests different range
171                 if( rSubset.mnSubsetBegin != 0 ||
172                     rSubset.mnSubsetEnd != 1 )
173                     return false;
174 
175                 return CachedPrimitiveBase::render( rTransformation );
176             }
177 
getBounds(const::basegfx::B2DHomMatrix & rTransformation) const178             ::basegfx::B2DRange BitmapAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
179             {
180                 rendering::RenderState aLocalState( maState );
181                 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
182 
183                 const geometry::IntegerSize2D aSize( mxBitmap->getSize() );
184 
185                 return tools::calcDevicePixelBounds( ::basegfx::B2DRange( 0,0,
186                                                                           aSize.Width,
187                                                                           aSize.Height ),
188                                                      mpCanvas->getViewState(),
189                                                      aLocalState );
190             }
191 
getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const192             ::basegfx::B2DRange BitmapAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
193                                                          const Subset&					rSubset ) const
194             {
195                 // bitmap only contains a single action, empty bounds
196                 // if subset requests different range
197                 if( rSubset.mnSubsetBegin != 0 ||
198                     rSubset.mnSubsetEnd != 1 )
199                     return ::basegfx::B2DRange();
200 
201                 return getBounds( rTransformation );
202             }
203 
getActionCount() const204             sal_Int32 BitmapAction::getActionCount() const
205             {
206                 return 1;
207             }
208         }
209 
createBitmapAction(const::BitmapEx & rBmpEx,const::basegfx::B2DPoint & rDstPoint,const CanvasSharedPtr & rCanvas,const OutDevState & rState)210         ActionSharedPtr BitmapActionFactory::createBitmapAction( const ::BitmapEx&          rBmpEx,
211                                                                  const ::basegfx::B2DPoint& rDstPoint,
212                                                                  const CanvasSharedPtr&     rCanvas,
213                                                                  const OutDevState&         rState )
214         {
215             return ActionSharedPtr( new BitmapAction(rBmpEx,
216                                                      rDstPoint,
217                                                      rCanvas,
218                                                      rState ) );
219         }
220 
createBitmapAction(const::BitmapEx & rBmpEx,const::basegfx::B2DPoint & rDstPoint,const::basegfx::B2DVector & rDstSize,const CanvasSharedPtr & rCanvas,const OutDevState & rState)221         ActionSharedPtr BitmapActionFactory::createBitmapAction( const ::BitmapEx&           rBmpEx,
222                                                                  const ::basegfx::B2DPoint&  rDstPoint,
223                                                                  const ::basegfx::B2DVector& rDstSize,
224                                                                  const CanvasSharedPtr&      rCanvas,
225                                                                  const OutDevState&          rState )
226         {
227             return ActionSharedPtr( new BitmapAction(rBmpEx,
228                                                      rDstPoint,
229                                                      rDstSize,
230                                                      rCanvas,
231                                                      rState ) );
232         }
233     }
234 }
235