| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 ) ); |
| } |
| |
| } |