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