/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * <http://www.openoffice.org/license.html> * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_cppcanvas.hxx" #include <rtl/instance.hxx> #include <osl/getglobalmutex.hxx> #include <osl/diagnose.h> #include <com/sun/star/rendering/InterpolationMode.hpp> #include <vcl/window.hxx> #include <vcl/graph.hxx> #include <vcl/canvastools.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <cppcanvas/vclfactory.hxx> #include <implbitmapcanvas.hxx> #include <implspritecanvas.hxx> #include <implpolypolygon.hxx> #include <implbitmap.hxx> #include <implrenderer.hxx> #include <impltext.hxx> #include <implsprite.hxx> using namespace ::com::sun::star; namespace cppcanvas { /* Singleton handling */ struct InitInstance { VCLFactory* operator()() { return new VCLFactory(); } }; VCLFactory& VCLFactory::getInstance() { return *rtl_Instance< VCLFactory, InitInstance, ::osl::MutexGuard, ::osl::GetGlobalMutex >::create( InitInstance(), ::osl::GetGlobalMutex()); } VCLFactory::VCLFactory() { } VCLFactory::~VCLFactory() { } BitmapCanvasSharedPtr VCLFactory::createCanvas( const ::Window& rVCLWindow ) { return BitmapCanvasSharedPtr( new internal::ImplBitmapCanvas( uno::Reference< rendering::XBitmapCanvas >( rVCLWindow.GetCanvas(), uno::UNO_QUERY) ) ); } BitmapCanvasSharedPtr VCLFactory::createCanvas( const uno::Reference< rendering::XBitmapCanvas >& xCanvas ) { return BitmapCanvasSharedPtr( new internal::ImplBitmapCanvas( xCanvas ) ); } SpriteCanvasSharedPtr VCLFactory::createSpriteCanvas( const ::Window& rVCLWindow ) const { return SpriteCanvasSharedPtr( new internal::ImplSpriteCanvas( uno::Reference< rendering::XSpriteCanvas >( rVCLWindow.GetSpriteCanvas(), uno::UNO_QUERY) ) ); } SpriteCanvasSharedPtr VCLFactory::createSpriteCanvas( const uno::Reference< rendering::XSpriteCanvas >& xCanvas ) const { return SpriteCanvasSharedPtr( new internal::ImplSpriteCanvas( xCanvas ) ); } SpriteCanvasSharedPtr VCLFactory::createFullscreenSpriteCanvas( const ::Window& rVCLWindow, const Size& rFullscreenSize ) const { return SpriteCanvasSharedPtr( new internal::ImplSpriteCanvas( uno::Reference< rendering::XSpriteCanvas >( rVCLWindow.GetFullscreenSpriteCanvas( rFullscreenSize ), uno::UNO_QUERY) ) ); } PolyPolygonSharedPtr VCLFactory::createPolyPolygon( const CanvasSharedPtr& rCanvas, const ::Polygon& rPoly ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createPolyPolygon(): Invalid canvas" ); if( rCanvas.get() == NULL ) return PolyPolygonSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return PolyPolygonSharedPtr(); return PolyPolygonSharedPtr( new internal::ImplPolyPolygon( rCanvas, ::vcl::unotools::xPolyPolygonFromPolygon( xCanvas->getDevice(), rPoly) ) ); } PolyPolygonSharedPtr VCLFactory::createPolyPolygon( const CanvasSharedPtr& rCanvas, const ::PolyPolygon& rPolyPoly ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createPolyPolygon(): Invalid canvas" ); if( rCanvas.get() == NULL ) return PolyPolygonSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return PolyPolygonSharedPtr(); return PolyPolygonSharedPtr( new internal::ImplPolyPolygon( rCanvas, ::vcl::unotools::xPolyPolygonFromPolyPolygon( xCanvas->getDevice(), rPolyPoly) ) ); } BitmapSharedPtr VCLFactory::createBitmap( const CanvasSharedPtr& rCanvas, const ::Size& rSize ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createBitmap(): Invalid canvas" ); if( rCanvas.get() == NULL ) return BitmapSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return BitmapSharedPtr(); return BitmapSharedPtr( new internal::ImplBitmap( rCanvas, xCanvas->getDevice()->createCompatibleBitmap( ::vcl::unotools::integerSize2DFromSize(rSize) ) ) ); } BitmapSharedPtr VCLFactory::createAlphaBitmap( const CanvasSharedPtr& rCanvas, const ::Size& rSize ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createBitmap(): Invalid canvas" ); if( rCanvas.get() == NULL ) return BitmapSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return BitmapSharedPtr(); return BitmapSharedPtr( new internal::ImplBitmap( rCanvas, xCanvas->getDevice()->createCompatibleAlphaBitmap( ::vcl::unotools::integerSize2DFromSize(rSize) ) ) ); } BitmapSharedPtr VCLFactory::createBitmap( const CanvasSharedPtr& rCanvas, const ::Bitmap& rBitmap ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createBitmap(): Invalid canvas" ); if( rCanvas.get() == NULL ) return BitmapSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return BitmapSharedPtr(); return BitmapSharedPtr( new internal::ImplBitmap( rCanvas, ::vcl::unotools::xBitmapFromBitmap( xCanvas->getDevice(), rBitmap) ) ); } BitmapSharedPtr VCLFactory::createBitmap( const CanvasSharedPtr& rCanvas, const ::BitmapEx& rBmpEx ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createBitmap(): Invalid canvas" ); if( rCanvas.get() == NULL ) return BitmapSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return BitmapSharedPtr(); return BitmapSharedPtr( new internal::ImplBitmap( rCanvas, ::vcl::unotools::xBitmapFromBitmapEx( xCanvas->getDevice(), rBmpEx) ) ); } RendererSharedPtr VCLFactory::createRenderer( const CanvasSharedPtr& rCanvas, const ::Graphic& rGraphic, const Renderer::Parameters& rParms ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createRenderer(): Invalid canvas" ); if( rCanvas.get() == NULL ) return RendererSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return RendererSharedPtr(); if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) return RendererSharedPtr( new internal::ImplRenderer( rCanvas, rGraphic.GetGDIMetaFile(), rParms ) ); else return RendererSharedPtr( new internal::ImplRenderer( rCanvas, rGraphic.GetBitmapEx(), rParms ) ); } RendererSharedPtr VCLFactory::createRenderer( const CanvasSharedPtr& rCanvas, const ::GDIMetaFile& rMtf, const Renderer::Parameters& rParms ) const { return RendererSharedPtr( new internal::ImplRenderer( rCanvas, rMtf, rParms ) ); } SpriteSharedPtr VCLFactory::createAnimatedSprite( const SpriteCanvasSharedPtr& rCanvas, const ::Animation& rAnim ) const { OSL_ENSURE( rCanvas.get() != NULL && rCanvas->getUNOCanvas().is(), "VCLFactory::createAnimatedSprite(): Invalid canvas" ); if( rCanvas.get() == NULL ) return SpriteSharedPtr(); uno::Reference< rendering::XCanvas > xCanvas( rCanvas->getUNOCanvas() ); if( !xCanvas.is() ) return SpriteSharedPtr(); uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas( rCanvas->getUNOSpriteCanvas() ); if( !xSpriteCanvas.is() ) return SpriteSharedPtr(); if( rAnim.IsEmpty() ) return SpriteSharedPtr(); internal::ImplSpriteCanvas* pSpriteCanvas = dynamic_cast< internal::ImplSpriteCanvas* >( rCanvas.get() ); if( !pSpriteCanvas ) return SpriteSharedPtr(); const sal_uInt16 nBitmaps( rAnim.Count() ); uno::Sequence< uno::Reference< rendering::XBitmap > > aBitmapSequence( nBitmaps ); uno::Reference< rendering::XBitmap >* pBitmaps = aBitmapSequence.getArray(); unsigned int i; BitmapEx aBmpEx; BitmapEx aRestoreBuffer; aBmpEx.SetSizePixel( rAnim.GetDisplaySizePixel() ); aRestoreBuffer.SetSizePixel( rAnim.GetDisplaySizePixel() ); aBmpEx.Erase( ::Color( 255, 0,0,0 ) ); // clear alpha channel aRestoreBuffer = aBmpEx; const Point aEmptyPoint; for( i=0; i<nBitmaps; ++i ) { const AnimationBitmap& rAnimBmp( rAnim.Get((sal_uInt16)i) ); // Handle dispose according to GIF spec: a // DISPOSE_PREVIOUS does _not_ mean to revert to the // previous frame, but to revert to the last frame with // DISPOSE_NOT // dispose previous if( rAnimBmp.eDisposal == DISPOSE_BACK ) { // simply clear bitmap to transparent aBmpEx.Erase( ::Color( 255, 0,0,0 ) ); } else if( rAnimBmp.eDisposal == DISPOSE_PREVIOUS ) { // copy in last known full frame aBmpEx = aRestoreBuffer; } // I have exactly _no_ idea what DISPOSE_FULL is supposed // to do. It's apparently not set anywhere in our code OSL_ENSURE( rAnimBmp.eDisposal!=DISPOSE_FULL, "VCLFactory::createAnimatedSprite(): Somebody set the deprecated DISPOSE_FULL at the Animation" ); // update display aBmpEx.CopyPixel( Rectangle( rAnimBmp.aPosPix, rAnimBmp.aSizePix ), Rectangle( aEmptyPoint, rAnimBmp.aSizePix ), &rAnimBmp.aBmpEx ); // store last DISPOSE_NOT frame, for later // DISPOSE_PREVIOUS updates if( rAnimBmp.eDisposal == DISPOSE_NOT ) aRestoreBuffer = aBmpEx; pBitmaps[i] = ::vcl::unotools::xBitmapFromBitmapEx( xCanvas->getDevice(), aBmpEx); } return pSpriteCanvas->createSpriteFromBitmaps( aBitmapSequence, rendering::InterpolationMode::NEAREST_NEIGHBOR ); } TextSharedPtr VCLFactory::createText( const CanvasSharedPtr& rCanvas, const ::rtl::OUString& rText ) const { return TextSharedPtr( new internal::ImplText( rCanvas, rText ) ); } }