blob: 9245f536a3813b86617e08578076e4c39cbdb1f7 [file] [log] [blame]
/**************************************************************
*
* 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 ) );
}
}