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 <ctype.h> // don't ask. msdev breaks otherwise... 28 #include <canvas/debug.hxx> 29 #include <canvas/verbosetrace.hxx> 30 #include <canvas/canvastools.hxx> 31 #include <tools/diagnose_ex.h> 32 33 #include <osl/mutex.hxx> 34 35 #include <com/sun/star/awt/XWindow.hpp> 36 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp> 37 #include <com/sun/star/registry/XRegistryKey.hpp> 38 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 39 #include <com/sun/star/uno/XComponentContext.hpp> 40 #include <com/sun/star/lang/NoSupportException.hpp> 41 42 #include <toolkit/helper/vclunohelper.hxx> 43 #include <cppuhelper/factory.hxx> 44 #include <cppuhelper/implementationentry.hxx> 45 #include <comphelper/servicedecl.hxx> 46 47 #include <basegfx/matrix/b2dhommatrix.hxx> 48 #include <basegfx/point/b2dpoint.hxx> 49 #include <basegfx/tools/canvastools.hxx> 50 #include <basegfx/numeric/ftools.hxx> 51 52 #include "dx_graphicsprovider.hxx" 53 #include "dx_winstuff.hxx" 54 #include "dx_canvas.hxx" 55 56 #include <vcl/sysdata.hxx> 57 58 #define CANVAS_TECH "GDI+" 59 #define CANVAS_SERVICE_NAME "com.sun.star.rendering.Canvas." CANVAS_TECH 60 #define CANVAS_IMPLEMENTATION_NAME "com.sun.star.comp.rendering.Canvas." CANVAS_TECH 61 #define BITMAPCANVAS_SERVICE_NAME "com.sun.star.rendering.BitmapCanvas." CANVAS_TECH 62 #define BITMAPCANVAS_IMPLEMENTATION_NAME "com.sun.star.comp.rendering.BitmapCanvas." CANVAS_TECH 63 64 65 using namespace ::com::sun::star; 66 67 namespace dxcanvas 68 { 69 /// Actual canonical implementation of the GraphicsProvider interface 70 class GraphicsProviderImpl : public GraphicsProvider 71 { 72 GraphicsSharedPtr mpGraphics; 73 public: GraphicsProviderImpl(Gdiplus::Graphics * pGraphics)74 explicit GraphicsProviderImpl( Gdiplus::Graphics* pGraphics ) : mpGraphics( pGraphics ) {} getGraphics()75 virtual GraphicsSharedPtr getGraphics() { return mpGraphics; } 76 }; 77 Canvas(const uno::Sequence<uno::Any> & aArguments,const uno::Reference<uno::XComponentContext> & rxContext)78 Canvas::Canvas( const uno::Sequence< uno::Any >& aArguments, 79 const uno::Reference< uno::XComponentContext >& rxContext ) : 80 maArguments(aArguments), 81 mxComponentContext( rxContext ) 82 { 83 } 84 initialize()85 void Canvas::initialize() 86 { 87 // #i64742# Only perform initialization when not in probe mode 88 if( maArguments.getLength() == 0 ) 89 return; 90 91 VERBOSE_TRACE( "Canvas::initialize called" ); 92 93 // At index 1, we expect a HWND handle here, containing a 94 // pointer to a valid window, on which to output 95 // At index 2, we expect the current window bound rect 96 ENSURE_ARG_OR_THROW( maArguments.getLength() >= 6 && 97 maArguments[5].getValueTypeClass() == uno::TypeClass_SEQUENCE, 98 "SpriteCanvas::initialize: wrong number of arguments, or wrong types" ); 99 100 uno::Sequence<sal_Int8> aSeq; 101 maArguments[5] >>= aSeq; 102 103 const SystemGraphicsData* pSysData=reinterpret_cast<const SystemGraphicsData*>(aSeq.getConstArray()); 104 if( !pSysData || !pSysData->hDC ) 105 throw lang::NoSupportException( 106 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 107 "Passed SystemGraphicsData or HDC invalid!")), 108 NULL); 109 110 // setup helper 111 maDeviceHelper.init( pSysData->hDC, 112 *this ); 113 maCanvasHelper.setDevice( *this ); 114 maCanvasHelper.setTarget( 115 GraphicsProviderSharedPtr( 116 new GraphicsProviderImpl( 117 Gdiplus::Graphics::FromHDC(pSysData->hDC)))); 118 119 maArguments.realloc(0); 120 } 121 disposing()122 void SAL_CALL Canvas::disposing() 123 { 124 ::osl::MutexGuard aGuard( m_aMutex ); 125 126 mxComponentContext.clear(); 127 128 // forward to parent 129 CanvasBaseT::disposing(); 130 } 131 getServiceName()132 ::rtl::OUString SAL_CALL Canvas::getServiceName( ) throw (uno::RuntimeException) 133 { 134 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CANVAS_SERVICE_NAME ) ); 135 } 136 BitmapCanvas(const uno::Sequence<uno::Any> & aArguments,const uno::Reference<uno::XComponentContext> & rxContext)137 BitmapCanvas::BitmapCanvas( const uno::Sequence< uno::Any >& aArguments, 138 const uno::Reference< uno::XComponentContext >& rxContext ) : 139 maArguments(aArguments), 140 mxComponentContext( rxContext ), 141 mpTarget() 142 { 143 } 144 initialize()145 void BitmapCanvas::initialize() 146 { 147 // #i64742# Only perform initialization when not in probe mode 148 if( maArguments.getLength() == 0 ) 149 return; 150 151 VERBOSE_TRACE( "BitmapCanvas::initialize called" ); 152 153 // At index 1, we expect a HWND handle here, containing a 154 // pointer to a valid window, on which to output 155 // At index 2, we expect the current window bound rect 156 ENSURE_ARG_OR_THROW( maArguments.getLength() >= 6 && 157 maArguments[5].getValueTypeClass() == uno::TypeClass_SEQUENCE, 158 "SpriteCanvas::initialize: wrong number of arguments, or wrong types" ); 159 160 uno::Sequence<sal_Int8> aSeq; 161 maArguments[5] >>= aSeq; 162 163 const SystemGraphicsData* pSysData=reinterpret_cast<const SystemGraphicsData*>(aSeq.getConstArray()); 164 if( !pSysData || !pSysData->hDC ) 165 throw lang::NoSupportException( 166 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 167 "Passed SystemGraphicsData or HDC invalid!")), 168 NULL); 169 170 // setup helper 171 maDeviceHelper.init( pSysData->hDC, 172 *this ); 173 maCanvasHelper.setDevice( *this ); 174 175 // check whether we can actually provide a BitmapCanvas 176 // here. for this, check whether the HDC has a bitmap 177 // selected. 178 HBITMAP hBmp; 179 hBmp=(HBITMAP)GetCurrentObject(pSysData->hDC, OBJ_BITMAP); 180 if( !hBmp || GetObjectType(pSysData->hDC) != OBJ_MEMDC ) 181 { 182 throw lang::NoSupportException( 183 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 184 "Passed HDC is no mem DC/has no bitmap selected!")), 185 NULL); 186 } 187 188 mpTarget.reset( new DXBitmap( 189 BitmapSharedPtr( 190 Gdiplus::Bitmap::FromHBITMAP( 191 hBmp, 0) ), 192 false )); 193 194 maCanvasHelper.setTarget( mpTarget ); 195 196 maArguments.realloc(0); 197 } 198 disposing()199 void SAL_CALL BitmapCanvas::disposing() 200 { 201 ::osl::MutexGuard aGuard( m_aMutex ); 202 203 mpTarget.reset(); 204 mxComponentContext.clear(); 205 206 // forward to parent 207 BitmapCanvasBaseT::disposing(); 208 } 209 getServiceName()210 ::rtl::OUString SAL_CALL BitmapCanvas::getServiceName( ) throw (uno::RuntimeException) 211 { 212 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( BITMAPCANVAS_SERVICE_NAME ) ); 213 } 214 getBitmap() const215 IBitmapSharedPtr BitmapCanvas::getBitmap() const 216 { 217 return mpTarget; 218 } 219 initCanvas(Canvas * pCanvas)220 static uno::Reference<uno::XInterface> initCanvas( Canvas* pCanvas ) 221 { 222 uno::Reference<uno::XInterface> xRet(static_cast<cppu::OWeakObject*>(pCanvas)); 223 pCanvas->initialize(); 224 return xRet; 225 } 226 227 namespace sdecl = comphelper::service_decl; 228 sdecl::class_<Canvas, sdecl::with_args<true> > serviceImpl1(&initCanvas); 229 const sdecl::ServiceDecl dxCanvasDecl( 230 serviceImpl1, 231 CANVAS_IMPLEMENTATION_NAME, 232 CANVAS_SERVICE_NAME ); 233 initBitmapCanvas(BitmapCanvas * pCanvas)234 static uno::Reference<uno::XInterface> initBitmapCanvas( BitmapCanvas* pCanvas ) 235 { 236 uno::Reference<uno::XInterface> xRet(static_cast<cppu::OWeakObject*>(pCanvas)); 237 pCanvas->initialize(); 238 return xRet; 239 } 240 241 namespace sdecl = comphelper::service_decl; 242 sdecl::class_<BitmapCanvas, sdecl::with_args<true> > serviceImpl2(&initBitmapCanvas); 243 const sdecl::ServiceDecl dxBitmapCanvasDecl( 244 serviceImpl2, 245 BITMAPCANVAS_IMPLEMENTATION_NAME, 246 BITMAPCANVAS_SERVICE_NAME ); 247 } 248 249 // The C shared lib entry points 250 COMPHELPER_SERVICEDECL_EXPORTS2(dxcanvas::dxCanvasDecl, 251 dxcanvas::dxBitmapCanvasDecl); 252