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 #include <rtl/instance.hxx> 27 #include <osl/getglobalmutex.hxx> 28 #include <osl/diagnose.h> 29 #include <com/sun/star/rendering/InterpolationMode.hpp> 30 #include <vcl/window.hxx> 31 #include <vcl/graph.hxx> 32 #include <vcl/canvastools.hxx> 33 #include <basegfx/polygon/b2dpolypolygon.hxx> 34 35 #include <cppcanvas/vclfactory.hxx> 36 37 #include <implbitmapcanvas.hxx> 38 #include <implspritecanvas.hxx> 39 #include <implpolypolygon.hxx> 40 #include <implbitmap.hxx> 41 #include <implrenderer.hxx> 42 #include <impltext.hxx> 43 #include <implsprite.hxx> 44 45 46 using namespace ::com::sun::star; 47 48 namespace cppcanvas 49 { 50 /* Singleton handling */ 51 struct InitInstance 52 { operator ()cppcanvas::InitInstance53 VCLFactory* operator()() 54 { 55 return new VCLFactory(); 56 } 57 }; 58 getInstance()59 VCLFactory& VCLFactory::getInstance() 60 { 61 return *rtl_Instance< VCLFactory, InitInstance, ::osl::MutexGuard, 62 ::osl::GetGlobalMutex >::create( 63 InitInstance(), ::osl::GetGlobalMutex()); 64 } 65 VCLFactory()66 VCLFactory::VCLFactory() 67 { 68 } 69 ~VCLFactory()70 VCLFactory::~VCLFactory() 71 { 72 } 73 createCanvas(const::Window & rVCLWindow)74 BitmapCanvasSharedPtr VCLFactory::createCanvas( const ::Window& rVCLWindow ) 75 { 76 return BitmapCanvasSharedPtr( 77 new internal::ImplBitmapCanvas( 78 uno::Reference< rendering::XBitmapCanvas >( 79 rVCLWindow.GetCanvas(), 80 uno::UNO_QUERY) ) ); 81 } 82 createCanvas(const uno::Reference<rendering::XBitmapCanvas> & xCanvas)83 BitmapCanvasSharedPtr VCLFactory::createCanvas( const uno::Reference< rendering::XBitmapCanvas >& xCanvas ) 84 { 85 return BitmapCanvasSharedPtr( 86 new internal::ImplBitmapCanvas( xCanvas ) ); 87 } 88 createSpriteCanvas(const::Window & rVCLWindow) const89 SpriteCanvasSharedPtr VCLFactory::createSpriteCanvas( const ::Window& rVCLWindow ) const 90 { 91 return SpriteCanvasSharedPtr( 92 new internal::ImplSpriteCanvas( 93 uno::Reference< rendering::XSpriteCanvas >( 94 rVCLWindow.GetSpriteCanvas(), 95 uno::UNO_QUERY) ) ); 96 } 97 createSpriteCanvas(const uno::Reference<rendering::XSpriteCanvas> & xCanvas) const98 SpriteCanvasSharedPtr VCLFactory::createSpriteCanvas( const uno::Reference< rendering::XSpriteCanvas >& xCanvas ) const 99 { 100 return SpriteCanvasSharedPtr( 101 new internal::ImplSpriteCanvas( xCanvas ) ); 102 } 103 createFullscreenSpriteCanvas(const::Window & rVCLWindow,const Size & rFullscreenSize) const104 SpriteCanvasSharedPtr VCLFactory::createFullscreenSpriteCanvas( const ::Window& rVCLWindow, 105 const Size& rFullscreenSize ) const 106 { 107 return SpriteCanvasSharedPtr( 108 new internal::ImplSpriteCanvas( 109 uno::Reference< rendering::XSpriteCanvas >( 110 rVCLWindow.GetFullscreenSpriteCanvas( rFullscreenSize ), 111 uno::UNO_QUERY) ) ); 112 } 113 createPolyPolygon(const CanvasSharedPtr & rCanvas,const::Polygon & rPoly) const114 PolyPolygonSharedPtr VCLFactory::createPolyPolygon( const CanvasSharedPtr& rCanvas, 115 const ::Polygon& rPoly ) const 116 { 117 OSL_ENSURE( rCanvas.get() != NULL && 118 rCanvas->getUNOCanvas().is(), 119 "VCLFactory::createPolyPolygon(): Invalid canvas" ); 120 121 if( rCanvas.get() == NULL ) 122 return PolyPolygonSharedPtr(); 123 124 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 125 if( !xCanvas.is() ) 126 return PolyPolygonSharedPtr(); 127 128 return PolyPolygonSharedPtr( 129 new internal::ImplPolyPolygon( rCanvas, 130 ::vcl::unotools::xPolyPolygonFromPolygon( 131 xCanvas->getDevice(), 132 rPoly) ) ); 133 } 134 createPolyPolygon(const CanvasSharedPtr & rCanvas,const::PolyPolygon & rPolyPoly) const135 PolyPolygonSharedPtr VCLFactory::createPolyPolygon( const CanvasSharedPtr& rCanvas, 136 const ::PolyPolygon& rPolyPoly ) const 137 { 138 OSL_ENSURE( rCanvas.get() != NULL && 139 rCanvas->getUNOCanvas().is(), 140 "VCLFactory::createPolyPolygon(): Invalid canvas" ); 141 142 if( rCanvas.get() == NULL ) 143 return PolyPolygonSharedPtr(); 144 145 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 146 if( !xCanvas.is() ) 147 return PolyPolygonSharedPtr(); 148 149 return PolyPolygonSharedPtr( 150 new internal::ImplPolyPolygon( rCanvas, 151 ::vcl::unotools::xPolyPolygonFromPolyPolygon( 152 xCanvas->getDevice(), 153 rPolyPoly) ) ); 154 } 155 createBitmap(const CanvasSharedPtr & rCanvas,const::Size & rSize) const156 BitmapSharedPtr VCLFactory::createBitmap( const CanvasSharedPtr& rCanvas, 157 const ::Size& rSize ) const 158 { 159 OSL_ENSURE( rCanvas.get() != NULL && 160 rCanvas->getUNOCanvas().is(), 161 "VCLFactory::createBitmap(): Invalid canvas" ); 162 163 if( rCanvas.get() == NULL ) 164 return BitmapSharedPtr(); 165 166 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 167 if( !xCanvas.is() ) 168 return BitmapSharedPtr(); 169 170 return BitmapSharedPtr( 171 new internal::ImplBitmap( rCanvas, 172 xCanvas->getDevice()->createCompatibleBitmap( 173 ::vcl::unotools::integerSize2DFromSize(rSize) ) ) ); 174 } 175 createAlphaBitmap(const CanvasSharedPtr & rCanvas,const::Size & rSize) const176 BitmapSharedPtr VCLFactory::createAlphaBitmap( const CanvasSharedPtr& rCanvas, 177 const ::Size& rSize ) const 178 { 179 OSL_ENSURE( rCanvas.get() != NULL && 180 rCanvas->getUNOCanvas().is(), 181 "VCLFactory::createBitmap(): Invalid canvas" ); 182 183 if( rCanvas.get() == NULL ) 184 return BitmapSharedPtr(); 185 186 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 187 if( !xCanvas.is() ) 188 return BitmapSharedPtr(); 189 190 return BitmapSharedPtr( 191 new internal::ImplBitmap( rCanvas, 192 xCanvas->getDevice()->createCompatibleAlphaBitmap( 193 ::vcl::unotools::integerSize2DFromSize(rSize) ) ) ); 194 } 195 createBitmap(const CanvasSharedPtr & rCanvas,const::Bitmap & rBitmap) const196 BitmapSharedPtr VCLFactory::createBitmap( const CanvasSharedPtr& rCanvas, 197 const ::Bitmap& rBitmap ) const 198 { 199 OSL_ENSURE( rCanvas.get() != NULL && 200 rCanvas->getUNOCanvas().is(), 201 "VCLFactory::createBitmap(): Invalid canvas" ); 202 203 if( rCanvas.get() == NULL ) 204 return BitmapSharedPtr(); 205 206 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 207 if( !xCanvas.is() ) 208 return BitmapSharedPtr(); 209 210 return BitmapSharedPtr( new internal::ImplBitmap( rCanvas, 211 ::vcl::unotools::xBitmapFromBitmap( 212 xCanvas->getDevice(), 213 rBitmap) ) ); 214 } 215 createBitmap(const CanvasSharedPtr & rCanvas,const::BitmapEx & rBmpEx) const216 BitmapSharedPtr VCLFactory::createBitmap( const CanvasSharedPtr& rCanvas, 217 const ::BitmapEx& rBmpEx ) const 218 { 219 OSL_ENSURE( rCanvas.get() != NULL && 220 rCanvas->getUNOCanvas().is(), 221 "VCLFactory::createBitmap(): Invalid canvas" ); 222 223 if( rCanvas.get() == NULL ) 224 return BitmapSharedPtr(); 225 226 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 227 if( !xCanvas.is() ) 228 return BitmapSharedPtr(); 229 230 return BitmapSharedPtr( new internal::ImplBitmap( rCanvas, 231 ::vcl::unotools::xBitmapFromBitmapEx( 232 xCanvas->getDevice(), 233 rBmpEx) ) ); 234 } 235 createRenderer(const CanvasSharedPtr & rCanvas,const::Graphic & rGraphic,const Renderer::Parameters & rParms) const236 RendererSharedPtr VCLFactory::createRenderer( const CanvasSharedPtr& rCanvas, 237 const ::Graphic& rGraphic, 238 const Renderer::Parameters& rParms ) const 239 { 240 OSL_ENSURE( rCanvas.get() != NULL && 241 rCanvas->getUNOCanvas().is(), 242 "VCLFactory::createRenderer(): Invalid canvas" ); 243 244 if( rCanvas.get() == NULL ) 245 return RendererSharedPtr(); 246 247 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 248 if( !xCanvas.is() ) 249 return RendererSharedPtr(); 250 251 if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) 252 return RendererSharedPtr( new internal::ImplRenderer( rCanvas, 253 rGraphic.GetGDIMetaFile(), 254 rParms ) ); 255 else 256 return RendererSharedPtr( new internal::ImplRenderer( rCanvas, 257 rGraphic.GetBitmapEx(), 258 rParms ) ); 259 } 260 createRenderer(const CanvasSharedPtr & rCanvas,const::GDIMetaFile & rMtf,const Renderer::Parameters & rParms) const261 RendererSharedPtr VCLFactory::createRenderer( const CanvasSharedPtr& rCanvas, 262 const ::GDIMetaFile& rMtf, 263 const Renderer::Parameters& rParms ) const 264 { 265 return RendererSharedPtr( new internal::ImplRenderer( rCanvas, 266 rMtf, 267 rParms ) ); 268 } 269 createAnimatedSprite(const SpriteCanvasSharedPtr & rCanvas,const::Animation & rAnim) const270 SpriteSharedPtr VCLFactory::createAnimatedSprite( const SpriteCanvasSharedPtr& rCanvas, const ::Animation& rAnim ) const 271 { 272 OSL_ENSURE( rCanvas.get() != NULL && 273 rCanvas->getUNOCanvas().is(), 274 "VCLFactory::createAnimatedSprite(): Invalid canvas" ); 275 276 if( rCanvas.get() == NULL ) 277 return SpriteSharedPtr(); 278 279 uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); 280 if( !xCanvas.is() ) 281 return SpriteSharedPtr(); 282 283 uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas( rCanvas->getUNOSpriteCanvas() ); 284 if( !xSpriteCanvas.is() ) 285 return SpriteSharedPtr(); 286 287 if( rAnim.IsEmpty() ) 288 return SpriteSharedPtr(); 289 290 internal::ImplSpriteCanvas* pSpriteCanvas = dynamic_cast< internal::ImplSpriteCanvas* >( rCanvas.get() ); 291 if( !pSpriteCanvas ) 292 return SpriteSharedPtr(); 293 294 const sal_uInt16 nBitmaps( rAnim.Count() ); 295 uno::Sequence< uno::Reference< rendering::XBitmap > > aBitmapSequence( nBitmaps ); 296 uno::Reference< rendering::XBitmap >* pBitmaps = aBitmapSequence.getArray(); 297 298 unsigned int i; 299 BitmapEx aBmpEx; 300 BitmapEx aRestoreBuffer; 301 aBmpEx.SetSizePixel( rAnim.GetDisplaySizePixel() ); 302 aRestoreBuffer.SetSizePixel( rAnim.GetDisplaySizePixel() ); 303 aBmpEx.Erase( ::Color( 255, 0,0,0 ) ); // clear alpha channel 304 aRestoreBuffer = aBmpEx; 305 const Point aEmptyPoint; 306 307 for( i=0; i<nBitmaps; ++i ) 308 { 309 const AnimationBitmap& rAnimBmp( rAnim.Get((sal_uInt16)i) ); 310 311 // Handle dispose according to GIF spec: a 312 // DISPOSE_PREVIOUS does _not_ mean to revert to the 313 // previous frame, but to revert to the last frame with 314 // DISPOSE_NOT 315 316 // dispose previous 317 if( rAnimBmp.eDisposal == DISPOSE_BACK ) 318 { 319 // simply clear bitmap to transparent 320 aBmpEx.Erase( ::Color( 255, 0,0,0 ) ); 321 } 322 else if( rAnimBmp.eDisposal == DISPOSE_PREVIOUS ) 323 { 324 // copy in last known full frame 325 aBmpEx = aRestoreBuffer; 326 } 327 // I have exactly _no_ idea what DISPOSE_FULL is supposed 328 // to do. It's apparently not set anywhere in our code 329 OSL_ENSURE( rAnimBmp.eDisposal!=DISPOSE_FULL, 330 "VCLFactory::createAnimatedSprite(): Somebody set the deprecated DISPOSE_FULL at the Animation" ); 331 332 // update display 333 aBmpEx.CopyPixel( Rectangle( rAnimBmp.aPosPix, 334 rAnimBmp.aSizePix ), 335 Rectangle( aEmptyPoint, 336 rAnimBmp.aSizePix ), 337 &rAnimBmp.aBmpEx ); 338 339 // store last DISPOSE_NOT frame, for later 340 // DISPOSE_PREVIOUS updates 341 if( rAnimBmp.eDisposal == DISPOSE_NOT ) 342 aRestoreBuffer = aBmpEx; 343 344 pBitmaps[i] = ::vcl::unotools::xBitmapFromBitmapEx( 345 xCanvas->getDevice(), 346 aBmpEx); 347 } 348 349 return pSpriteCanvas->createSpriteFromBitmaps( aBitmapSequence, 350 rendering::InterpolationMode::NEAREST_NEIGHBOR ); 351 } 352 createText(const CanvasSharedPtr & rCanvas,const::rtl::OUString & rText) const353 TextSharedPtr VCLFactory::createText( const CanvasSharedPtr& rCanvas, const ::rtl::OUString& rText ) const 354 { 355 return TextSharedPtr( new internal::ImplText( rCanvas, 356 rText ) ); 357 } 358 359 } 360