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_canvas.hxx"
26 
27 #include <canvas/debug.hxx>
28 #include <tools/diagnose_ex.h>
29 
30 #include <rtl/logfile.hxx>
31 #include <rtl/math.hxx>
32 
33 #include <com/sun/star/rendering/TexturingMode.hpp>
34 #include <com/sun/star/rendering/CompositeOperation.hpp>
35 #include <com/sun/star/rendering/RepaintResult.hpp>
36 #include <com/sun/star/rendering/PathCapType.hpp>
37 #include <com/sun/star/rendering/PathJoinType.hpp>
38 
39 #include <basegfx/matrix/b2dhommatrix.hxx>
40 #include <basegfx/point/b2dpoint.hxx>
41 #include <basegfx/tools/canvastools.hxx>
42 
43 #include <comphelper/sequence.hxx>
44 #include <canvas/canvastools.hxx>
45 
46 #include "dx_spritecanvas.hxx"
47 #include "dx_impltools.hxx"
48 #include "dx_canvasfont.hxx"
49 #include "dx_textlayout.hxx"
50 #include "dx_bitmapcanvashelper.hxx"
51 
52 #include <algorithm>
53 
54 
55 using namespace ::com::sun::star;
56 
57 namespace dxcanvas
58 {
59     BitmapCanvasHelper::BitmapCanvasHelper() :
60         mpTarget()
61     {}
62 
63     void BitmapCanvasHelper::disposing()
64     {
65         mpTarget.reset();
66         CanvasHelper::disposing();
67     }
68 
69     void BitmapCanvasHelper::setTarget( const IBitmapSharedPtr& rTarget )
70     {
71         ENSURE_OR_THROW( rTarget,
72                           "BitmapCanvasHelper::setTarget(): Invalid target" );
73         ENSURE_OR_THROW( !mpTarget.get(),
74                           "BitmapCanvasHelper::setTarget(): target set, old target would be overwritten" );
75 
76         mpTarget = rTarget;
77         CanvasHelper::setTarget(rTarget);
78     }
79 
80     void BitmapCanvasHelper::setTarget( const IBitmapSharedPtr&   rTarget,
81                                         const ::basegfx::B2ISize& rOutputOffset )
82     {
83         ENSURE_OR_THROW( rTarget,
84                          "BitmapCanvasHelper::setTarget(): invalid target" );
85         ENSURE_OR_THROW( !mpTarget.get(),
86                          "BitmapCanvasHelper::setTarget(): target set, old target would be overwritten" );
87 
88         mpTarget = rTarget;
89         CanvasHelper::setTarget(rTarget,rOutputOffset);
90     }
91 
92     void BitmapCanvasHelper::clear()
93     {
94         if( needOutput() )
95         {
96             GraphicsSharedPtr pGraphics( mpTarget->getGraphics() );
97 
98             Gdiplus::Color aClearColor = hasAlpha() ?
99                 Gdiplus::Color( 0,255,255,255 ) : Gdiplus::Color((Gdiplus::ARGB)Gdiplus::Color::White);
100 
101             ENSURE_OR_THROW(
102                 Gdiplus::Ok == pGraphics->SetCompositingMode(
103                     Gdiplus::CompositingModeSourceCopy ), // force set, don't blend
104                 "BitmapCanvasHelper::clear(): GDI+ SetCompositingMode call failed" );
105             ENSURE_OR_THROW(
106                 Gdiplus::Ok == pGraphics->Clear( aClearColor ),
107                 "BitmapCanvasHelper::clear(): GDI+ Clear call failed" );
108         }
109     }
110 
111     uno::Reference< rendering::XCachedPrimitive > BitmapCanvasHelper::drawTextLayout( const rendering::XCanvas* 					  /*pCanvas*/,
112                                                                                       const uno::Reference< rendering::XTextLayout >& xLayoutetText,
113                                                                                       const rendering::ViewState& 					  viewState,
114                                                                                       const rendering::RenderState& 				  renderState )
115     {
116         ENSURE_OR_THROW( xLayoutetText.is(),
117                           "BitmapCanvasHelper::drawTextLayout: layout is NULL");
118 
119         if( needOutput() )
120         {
121 			TextLayout* pTextLayout =
122                 dynamic_cast< TextLayout* >( xLayoutetText.get() );
123 
124             ENSURE_OR_THROW( pTextLayout,
125                                 "BitmapCanvasHelper::drawTextLayout(): TextLayout not compatible with this canvas" );
126 
127 			pTextLayout->draw( mpTarget->getGraphics(),
128                                viewState,
129                                renderState,
130                                maOutputOffset,
131                                mpDevice,
132                                mpTarget->hasAlpha() );
133         }
134 
135         return uno::Reference< rendering::XCachedPrimitive >(NULL);
136     }
137 
138     void BitmapCanvasHelper::copyRect( const rendering::XCanvas* 							/*pCanvas*/,
139                                        const uno::Reference< rendering::XBitmapCanvas >&	/*sourceCanvas*/,
140                                        const geometry::RealRectangle2D& 					/*sourceRect*/,
141                                        const rendering::ViewState& 							/*sourceViewState*/,
142                                        const rendering::RenderState& 						/*sourceRenderState*/,
143                                        const geometry::RealRectangle2D& 					/*destRect*/,
144                                        const rendering::ViewState& 							/*destViewState*/,
145                                        const rendering::RenderState& 						/*destRenderState*/ )
146     {
147         // TODO(F2): copyRect NYI
148     }
149 
150     geometry::IntegerSize2D BitmapCanvasHelper::getSize()
151     {
152         if( !mpTarget )
153             return geometry::IntegerSize2D(1, 1);
154 
155         return basegfx::unotools::integerSize2DFromB2ISize(mpTarget->getSize());
156     }
157 
158     uno::Reference< rendering::XBitmap > BitmapCanvasHelper::getScaledBitmap( const geometry::RealSize2D& /*newSize*/,
159                                                                               sal_Bool 					  /*beFast*/ )
160     {
161         // TODO(F1):
162         return uno::Reference< rendering::XBitmap >();
163     }
164 
165     uno::Sequence< sal_Int8 > BitmapCanvasHelper::getData( rendering::IntegerBitmapLayout&     bitmapLayout,
166                                                            const geometry::IntegerRectangle2D& rect )
167     {
168         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::getData()" );
169 
170         ENSURE_OR_THROW( mpTarget,
171                           "::dxcanvas::BitmapCanvasHelper::getData(): disposed" );
172 
173 		if( !mpTarget )
174 	        return uno::Sequence< sal_Int8 >();
175 
176 		bitmapLayout = getMemoryLayout();
177 		return mpTarget->getData(bitmapLayout,rect);
178     }
179 
180     void BitmapCanvasHelper::setData( const uno::Sequence< sal_Int8 >& 		data,
181                                       const rendering::IntegerBitmapLayout& bitmapLayout,
182                                       const geometry::IntegerRectangle2D& 	rect )
183     {
184         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::setData()" );
185 
186         ENSURE_OR_THROW( mpTarget,
187                           "::dxcanvas::BitmapCanvasHelper::setData(): disposed" );
188 
189 		if( !mpTarget )
190 			return;
191 
192 		mpTarget->setData(data,bitmapLayout,rect);
193     }
194 
195     void BitmapCanvasHelper::setPixel( const uno::Sequence< sal_Int8 >&       color,
196                                        const rendering::IntegerBitmapLayout&  bitmapLayout,
197                                        const geometry::IntegerPoint2D&        pos )
198     {
199         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::setPixel()" );
200 
201         ENSURE_OR_THROW( mpTarget,
202                           "::dxcanvas::BitmapCanvasHelper::setPixel(): disposed" );
203 
204 		if( !mpTarget )
205 			return;
206 
207 		mpTarget->setPixel(color,bitmapLayout,pos);
208     }
209 
210     uno::Sequence< sal_Int8 > BitmapCanvasHelper::getPixel( rendering::IntegerBitmapLayout&   bitmapLayout,
211                                                             const geometry::IntegerPoint2D&   pos )
212     {
213         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::getPixel()" );
214 
215         ENSURE_OR_THROW( mpTarget,
216                           "::dxcanvas::BitmapCanvasHelper::getPixel(): disposed" );
217 
218 		if( !mpTarget )
219 			return uno::Sequence< sal_Int8 >();
220 
221 		bitmapLayout = getMemoryLayout();
222 		return mpTarget->getPixel(bitmapLayout,pos);
223     }
224 
225     uno::Reference< rendering::XBitmapPalette > BitmapCanvasHelper::getPalette()
226     {
227         // TODO(F1): Palette bitmaps NYI
228         return uno::Reference< rendering::XBitmapPalette >();
229     }
230 
231     rendering::IntegerBitmapLayout BitmapCanvasHelper::getMemoryLayout()
232     {
233         if( !mpTarget )
234             return rendering::IntegerBitmapLayout(); // we're disposed
235 
236         return ::canvas::tools::getStdMemoryLayout(getSize());
237     }
238     bool BitmapCanvasHelper::hasAlpha() const
239     {
240 		return mpTarget ? mpTarget->hasAlpha() : false;
241     }
242 }
243