1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_canvas.hxx"
30 
31 #include <canvas/debug.hxx>
32 #include <tools/diagnose_ex.h>
33 
34 #include <rtl/logfile.hxx>
35 #include <rtl/math.hxx>
36 
37 #include <com/sun/star/rendering/TexturingMode.hpp>
38 #include <com/sun/star/rendering/CompositeOperation.hpp>
39 #include <com/sun/star/rendering/RepaintResult.hpp>
40 #include <com/sun/star/rendering/PathCapType.hpp>
41 #include <com/sun/star/rendering/PathJoinType.hpp>
42 
43 #include <basegfx/matrix/b2dhommatrix.hxx>
44 #include <basegfx/point/b2dpoint.hxx>
45 #include <basegfx/tools/canvastools.hxx>
46 
47 #include <comphelper/sequence.hxx>
48 #include <canvas/canvastools.hxx>
49 
50 #include "dx_spritecanvas.hxx"
51 #include "dx_impltools.hxx"
52 #include "dx_canvasfont.hxx"
53 #include "dx_textlayout.hxx"
54 #include "dx_bitmapcanvashelper.hxx"
55 
56 #include <algorithm>
57 
58 
59 using namespace ::com::sun::star;
60 
61 namespace dxcanvas
62 {
63     BitmapCanvasHelper::BitmapCanvasHelper() :
64         mpTarget()
65     {}
66 
67     void BitmapCanvasHelper::disposing()
68     {
69         mpTarget.reset();
70         CanvasHelper::disposing();
71     }
72 
73     void BitmapCanvasHelper::setTarget( const IBitmapSharedPtr& rTarget )
74     {
75         ENSURE_OR_THROW( rTarget,
76                           "BitmapCanvasHelper::setTarget(): Invalid target" );
77         ENSURE_OR_THROW( !mpTarget.get(),
78                           "BitmapCanvasHelper::setTarget(): target set, old target would be overwritten" );
79 
80         mpTarget = rTarget;
81         CanvasHelper::setTarget(rTarget);
82     }
83 
84     void BitmapCanvasHelper::setTarget( const IBitmapSharedPtr&   rTarget,
85                                         const ::basegfx::B2ISize& rOutputOffset )
86     {
87         ENSURE_OR_THROW( rTarget,
88                          "BitmapCanvasHelper::setTarget(): invalid target" );
89         ENSURE_OR_THROW( !mpTarget.get(),
90                          "BitmapCanvasHelper::setTarget(): target set, old target would be overwritten" );
91 
92         mpTarget = rTarget;
93         CanvasHelper::setTarget(rTarget,rOutputOffset);
94     }
95 
96     void BitmapCanvasHelper::clear()
97     {
98         if( needOutput() )
99         {
100             GraphicsSharedPtr pGraphics( mpTarget->getGraphics() );
101 
102             Gdiplus::Color aClearColor = hasAlpha() ?
103                 Gdiplus::Color( 0,255,255,255 ) : Gdiplus::Color((Gdiplus::ARGB)Gdiplus::Color::White);
104 
105             ENSURE_OR_THROW(
106                 Gdiplus::Ok == pGraphics->SetCompositingMode(
107                     Gdiplus::CompositingModeSourceCopy ), // force set, don't blend
108                 "BitmapCanvasHelper::clear(): GDI+ SetCompositingMode call failed" );
109             ENSURE_OR_THROW(
110                 Gdiplus::Ok == pGraphics->Clear( aClearColor ),
111                 "BitmapCanvasHelper::clear(): GDI+ Clear call failed" );
112         }
113     }
114 
115     uno::Reference< rendering::XCachedPrimitive > BitmapCanvasHelper::drawTextLayout( const rendering::XCanvas* 					  /*pCanvas*/,
116                                                                                       const uno::Reference< rendering::XTextLayout >& xLayoutetText,
117                                                                                       const rendering::ViewState& 					  viewState,
118                                                                                       const rendering::RenderState& 				  renderState )
119     {
120         ENSURE_OR_THROW( xLayoutetText.is(),
121                           "BitmapCanvasHelper::drawTextLayout: layout is NULL");
122 
123         if( needOutput() )
124         {
125 			TextLayout* pTextLayout =
126                 dynamic_cast< TextLayout* >( xLayoutetText.get() );
127 
128             ENSURE_OR_THROW( pTextLayout,
129                                 "BitmapCanvasHelper::drawTextLayout(): TextLayout not compatible with this canvas" );
130 
131 			pTextLayout->draw( mpTarget->getGraphics(),
132                                viewState,
133                                renderState,
134                                maOutputOffset,
135                                mpDevice,
136                                mpTarget->hasAlpha() );
137         }
138 
139         return uno::Reference< rendering::XCachedPrimitive >(NULL);
140     }
141 
142     void BitmapCanvasHelper::copyRect( const rendering::XCanvas* 							/*pCanvas*/,
143                                        const uno::Reference< rendering::XBitmapCanvas >&	/*sourceCanvas*/,
144                                        const geometry::RealRectangle2D& 					/*sourceRect*/,
145                                        const rendering::ViewState& 							/*sourceViewState*/,
146                                        const rendering::RenderState& 						/*sourceRenderState*/,
147                                        const geometry::RealRectangle2D& 					/*destRect*/,
148                                        const rendering::ViewState& 							/*destViewState*/,
149                                        const rendering::RenderState& 						/*destRenderState*/ )
150     {
151         // TODO(F2): copyRect NYI
152     }
153 
154     geometry::IntegerSize2D BitmapCanvasHelper::getSize()
155     {
156         if( !mpTarget )
157             return geometry::IntegerSize2D(1, 1);
158 
159         return basegfx::unotools::integerSize2DFromB2ISize(mpTarget->getSize());
160     }
161 
162     uno::Reference< rendering::XBitmap > BitmapCanvasHelper::getScaledBitmap( const geometry::RealSize2D& /*newSize*/,
163                                                                               sal_Bool 					  /*beFast*/ )
164     {
165         // TODO(F1):
166         return uno::Reference< rendering::XBitmap >();
167     }
168 
169     uno::Sequence< sal_Int8 > BitmapCanvasHelper::getData( rendering::IntegerBitmapLayout&     bitmapLayout,
170                                                            const geometry::IntegerRectangle2D& rect )
171     {
172         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::getData()" );
173 
174         ENSURE_OR_THROW( mpTarget,
175                           "::dxcanvas::BitmapCanvasHelper::getData(): disposed" );
176 
177 		if( !mpTarget )
178 	        return uno::Sequence< sal_Int8 >();
179 
180 		bitmapLayout = getMemoryLayout();
181 		return mpTarget->getData(bitmapLayout,rect);
182     }
183 
184     void BitmapCanvasHelper::setData( const uno::Sequence< sal_Int8 >& 		data,
185                                       const rendering::IntegerBitmapLayout& bitmapLayout,
186                                       const geometry::IntegerRectangle2D& 	rect )
187     {
188         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::setData()" );
189 
190         ENSURE_OR_THROW( mpTarget,
191                           "::dxcanvas::BitmapCanvasHelper::setData(): disposed" );
192 
193 		if( !mpTarget )
194 			return;
195 
196 		mpTarget->setData(data,bitmapLayout,rect);
197     }
198 
199     void BitmapCanvasHelper::setPixel( const uno::Sequence< sal_Int8 >&       color,
200                                        const rendering::IntegerBitmapLayout&  bitmapLayout,
201                                        const geometry::IntegerPoint2D&        pos )
202     {
203         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::setPixel()" );
204 
205         ENSURE_OR_THROW( mpTarget,
206                           "::dxcanvas::BitmapCanvasHelper::setPixel(): disposed" );
207 
208 		if( !mpTarget )
209 			return;
210 
211 		mpTarget->setPixel(color,bitmapLayout,pos);
212     }
213 
214     uno::Sequence< sal_Int8 > BitmapCanvasHelper::getPixel( rendering::IntegerBitmapLayout&   bitmapLayout,
215                                                             const geometry::IntegerPoint2D&   pos )
216     {
217         RTL_LOGFILE_CONTEXT( aLog, "::dxcanvas::BitmapCanvasHelper::getPixel()" );
218 
219         ENSURE_OR_THROW( mpTarget,
220                           "::dxcanvas::BitmapCanvasHelper::getPixel(): disposed" );
221 
222 		if( !mpTarget )
223 			return uno::Sequence< sal_Int8 >();
224 
225 		bitmapLayout = getMemoryLayout();
226 		return mpTarget->getPixel(bitmapLayout,pos);
227     }
228 
229     uno::Reference< rendering::XBitmapPalette > BitmapCanvasHelper::getPalette()
230     {
231         // TODO(F1): Palette bitmaps NYI
232         return uno::Reference< rendering::XBitmapPalette >();
233     }
234 
235     rendering::IntegerBitmapLayout BitmapCanvasHelper::getMemoryLayout()
236     {
237         if( !mpTarget )
238             return rendering::IntegerBitmapLayout(); // we're disposed
239 
240         return ::canvas::tools::getStdMemoryLayout(getSize());
241     }
242     bool BitmapCanvasHelper::hasAlpha() const
243     {
244 		return mpTarget ? mpTarget->hasAlpha() : false;
245     }
246 }
247