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 <canvas/verbosetrace.hxx> 29 #include <canvas/canvastools.hxx> 30 #include <tools/diagnose_ex.h> 31 32 #include <osl/mutex.hxx> 33 34 #include <com/sun/star/registry/XRegistryKey.hpp> 35 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 36 #include <com/sun/star/uno/XComponentContext.hpp> 37 #include <com/sun/star/lang/NoSupportException.hpp> 38 39 #include <toolkit/helper/vclunohelper.hxx> 40 41 #include <basegfx/matrix/b2dhommatrix.hxx> 42 #include <basegfx/point/b2dpoint.hxx> 43 #include <basegfx/tools/canvastools.hxx> 44 #include <basegfx/numeric/ftools.hxx> 45 46 #include "cairo_spritecanvas.hxx" 47 48 using namespace ::cairo; 49 using namespace ::com::sun::star; 50 51 namespace cairocanvas 52 { SpriteCanvas(const uno::Sequence<uno::Any> & aArguments,const uno::Reference<uno::XComponentContext> & rxContext)53 SpriteCanvas::SpriteCanvas( const uno::Sequence< uno::Any >& aArguments, 54 const uno::Reference< uno::XComponentContext >& rxContext ) : 55 maArguments(aArguments), 56 mxComponentContext( rxContext ) 57 { 58 } 59 initialize()60 void SpriteCanvas::initialize() 61 { 62 VERBOSE_TRACE("CairoSpriteCanvas created %p\n", this); 63 64 // #i64742# Only call initialize when not in probe mode 65 if( maArguments.getLength() == 0 ) 66 return; 67 68 /* maArguments: 69 0: ptr to creating instance (Window or VirtualDevice) 70 1: SystemEnvData as a streamed Any (or empty for VirtualDevice) 71 2: current bounds of creating instance 72 3: bool, denoting always on top state for Window (always false for VirtualDevice) 73 4: XWindow for creating Window (or empty for VirtualDevice) 74 5: SystemGraphicsData as a streamed Any 75 */ 76 ENSURE_ARG_OR_THROW( maArguments.getLength() >= 4 && 77 maArguments[0].getValueTypeClass() == uno::TypeClass_HYPER && 78 maArguments[4].getValueTypeClass() == uno::TypeClass_INTERFACE, 79 "CairoSpriteCanvas::initialize: wrong number of arguments, or wrong types" ); 80 81 awt::Rectangle aRect; 82 maArguments[2] >>= aRect; 83 84 sal_Bool bIsFullscreen( sal_False ); 85 maArguments[3] >>= bIsFullscreen; 86 87 uno::Reference< awt::XWindow > xParentWindow; 88 maArguments[4] >>= xParentWindow; 89 90 Window* pParentWindow = VCLUnoHelper::GetWindow(xParentWindow); 91 if( !pParentWindow ) 92 throw lang::NoSupportException( 93 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 94 "Parent window not VCL window, or canvas out-of-process!")), 95 NULL); 96 97 bool bHasXRender = IsCairoWorking(pParentWindow); 98 ENSURE_ARG_OR_THROW( bHasXRender == true, 99 "CairoSpriteCanvas::SpriteCanvas: No RENDER extension" ); 100 101 Size aPixelSize( pParentWindow->GetOutputSizePixel() ); 102 const ::basegfx::B2ISize aSize( aPixelSize.Width(), 103 aPixelSize.Height() ); 104 105 ENSURE_ARG_OR_THROW( pParentWindow != NULL, 106 "CairoSpriteCanvas::initialize: invalid Window pointer" ); 107 108 // setup helper 109 maDeviceHelper.init( *pParentWindow, 110 *this, 111 aSize, 112 bIsFullscreen ); 113 114 setWindow(uno::Reference<awt::XWindow2>(xParentWindow, uno::UNO_QUERY_THROW)); 115 116 maCanvasHelper.init( maRedrawManager, 117 *this, 118 aSize ); 119 120 maArguments.realloc(0); 121 } 122 disposing()123 void SAL_CALL SpriteCanvas::disposing() 124 { 125 ::osl::MutexGuard aGuard( m_aMutex ); 126 127 mxComponentContext.clear(); 128 129 // forward to parent 130 SpriteCanvasBaseT::disposing(); 131 } 132 showBuffer(::sal_Bool bUpdateAll)133 ::sal_Bool SAL_CALL SpriteCanvas::showBuffer( ::sal_Bool bUpdateAll ) throw (uno::RuntimeException) 134 { 135 return updateScreen( bUpdateAll ); 136 } 137 switchBuffer(::sal_Bool bUpdateAll)138 ::sal_Bool SAL_CALL SpriteCanvas::switchBuffer( ::sal_Bool bUpdateAll ) throw (uno::RuntimeException) 139 { 140 return updateScreen( bUpdateAll ); 141 } 142 updateScreen(sal_Bool bUpdateAll)143 sal_Bool SAL_CALL SpriteCanvas::updateScreen( sal_Bool bUpdateAll ) throw (uno::RuntimeException) 144 { 145 ::osl::MutexGuard aGuard( m_aMutex ); 146 147 // avoid repaints on hidden window (hidden: not mapped to 148 // screen). Return failure, since the screen really has _not_ 149 // been updated (caller should try again later) 150 return !mbIsVisible ? false : maCanvasHelper.updateScreen( 151 ::basegfx::unotools::b2IRectangleFromAwtRectangle(maBounds), 152 bUpdateAll, 153 mbSurfaceDirty); 154 } 155 getServiceName()156 ::rtl::OUString SAL_CALL SpriteCanvas::getServiceName( ) throw (uno::RuntimeException) 157 { 158 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SPRITECANVAS_SERVICE_NAME ) ); 159 } 160 getSurface()161 SurfaceSharedPtr SpriteCanvas::getSurface() 162 { 163 return maDeviceHelper.getBufferSurface(); 164 } 165 createSurface(const::basegfx::B2ISize & rSize,Content aContent)166 SurfaceSharedPtr SpriteCanvas::createSurface( const ::basegfx::B2ISize& rSize, Content aContent ) 167 { 168 return maDeviceHelper.createSurface( rSize, aContent ); 169 } 170 createSurface(::Bitmap & rBitmap)171 SurfaceSharedPtr SpriteCanvas::createSurface( ::Bitmap& rBitmap ) 172 { 173 BitmapSystemData aData; 174 if( rBitmap.GetSystemData( aData ) ) { 175 const Size& rSize = rBitmap.GetSizePixel(); 176 177 return maDeviceHelper.createSurface( aData, rSize ); 178 } 179 180 return SurfaceSharedPtr(); 181 } 182 changeSurface(bool,bool)183 SurfaceSharedPtr SpriteCanvas::changeSurface( bool, bool ) 184 { 185 // non-modifiable surface here 186 return SurfaceSharedPtr(); 187 } 188 getOutputDevice()189 OutputDevice* SpriteCanvas::getOutputDevice() 190 { 191 return maDeviceHelper.getOutputDevice(); 192 } 193 getBufferSurface()194 SurfaceSharedPtr SpriteCanvas::getBufferSurface() 195 { 196 return maDeviceHelper.getBufferSurface(); 197 } 198 getWindowSurface()199 SurfaceSharedPtr SpriteCanvas::getWindowSurface() 200 { 201 return maDeviceHelper.getWindowSurface(); 202 } 203 getSizePixel()204 const ::basegfx::B2ISize& SpriteCanvas::getSizePixel() 205 { 206 return maDeviceHelper.getSizePixel(); 207 } 208 setSizePixel(const::basegfx::B2ISize & rSize)209 void SpriteCanvas::setSizePixel( const ::basegfx::B2ISize& rSize ) 210 { 211 maCanvasHelper.setSize( rSize ); 212 // re-set background surface, in case it needed recreation 213 maCanvasHelper.setSurface( maDeviceHelper.getBufferSurface(), 214 false ); 215 } 216 flush()217 void SpriteCanvas::flush() 218 { 219 maDeviceHelper.flush(); 220 } 221 repaint(const SurfaceSharedPtr & pSurface,const rendering::ViewState & viewState,const rendering::RenderState & renderState)222 bool SpriteCanvas::repaint( const SurfaceSharedPtr& pSurface, 223 const rendering::ViewState& viewState, 224 const rendering::RenderState& renderState ) 225 { 226 return maCanvasHelper.repaint( pSurface, viewState, renderState ); 227 } 228 } 229