diff options
Diffstat (limited to 'canvas/inc/base')
-rw-r--r-- | canvas/inc/base/basemutexhelper.hxx | 63 | ||||
-rw-r--r-- | canvas/inc/base/bitmapcanvasbase.hxx | 125 | ||||
-rw-r--r-- | canvas/inc/base/bufferedgraphicdevicebase.hxx | 258 | ||||
-rw-r--r-- | canvas/inc/base/cachedprimitivebase.hxx | 104 | ||||
-rw-r--r-- | canvas/inc/base/canvasbase.hxx | 451 | ||||
-rw-r--r-- | canvas/inc/base/canvascustomspritebase.hxx | 261 | ||||
-rw-r--r-- | canvas/inc/base/canvascustomspritehelper.hxx | 217 | ||||
-rw-r--r-- | canvas/inc/base/disambiguationhelper.hxx | 79 | ||||
-rw-r--r-- | canvas/inc/base/graphicdevicebase.hxx | 348 | ||||
-rw-r--r-- | canvas/inc/base/integerbitmapbase.hxx | 109 | ||||
-rw-r--r-- | canvas/inc/base/sprite.hxx | 110 | ||||
-rw-r--r-- | canvas/inc/base/spritecanvasbase.hxx | 190 | ||||
-rw-r--r-- | canvas/inc/base/spritesurface.hxx | 67 |
13 files changed, 2382 insertions, 0 deletions
diff --git a/canvas/inc/base/basemutexhelper.hxx b/canvas/inc/base/basemutexhelper.hxx new file mode 100644 index 000000000..eba03cd9a --- /dev/null +++ b/canvas/inc/base/basemutexhelper.hxx @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <sal/config.h> + +#include <osl/mutex.hxx> + +/* Definition of the BaseMutexHelper class */ + +namespace canvas +{ + /** Base class, initializing its own baseclass with m_aMutex. + + This is necessary to make the CanvasBase, GraphicDeviceBase, + etc. classes freely combinable - letting them perform this + initialization would prohibit deriving e.g. CanvasBase from + GraphicDeviceBase. + */ + template< class Base > class BaseMutexHelper : public Base + { + protected: + /** Construct BaseMutexHelper + + This method is the whole purpose of this template: + initializing a base class with the provided m_aMutex + member (the WeakComponentImplHelper templates need that, + as they require the lifetime of the mutex to extend + theirs). + */ + BaseMutexHelper() : + Base( m_aMutex ) + { + } + + virtual void disposeThis() {} + + mutable osl::Mutex m_aMutex; + + private: + virtual void SAL_CALL disposing() override + { disposeThis(); } + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/bitmapcanvasbase.hxx b/canvas/inc/base/bitmapcanvasbase.hxx new file mode 100644 index 000000000..efbf58f55 --- /dev/null +++ b/canvas/inc/base/bitmapcanvasbase.hxx @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <base/canvasbase.hxx> +#include <com/sun/star/geometry/IntegerSize2D.hpp> + +namespace com::sun::star::rendering { class XBitmapCanvas; } + +namespace canvas +{ + /** Helper template to handle XBitmapCanvas method forwarding to + BitmapCanvasHelper + + Use this helper to handle the XBitmapCanvas part of your + implementation. + + @tpl Base + Base class to use, most probably one of the + WeakComponentImplHelperN templates with the appropriate + interfaces. At least XBitmapCanvas should be among them (why + else would you use this template, then?). Base class must have + a Base( const Mutex& ) constructor (like the + WeakComponentImplHelperN templates have). + + @tpl CanvasHelper + Canvas helper implementation for the backend in question + + @tpl Mutex + Lock strategy to use. Defaults to using the + BaseMutex-provided lock. Every time one of the methods is + entered, an object of type Mutex is created with m_aMutex as + the sole parameter, and destroyed again when the method scope + is left. + + @tpl UnambiguousBase + Optional unambiguous base class for XInterface of Base. It's + sometimes necessary to specify this parameter, e.g. if Base + derives from multiple UNO interface (were each provides its + own version of XInterface, making the conversion ambiguous) + + @see CanvasBase for further contractual requirements towards + the CanvasHelper type, and some examples. + */ + template< class Base, + class CanvasHelper, + class Mutex=::osl::MutexGuard, + class UnambiguousBase=css::uno::XInterface > class BitmapCanvasBase : + public CanvasBase< Base, CanvasHelper, Mutex, UnambiguousBase > + { + public: + typedef CanvasBase< Base, CanvasHelper, Mutex, UnambiguousBase > BaseType; + + // XBitmap + virtual css::geometry::IntegerSize2D SAL_CALL getSize( ) override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maCanvasHelper.getSize(); + } + + virtual sal_Bool SAL_CALL hasAlpha( ) override + { + return true; + } + + virtual css::uno::Reference< css::rendering::XBitmap > SAL_CALL getScaledBitmap( const css::geometry::RealSize2D& newSize, + sal_Bool beFast ) override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maCanvasHelper.getScaledBitmap( newSize, beFast ); + } + + }; + + template< class Base, + class CanvasHelper, + class Mutex=::osl::MutexGuard, + class UnambiguousBase = css::uno::XInterface > class BitmapCanvasBase2 : + public BitmapCanvasBase< Base, CanvasHelper, Mutex, UnambiguousBase > + { + typedef BitmapCanvasBase< Base, CanvasHelper, Mutex, UnambiguousBase > + BaseType; + + public: + // XBitmapCanvas + virtual void SAL_CALL copyRect( const css::uno::Reference< css::rendering::XBitmapCanvas >& sourceCanvas, + const css::geometry::RealRectangle2D& sourceRect, + const css::rendering::ViewState& sourceViewState, + const css::rendering::RenderState& sourceRenderState, + const css::geometry::RealRectangle2D& destRect, + const css::rendering::ViewState& destViewState, + const css::rendering::RenderState& destRenderState ) override + { + tools::verifyArgs(sourceCanvas, sourceRect, sourceViewState, sourceRenderState, + destRect, destViewState, destRenderState, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + + typename BaseType::BaseType::MutexType aGuard( BaseType::m_aMutex ); + + BaseType::BaseType::mbSurfaceDirty = true; + } + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/bufferedgraphicdevicebase.hxx b/canvas/inc/base/bufferedgraphicdevicebase.hxx new file mode 100644 index 000000000..067d37a98 --- /dev/null +++ b/canvas/inc/base/bufferedgraphicdevicebase.hxx @@ -0,0 +1,258 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <com/sun/star/awt/XWindow2.hpp> + +#include <canvas/canvastools.hxx> +#include <base/graphicdevicebase.hxx> + +namespace com::sun::star::awt { class XTopWindow; } + + +/* Definition of BufferedGraphicDeviceBase class */ + +namespace canvas +{ + /** Helper template base class for XGraphicDevice implementations + on windows. + + Use this base class if your target device is a + window. Additionally to GraphicDeviceBase, this template + provides an implementation of the awt::XWindowListener + interface, to receive notifications about state changes of the + associated window. + + @tpl Base + Base class to use, most probably one of the + WeakComponentImplHelperN templates with the appropriate + interfaces. At least XGraphicDevice should be among them (why else + would you use this template, then?). Base class must have an + Base( const Mutex& ) constructor (like the + WeakComponentImplHelperN templates have). As the very least, + the base class must be derived from uno::XInterface, as some + error reporting mechanisms rely on that. + + @tpl DeviceHelper + Device helper implementation for the backend in question. This + object will be held as a member of this template class, and + basically gets forwarded all XGraphicDevice API calls that + could not be handled generically. + + @tpl Mutex + Lock strategy to use. Defaults to using the + BaseMutex-provided lock. Every time one of the methods is + entered, an object of type Mutex is created with m_aMutex as + the sole parameter, and destroyed again when the method scope + is left. + + @tpl UnambiguousBase + Optional unambiguous base class for XInterface of Base. It's + sometimes necessary to specify this parameter, e.g. if Base + derives from multiple UNO interface (were each provides its + own version of XInterface, making the conversion ambiguous) + */ + template< class Base, + class DeviceHelper, + class Mutex=::osl::MutexGuard, + class UnambiguousBase = css::uno::XInterface > class BufferedGraphicDeviceBase : + public GraphicDeviceBase< Base, DeviceHelper, Mutex, UnambiguousBase > + { + public: + typedef GraphicDeviceBase< Base, DeviceHelper, Mutex, UnambiguousBase > BaseType; + typedef Mutex MutexType; + + BufferedGraphicDeviceBase() : + mxWindow(), + maBounds(), + mbIsVisible( false ), + mbIsTopLevel( false ) + { + BaseType::maPropHelper.addProperties( + PropertySetHelper::MakeMap("Window", + [this] () { return this->getXWindow(); })); + } + + // XGraphicDevice + virtual css::uno::Reference< css::rendering::XBufferController > SAL_CALL getBufferController( ) override + { + return this; + } + + // XBufferController + virtual ::sal_Int32 SAL_CALL createBuffers( ::sal_Int32 nBuffers ) override + { + tools::verifyRange( nBuffers, sal_Int32(1) ); + + return 1; + } + + virtual void SAL_CALL destroyBuffers( ) override + { + } + + virtual sal_Bool SAL_CALL showBuffer( sal_Bool bUpdateAll ) override + { + MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maDeviceHelper.showBuffer( mbIsVisible, bUpdateAll ); + } + + virtual sal_Bool SAL_CALL switchBuffer( sal_Bool bUpdateAll ) override + { + MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maDeviceHelper.switchBuffer( mbIsVisible, bUpdateAll ); + } + + + /** Set corresponding canvas window + + Use this method to set the window this canvas displays + on. Comes in handy when the canvas needs to adapt size or + output position to the changing window. + + Whenever the bounds of the window change, <code>void + notifySizeUpdate( const awt::Rectangle& rBounds )</code> + is called, with rBounds the window bound rect relative to + the frame window. + */ + void setWindow( const css::uno::Reference< css::awt::XWindow2 >& rWindow ) + { + if( mxWindow.is() ) + mxWindow->removeWindowListener( this ); + + mxWindow = rWindow; + + if( mxWindow.is() ) + { + mbIsVisible = mxWindow->isVisible(); + mbIsTopLevel = + css::uno::Reference< css::awt::XTopWindow >( + mxWindow, + css::uno::UNO_QUERY ).is(); + + maBounds = transformBounds( mxWindow->getPosSize() ); + mxWindow->addWindowListener( this ); + } + } + + css::uno::Any getXWindow() const + { + return css::uno::makeAny(mxWindow); + } + + virtual void disposeThis() override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + if( mxWindow.is() ) + { + mxWindow->removeWindowListener(this); + mxWindow.clear(); + } + + // pass on to base class + BaseType::disposeThis(); + } + + css::awt::Rectangle transformBounds( const css::awt::Rectangle& rBounds ) + { + // notifySizeUpdate's bounds are relative to the toplevel + // window + if( !mbIsTopLevel ) + return tools::getAbsoluteWindowRect( + rBounds, + mxWindow ); + else + return css::awt::Rectangle( 0,0,rBounds.Width,rBounds.Height ); + } + + void boundsChanged( const css::awt::WindowEvent& e ) + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + const css::awt::Rectangle& rNewBounds( + transformBounds( css::awt::Rectangle( e.X, + e.Y, + e.Width, + e.Height ))); + + if( rNewBounds.X != maBounds.X || + rNewBounds.Y != maBounds.Y || + rNewBounds.Width != maBounds.Width || + rNewBounds.Height != maBounds.Height ) + { + maBounds = rNewBounds; + BaseType::maDeviceHelper.notifySizeUpdate( maBounds ); + } + } + + // XWindowListener + virtual void disposeEventSource( const css::lang::EventObject& Source ) override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + if( Source.Source == mxWindow ) + mxWindow.clear(); + + BaseType::disposeEventSource(Source); + } + + virtual void SAL_CALL windowResized( const css::awt::WindowEvent& e ) override + { + boundsChanged( e ); + } + + virtual void SAL_CALL windowMoved( const css::awt::WindowEvent& e ) override + { + boundsChanged( e ); + } + + virtual void SAL_CALL windowShown( const css::lang::EventObject& ) override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + mbIsVisible = true; + } + + virtual void SAL_CALL windowHidden( const css::lang::EventObject& ) override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + mbIsVisible = false; + } + + protected: + css::uno::Reference< css::awt::XWindow2 > mxWindow; + + /// Current bounds of the owning Window + css::awt::Rectangle maBounds; + + /// True, if the window this canvas is contained in, is visible + bool mbIsVisible; + + private: + /// True, if the window this canvas is contained in, is a toplevel window + bool mbIsTopLevel; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/cachedprimitivebase.hxx b/canvas/inc/base/cachedprimitivebase.hxx new file mode 100644 index 000000000..ffdee6ee2 --- /dev/null +++ b/canvas/inc/base/cachedprimitivebase.hxx @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/rendering/XCachedPrimitive.hpp> +#include <com/sun/star/rendering/ViewState.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> + +#include <canvas/canvastoolsdllapi.h> + +namespace com::sun::star::rendering { class XCanvas; } + +/* Definition of CachedPrimitiveBase class */ + +namespace canvas +{ + typedef cppu::WeakComponentImplHelper< css::rendering::XCachedPrimitive, + css::lang::XServiceInfo > CachedPrimitiveBase_Base; + + /** Base class, providing common functionality for implementers of + the XCachedPrimitive interface. + */ + class CANVASTOOLS_DLLPUBLIC CachedPrimitiveBase: + public cppu::BaseMutex, public CachedPrimitiveBase_Base + { + public: + + /** Create an XCachedPrimitive for given target canvas + + @param rUsedViewState + The viewstate the original object was rendered with + + @param rTarget + The target canvas the repaint should happen on. + */ + CachedPrimitiveBase( const css::rendering::ViewState& rUsedViewState, + const css::uno::Reference< css::rendering::XCanvas >& rTarget ); + + /// Dispose all internal references + virtual void SAL_CALL disposing() override; + + // XCachedPrimitive + virtual ::sal_Int8 SAL_CALL redraw( const css::rendering::ViewState& aState ) override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + protected: + virtual ~CachedPrimitiveBase() override; // we're a ref-counted UNO class. _We_ destroy ourselves. + + private: + CachedPrimitiveBase( const CachedPrimitiveBase& ) = delete; + CachedPrimitiveBase& operator=( const CachedPrimitiveBase& ) = delete; + + /** Actually perform the requested redraw. + + Clients must override this method, instead of the public + redraw() one. + + @param rNewState + The viewstate to redraw with + + @param rOldState + The viewstate this cache object was created with. + + @param rTargetCanvas + Target canvas to render to. + + @param bSameViewTransform + When true, rNewState and rOldState have the same transformation. + */ + virtual ::sal_Int8 doRedraw( const css::rendering::ViewState& rNewState, + const css::rendering::ViewState& rOldState, + const css::uno::Reference< css::rendering::XCanvas >& rTargetCanvas, + bool bSameViewTransform ) = 0; + + css::rendering::ViewState maUsedViewState; + css::uno::Reference< css::rendering::XCanvas > mxTarget; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/canvasbase.hxx b/canvas/inc/base/canvasbase.hxx new file mode 100644 index 000000000..323460a10 --- /dev/null +++ b/canvas/inc/base/canvasbase.hxx @@ -0,0 +1,451 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/rendering/TextDirection.hpp> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <verifyinput.hxx> + +namespace com::sun::star::beans { struct PropertyValue; } +namespace com::sun::star::geometry { class XMapping2D; } +namespace com::sun::star::rendering { class XBitmap; } +namespace com::sun::star::rendering { class XCachedPrimitive; } +namespace com::sun::star::rendering { class XCanvasFont; } +namespace com::sun::star::rendering { class XGraphicDevice; } +namespace com::sun::star::rendering { class XPolyPolygon2D; } +namespace com::sun::star::rendering { class XTextLayout; } +namespace com::sun::star::rendering { struct FontInfo; } +namespace com::sun::star::rendering { struct StringContext; } + + +namespace canvas +{ + /** Helper template to handle XCanvas method forwarding to CanvasHelper + + Use this helper to handle the XCanvas part of your + implementation. In theory, we could have provided CanvasHelper + and CanvasBase as a single template, but that would duplicate + a lot of code now residing in CanvasHelper only. + + This template basically interposes itself between the full + interface you implement (i.e. not restricted to XCanvas. The + problem with UNO partial interface implementation actually is, + that you cannot do it the plain way, since deriving from a + common base subclass always introduces the whole set of pure + virtuals, that your baseclass helper just overridden) and your + implementation class. You then only have to implement the + functionality <em>besides</em> XCanvas. + + <pre> + Example: + typedef ::cppu::WeakComponentImplHelper < css::rendering::XSpriteCanvas, + css::lang::XInitialization, + css::lang::XServiceInfo, + css::lang::XServiceName > CanvasBase_Base; + typedef ::canvas::internal::CanvasBase< CanvasBase_Base, CanvasHelper > ExampleCanvas_Base; + + class ExampleCanvas : public ExampleCanvas_Base, + public SpriteSurface, + public RepaintTarget + { + }; + </pre> + + @tpl Base + Base class to use, most probably the + WeakComponentImplHelper template with the appropriate + interfaces. At least XCanvas should be among them (why else + would you use this template, then?). Base class must have an + Base( const Mutex& ) constructor (like the + WeakComponentImplHelper template has). As the very least, + the base class must be derived from uno::XInterface, as some + error reporting mechanisms rely on that. + + @tpl CanvasHelper + Canvas helper implementation for the backend in question. This + object will be held as a member of this template class, and + basically gets forwarded all XCanvas API calls. Furthermore, + every time the canvas API semantically changes the content of + the canvas, CanvasHelper::modifying() will get called + (<em>before</em> the actual modification takes place). + + @tpl Mutex + Lock strategy to use. Defaults to using the + BaseMutex-provided lock. Every time one of the methods is + entered, an object of type Mutex is created with m_aMutex as + the sole parameter, and destroyed again when the method scope + is left. + + @tpl UnambiguousBase + Optional unambiguous base class for XInterface of Base. It's + sometimes necessary to specify this parameter, e.g. if Base + derives from multiple UNO interface (were each provides its + own version of XInterface, making the conversion ambiguous) + */ + template< class Base, + class CanvasHelper, + class Mutex=::osl::MutexGuard, + class UnambiguousBase=css::uno::XInterface > class CanvasBase : + public Base + { + public: + typedef Base BaseType; + typedef Mutex MutexType; + typedef UnambiguousBase UnambiguousBaseType; + + /** Create CanvasBase + */ + CanvasBase() : + maCanvasHelper(), + mbSurfaceDirty( true ) + { + } + + virtual void disposeThis() override + { + MutexType aGuard( BaseType::m_aMutex ); + + maCanvasHelper.disposing(); + + // pass on to base class + BaseType::disposeThis(); + } + + // XCanvas + virtual void SAL_CALL clear() override + { + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + maCanvasHelper.clear(); + } + + virtual void SAL_CALL drawPoint(const css::geometry::RealPoint2D& aPoint, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState) override + { + tools::verifyArgs(aPoint, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + } + + virtual void SAL_CALL drawLine(const css::geometry::RealPoint2D& aStartPoint, + const css::geometry::RealPoint2D& aEndPoint, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState) override + { + tools::verifyArgs(aStartPoint, aEndPoint, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + maCanvasHelper.drawLine( this, aStartPoint, aEndPoint, viewState, renderState ); + } + + virtual void SAL_CALL drawBezier( const css::geometry::RealBezierSegment2D& aBezierSegment, + const css::geometry::RealPoint2D& aEndPoint, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState ) override + { + tools::verifyArgs(aBezierSegment, aEndPoint, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + maCanvasHelper.drawBezier( this, aBezierSegment, aEndPoint, viewState, renderState ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + drawPolyPolygon(const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.drawPolyPolygon( this, xPolyPolygon, viewState, renderState ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + strokePolyPolygon(const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState, + const css::rendering::StrokeAttributes& strokeAttributes) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, strokeAttributes, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.strokePolyPolygon( this, xPolyPolygon, viewState, renderState, strokeAttributes ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + strokeTexturedPolyPolygon( const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState, + const css::uno::Sequence< css::rendering::Texture >& textures, + const css::rendering::StrokeAttributes& strokeAttributes ) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, strokeAttributes, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.strokeTexturedPolyPolygon( this, xPolyPolygon, viewState, renderState, textures, strokeAttributes ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + strokeTextureMappedPolyPolygon( const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState, + const css::uno::Sequence< css::rendering::Texture >& textures, + const css::uno::Reference< css::geometry::XMapping2D >& xMapping, + const css::rendering::StrokeAttributes& strokeAttributes ) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, textures, xMapping, strokeAttributes, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.strokeTextureMappedPolyPolygon( this, xPolyPolygon, viewState, renderState, textures, xMapping, strokeAttributes ); + } + + virtual css::uno::Reference< css::rendering::XPolyPolygon2D > SAL_CALL + queryStrokeShapes( const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState, + const css::rendering::StrokeAttributes& strokeAttributes ) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, strokeAttributes, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.queryStrokeShapes( this, xPolyPolygon, viewState, renderState, strokeAttributes ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + fillPolyPolygon(const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.fillPolyPolygon( this, xPolyPolygon, viewState, renderState ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + fillTexturedPolyPolygon(const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState, + const css::uno::Sequence< css::rendering::Texture >& textures) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, textures, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.fillTexturedPolyPolygon( this, xPolyPolygon, viewState, renderState, textures ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + fillTextureMappedPolyPolygon( const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState, + const css::uno::Sequence< css::rendering::Texture >& textures, + const css::uno::Reference< css::geometry::XMapping2D >& xMapping ) override + { + tools::verifyArgs(xPolyPolygon, viewState, renderState, textures, xMapping, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.fillTextureMappedPolyPolygon( this, xPolyPolygon, viewState, renderState, textures, xMapping ); + } + + + virtual css::uno::Reference< css::rendering::XCanvasFont > SAL_CALL + createFont( const css::rendering::FontRequest& fontRequest, + const css::uno::Sequence< css::beans::PropertyValue >& extraFontProperties, + const css::geometry::Matrix2D& fontMatrix ) override + { + tools::verifyArgs(fontRequest, + // dummy, to keep argPos in sync + fontRequest, + fontMatrix, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + return maCanvasHelper.createFont( this, fontRequest, extraFontProperties, fontMatrix ); + } + + + virtual css::uno::Sequence< css::rendering::FontInfo > SAL_CALL + queryAvailableFonts( const css::rendering::FontInfo& aFilter, + const css::uno::Sequence< css::beans::PropertyValue >& aFontProperties ) override + { + tools::verifyArgs(aFilter, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + return maCanvasHelper.queryAvailableFonts( this, aFilter, aFontProperties ); + } + + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + drawText(const css::rendering::StringContext& text, + const css::uno::Reference< css::rendering::XCanvasFont >& xFont, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState, + sal_Int8 textDirection) override + { + tools::verifyArgs(xFont, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + tools::verifyRange( textDirection, + css::rendering::TextDirection::WEAK_LEFT_TO_RIGHT, + css::rendering::TextDirection::STRONG_RIGHT_TO_LEFT ); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.drawText( this, text, xFont, viewState, renderState, textDirection ); + } + + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + drawTextLayout(const css::uno::Reference< css::rendering::XTextLayout >& laidOutText, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState) override + { + tools::verifyArgs(laidOutText, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.drawTextLayout( this, laidOutText, viewState, renderState ); + } + + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + drawBitmap( const css::uno::Reference< css::rendering::XBitmap >& xBitmap, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState ) override + { + tools::verifyArgs(xBitmap, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.drawBitmap( this, xBitmap, viewState, renderState ); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + drawBitmapModulated( const css::uno::Reference< css::rendering::XBitmap >& xBitmap, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState ) override + { + tools::verifyArgs(xBitmap, viewState, renderState, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + mbSurfaceDirty = true; + + return maCanvasHelper.drawBitmapModulated( this, xBitmap, viewState, renderState ); + } + + virtual css::uno::Reference< css::rendering::XGraphicDevice > SAL_CALL + getDevice() override + { + MutexType aGuard( BaseType::m_aMutex ); + + return maCanvasHelper.getDevice(); + } + + protected: + ~CanvasBase() {} // we're a ref-counted UNO class. _We_ destroy ourselves. + + CanvasHelper maCanvasHelper; + mutable bool mbSurfaceDirty; + + private: + CanvasBase( const CanvasBase& ) = delete; + CanvasBase& operator=( const CanvasBase& ) = delete; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/canvascustomspritebase.hxx b/canvas/inc/base/canvascustomspritebase.hxx new file mode 100644 index 000000000..c47f232e0 --- /dev/null +++ b/canvas/inc/base/canvascustomspritebase.hxx @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <com/sun/star/rendering/XCanvas.hpp> + +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <basegfx/range/b2drange.hxx> +#include <base/integerbitmapbase.hxx> +#include <base/bitmapcanvasbase.hxx> + +namespace com::sun::star::rendering { class XPolyPolygon2D; } + +namespace canvas +{ + /** Helper template to handle XCustomSprite method forwarding to + CanvasCustomSpriteHelper + + Use this helper to handle the XCustomSprite part of your + implementation. + + @tpl Base + Base class to use, most probably one of the + WeakComponentImplHelperN templates with the appropriate + interfaces. At least XCustomSprite and Sprite should be among + them (why else would you use this template, then?). Base class + must have a Base( const Mutex& ) constructor (like the + WeakComponentImplHelperN templates have). + + @tpl SpriteHelper + Sprite helper implementation for the backend in question + + @tpl CanvasHelper + Canvas helper implementation for the backend in question + + @tpl Mutex + Lock strategy to use. Defaults to using the + BaseMutex-provided lock. Every time one of the methods is + entered, an object of type Mutex is created with m_aMutex as + the sole parameter, and destroyed again when the method scope + is left. + + @tpl UnambiguousBase + Optional unambiguous base class for XInterface of Base. It's + sometimes necessary to specify this parameter, e.g. if Base + derives from multiple UNO interface (were each provides its + own version of XInterface, making the conversion ambiguous) + + @see CanvasCustomSpriteHelper for further contractual + requirements towards the SpriteHelper type, and some examples. + */ + template< class Base, + class SpriteHelper, + class CanvasHelper, + class Mutex=::osl::MutexGuard, + class UnambiguousBase = css::uno::XInterface > class CanvasCustomSpriteBase : + public IntegerBitmapBase< BitmapCanvasBase2<Base, CanvasHelper, Mutex, UnambiguousBase> > + { + public: + typedef IntegerBitmapBase< BitmapCanvasBase2<Base, CanvasHelper, Mutex, UnambiguousBase> > BaseType; + + CanvasCustomSpriteBase() : + maSpriteHelper() + { + } + + /** Object is being disposed. + + Called from the cppu helper base, to notify disposal of + this object. Already releases all internal references. + + @derive when overriding this method in derived classes, + <em>always</em> call the base class' method! + */ + virtual void disposeThis() override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.disposing(); + + // pass on to base class + BaseType::disposeThis(); + } + + // XCanvas: selectively override base's methods here, for opacity tracking + virtual void SAL_CALL clear() override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.clearingContent( this ); + + // and forward to base class, which handles the actual rendering + return BaseType::clear(); + } + + virtual css::uno::Reference< css::rendering::XCachedPrimitive > SAL_CALL + drawBitmap( const css::uno::Reference< css::rendering::XBitmap >& xBitmap, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState ) override + { + tools::verifyArgs(xBitmap, viewState, renderState, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.checkDrawBitmap( this, xBitmap, viewState, renderState ); + + // and forward to base class, which handles the actual rendering + return BaseType::drawBitmap( xBitmap, + viewState, + renderState ); + } + + // TODO(F3): If somebody uses the XIntegerBitmap methods to + // clear pixel (setting alpha != 1.0 there), or a compositing + // mode results in similar alpha, maSpriteHelper might + // erroneously report fully opaque sprites. Effectively, all + // render methods must be overridden here; or better, + // functionality provided at the baseclass. + + // XSprite + virtual void SAL_CALL setAlpha( double alpha ) override + { + tools::verifyRange( alpha, 0.0, 1.0 ); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.setAlpha( this, alpha ); + } + + virtual void SAL_CALL move( const css::geometry::RealPoint2D& aNewPos, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState ) override + { + tools::verifyArgs(aNewPos, viewState, renderState, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.move( this, aNewPos, viewState, renderState ); + } + + virtual void SAL_CALL transform( const css::geometry::AffineMatrix2D& aTransformation ) override + { + tools::verifyArgs(aTransformation, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.transform( this, aTransformation ); + } + + virtual void SAL_CALL clip( const css::uno::Reference< css::rendering::XPolyPolygon2D >& aClip ) override + { + // NULL xClip explicitly allowed here (to clear clipping) + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.clip( this, aClip ); + } + + virtual void SAL_CALL setPriority( double nPriority ) override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.setPriority( this, nPriority ); + } + + virtual void SAL_CALL show() override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.show( this ); + } + + virtual void SAL_CALL hide() override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maSpriteHelper.hide( this ); + } + + // XCustomSprite + virtual css::uno::Reference< css::rendering::XCanvas > SAL_CALL + getContentCanvas() override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return this; + } + + // Sprite + virtual bool isAreaUpdateOpaque( const ::basegfx::B2DRange& rUpdateArea ) const override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return maSpriteHelper.isAreaUpdateOpaque( rUpdateArea ); + } + + virtual bool isContentChanged() const override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::mbSurfaceDirty; + } + + virtual ::basegfx::B2DPoint getPosPixel() const override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return maSpriteHelper.getPosPixel(); + } + + virtual ::basegfx::B2DVector getSizePixel() const override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return maSpriteHelper.getSizePixel(); + } + + virtual ::basegfx::B2DRange getUpdateArea() const override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return maSpriteHelper.getUpdateArea(); + } + + virtual double getPriority() const override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return maSpriteHelper.getPriority(); + } + + protected: + SpriteHelper maSpriteHelper; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/canvascustomspritehelper.hxx b/canvas/inc/base/canvascustomspritehelper.hxx new file mode 100644 index 000000000..32fcf6452 --- /dev/null +++ b/canvas/inc/base/canvascustomspritehelper.hxx @@ -0,0 +1,217 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <base/spritesurface.hxx> +#include <canvas/canvastoolsdllapi.h> + +namespace com::sun::star::geometry { struct AffineMatrix2D; } +namespace com::sun::star::geometry { struct RealPoint2D; } +namespace com::sun::star::geometry { struct RealSize2D; } +namespace com::sun::star::rendering { class XBitmap; } +namespace com::sun::star::rendering { class XPolyPolygon2D; } +namespace com::sun::star::rendering { struct RenderState; } +namespace com::sun::star::rendering { struct ViewState; } + + +namespace canvas +{ + /* Definition of CanvasCustomSpriteHelper class */ + + /** Base class for an XSprite helper implementation - to be used + in concert with CanvasCustomSpriteBase + */ + class CANVASTOOLS_DLLPUBLIC CanvasCustomSpriteHelper + { + public: + CanvasCustomSpriteHelper(); + virtual ~CanvasCustomSpriteHelper() {} + + /** Init helper + + @param rSpriteSize + Requested size of the sprite, as passed to the + XSpriteCanvas::createCustomSprite() method + + @param rOwningSpriteCanvas + The XSpriteCanvas this sprite is displayed on + */ + void init( const css::geometry::RealSize2D& rSpriteSize, + const SpriteSurface::Reference& rOwningSpriteCanvas ); + + /** Object is being disposed, release all internal references + + @derive when overriding this method in derived classes, + <em>always</em> call the base class' method! + */ + void disposing(); + + // XCanvas + /// need to call this method for XCanvas::clear(), for opacity tracking + void clearingContent( const Sprite::Reference& rSprite ); + + /// need to call this method for XCanvas::drawBitmap(), for opacity tracking + void checkDrawBitmap( const Sprite::Reference& rSprite, + const css::uno::Reference< css::rendering::XBitmap >& xBitmap, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState ); + + // XSprite + void setAlpha( const Sprite::Reference& rSprite, + double alpha ); + void move( const Sprite::Reference& rSprite, + const css::geometry::RealPoint2D& aNewPos, + const css::rendering::ViewState& viewState, + const css::rendering::RenderState& renderState ); + void transform( const Sprite::Reference& rSprite, + const css::geometry::AffineMatrix2D& aTransformation ); + void clip( const Sprite::Reference& rSprite, + const css::uno::Reference< css::rendering::XPolyPolygon2D >& aClip ); + void setPriority( const Sprite::Reference& rSprite, + double nPriority ); + void show( const Sprite::Reference& rSprite ); + void hide( const Sprite::Reference& rSprite ); + + // Sprite + bool isAreaUpdateOpaque( const ::basegfx::B2DRange& rUpdateArea ) const; + const ::basegfx::B2DPoint& getPosPixel() const { return maPosition; } + const ::basegfx::B2DVector& getSizePixel() const { return maSize; } + ::basegfx::B2DRange getUpdateArea() const; + double getPriority() const { return mfPriority; } + + // redraw must be implemented by derived - non sensible default implementation + // void redraw( const Sprite::Reference& rSprite, + // const ::basegfx::B2DPoint& rPos ) const; + + + // Helper methods for derived classes + + + /// Calc sprite update area from given raw sprite bounds + ::basegfx::B2DRange getUpdateArea( const ::basegfx::B2DRange& rUntransformedSpriteBounds ) const; + + /** Returns true, if sprite content bitmap is fully opaque. + + This does not take clipping or transformation into + account, but only denotes that the sprite bitmap's alpha + channel is all 1.0 + */ + bool isContentFullyOpaque() const { return mbIsContentFullyOpaque; } + + /// Returns true, if transformation has changed since last transformUpdated() call + bool hasTransformChanged() const { return mbTransformDirty; } + + /// Retrieve current alpha value + double getAlpha() const { return mfAlpha; } + + /// Retrieve current clip + const css::uno::Reference< + css::rendering::XPolyPolygon2D >& getClip() const { return mxClipPoly; } + + const ::basegfx::B2DHomMatrix& getTransformation() const { return maTransform; } + + /// Retrieve current activation state + bool isActive() const { return mbActive; } + + protected: + /** Notifies that caller is again in sync with current transformation + + const, but modifies state visible to derived + classes. beware of passing this information to the + outside! + */ + void transformUpdated() const { mbTransformDirty=false; } + + private: + CanvasCustomSpriteHelper( const CanvasCustomSpriteHelper& ) = delete; + CanvasCustomSpriteHelper& operator=( const CanvasCustomSpriteHelper& ) = delete; + + /** Called to convert an API polygon to a basegfx polygon + + @derive Needs to be provided by backend-specific code + */ + virtual ::basegfx::B2DPolyPolygon polyPolygonFromXPolyPolygon2D( + css::uno::Reference< css::rendering::XPolyPolygon2D >& xPoly ) const = 0; + + /** Update clip information from current state + + This method recomputes the maCurrClipBounds and + mbIsCurrClipRectangle members from the current clip and + transformation. IFF the clip changed from rectangular to + rectangular again, this method issues a sequence of + optimized SpriteSurface::updateSprite() calls. + + @return true, if SpriteSurface::updateSprite() was already + called within this method. + */ + bool updateClipState( const Sprite::Reference& rSprite ); + + + /// Owning sprite canvas + SpriteSurface::Reference mpSpriteCanvas; + + /** Currently active clip area. + + This member is either empty, denoting that the current + clip shows the full sprite content, or contains a + rectangular subarea of the sprite, outside of which + the sprite content is fully clipped. + + @see mbIsCurrClipRectangle + */ + ::basegfx::B2DRange maCurrClipBounds; + + // sprite state + ::basegfx::B2DPoint maPosition; + ::basegfx::B2DVector maSize; + ::basegfx::B2DHomMatrix maTransform; + css::uno::Reference< css::rendering::XPolyPolygon2D > mxClipPoly; + double mfPriority; + double mfAlpha; + bool mbActive; // true, if not hidden + + /** If true, denotes that the current sprite clip is a true + rectangle, i.e. maCurrClipBounds <em>exactly</em> + describes the visible area of the sprite. + + @see maCurrClipBounds + */ + bool mbIsCurrClipRectangle; + + /** Redraw speedup. + + When true, this flag denotes that the current sprite + content is fully opaque, thus, that blits to the screen do + neither have to take alpha into account, nor prepare any + background for the sprite area. + */ + mutable bool mbIsContentFullyOpaque; + + /// True, iff maTransform has changed + mutable bool mbTransformDirty; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/disambiguationhelper.hxx b/canvas/inc/base/disambiguationhelper.hxx new file mode 100644 index 000000000..06e6f9af0 --- /dev/null +++ b/canvas/inc/base/disambiguationhelper.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <com/sun/star/lang/EventObject.hpp> +#include <osl/mutex.hxx> + + +/* Definition of the DisambiguationHelper class */ + +namespace canvas +{ + /** Base class, initializing its own baseclass with m_aMutex. + + This is necessary to make the CanvasBase, GraphicDeviceBase, + etc. classes freely combinable - letting them perform this + initialization would prohibit deriving e.g. CanvasBase from + GraphicDeviceBase. + + On top of that, disambiguates XEventListener::disposing and + WeakComponentImplHelper::disposing. + + Having two virtual methods with the same name, and not + overriding them in every derived class, will hide one of + them. Later trying to override the same method, will generate + a new vtable slot, and lead to very hard to spot errors. + */ + template< class Base > class DisambiguationHelper : public Base + { + protected: + /** Construct DisambiguationHelper + + This method is the whole purpose of this template: + initializing a base class with the provided m_aMutex + member (the WeakComponentImplHelper templates need that, + as they require the lifetime of the mutex to extend + theirs). + */ + DisambiguationHelper() : + Base( m_aMutex ) + { + } + + virtual void disposeThis() + {} + /// @throws css::uno::RuntimeException + virtual void disposeEventSource( const css::lang::EventObject& ) + {} + + mutable ::osl::Mutex m_aMutex; + + private: + virtual void SAL_CALL disposing() override + { disposeThis(); } + + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override + { disposeEventSource(Source); } + + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/graphicdevicebase.hxx b/canvas/inc/base/graphicdevicebase.hxx new file mode 100644 index 000000000..3a7c49834 --- /dev/null +++ b/canvas/inc/base/graphicdevicebase.hxx @@ -0,0 +1,348 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <com/sun/star/rendering/XBufferController.hpp> +#include <com/sun/star/rendering/XLinePolyPolygon2D.hpp> +#include <com/sun/star/rendering/XBezierPolyPolygon2D.hpp> +#include <com/sun/star/rendering/XBitmap.hpp> +#include <com/sun/star/rendering/XVolatileBitmap.hpp> + +#include <rtl/ref.hxx> + +#include <parametricpolypolygon.hxx> +#include <propertysethelper.hxx> +#include <verifyinput.hxx> + +namespace com::sun::star::beans { class XPropertySetInfo; } +namespace com::sun::star::lang { class XMultiServiceFactory; } +namespace com::sun::star::rendering { class XColorSpace; } + + +/* Definition of GraphicDeviceBase class */ + +namespace canvas +{ + /** Helper template base class for XGraphicDevice implementations. + + This base class provides partial implementations of the + XGraphicDevice-related interface, such as XColorSpace. + + This template basically interposes itself between the full + interface you implement (i.e. not restricted to XGraphicDevice + etc.). The problem with UNO partial interface implementation + actually is, that you cannot do it the plain way, since + deriving from a common base subclass always introduces the + whole set of pure virtuals, that your baseclass helper just + overridden) and your implementation class. You then only have + to implement the functionality <em>besides</em> + XGraphicDevice. If you want to support the optional debug + XUpdatable interface, also add that to the base classes + (client code will call the corresponding update() method, + whenever a burst of animations is over). + + <pre> + Example: + typedef ::cppu::WeakComponentImplHelper < css::rendering::XGraphicDevice, + css::rendering::XColorSpace, + css::rendering::XPropertySet, + css::lang::XServiceInfo, + css::lang::XServiceName > GraphicDeviceBase_Base; + typedef ::canvas::internal::GraphicDeviceBase< GraphicDeviceBase, DeviceHelper > ExampleDevice_Base; + + class ExampleDevice : public ExampleDevice_Base + { + }; + </pre> + + @tpl Base + Base class to use, most probably the + WeakComponentImplHelper template with the appropriate + interfaces. At least XGraphicDevice should be among them (why else + would you use this template, then?). Base class must have an + Base( const Mutex& ) constructor (like the + WeakComponentImplHelper template has). As the very least, + the base class must be derived from uno::XInterface, as some + error reporting mechanisms rely on that. + + @tpl DeviceHelper + Device helper implementation for the backend in question. This + object will be held as a member of this template class, and + basically gets forwarded all XGraphicDevice API calls that + could not be handled generically. + + @tpl Mutex + Lock strategy to use. Defaults to using the + DisambiguationHelper-provided lock. Every time one of the methods is + entered, an object of type Mutex is created with m_aMutex as + the sole parameter, and destroyed again when the method scope + is left. + + @tpl UnambiguousBase + Optional unambiguous base class for XInterface of Base. It's + sometimes necessary to specify this parameter, e.g. if Base + derives from multiple UNO interface (were each provides its + own version of XInterface, making the conversion ambiguous) + */ + template< class Base, + class DeviceHelper, + class Mutex=::osl::MutexGuard, + class UnambiguousBase=css::uno::XInterface > class GraphicDeviceBase : + public Base + { + public: + typedef Base BaseType; + typedef Mutex MutexType; + typedef UnambiguousBase UnambiguousBaseType; + + typedef ::rtl::Reference< GraphicDeviceBase > Reference; + + GraphicDeviceBase() : + maDeviceHelper(), + maPropHelper(), + mbDumpScreenContent(false) + { + maPropHelper.initProperties( PropertySetHelper::MakeMap + ("HardwareAcceleration", + [this] () { return this->maDeviceHelper.isAccelerated(); } ) + ("DeviceHandle", + [this] () { return this->maDeviceHelper.getDeviceHandle(); } ) + ("SurfaceHandle", + [this] () { return this->maDeviceHelper.getSurfaceHandle(); } ) + ("DumpScreenContent", + [this] () { return this->getDumpScreenContent(); }, + [this] (css::uno::Any const& rAny) { this->setDumpScreenContent(rAny); })); + } + + virtual void disposeThis() override + { + MutexType aGuard( BaseType::m_aMutex ); + + maDeviceHelper.disposing(); + + // pass on to base class + BaseType::disposeThis(); + } + + // XGraphicDevice + virtual css::uno::Reference< css::rendering::XBufferController > SAL_CALL getBufferController( ) override + { + return css::uno::Reference< css::rendering::XBufferController >(); + } + + virtual css::uno::Reference< css::rendering::XColorSpace > SAL_CALL getDeviceColorSpace( ) override + { + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.getColorSpace(); + } + + virtual css::geometry::RealSize2D SAL_CALL getPhysicalResolution() override + { + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.getPhysicalResolution(); + } + + virtual css::geometry::RealSize2D SAL_CALL getPhysicalSize() override + { + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.getPhysicalSize(); + } + + virtual css::uno::Reference< css::rendering::XLinePolyPolygon2D > SAL_CALL createCompatibleLinePolyPolygon( const css::uno::Sequence< css::uno::Sequence< css::geometry::RealPoint2D > >& points ) override + { + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.createCompatibleLinePolyPolygon( this, points ); + } + + virtual css::uno::Reference< css::rendering::XBezierPolyPolygon2D > SAL_CALL createCompatibleBezierPolyPolygon( const css::uno::Sequence< css::uno::Sequence< css::geometry::RealBezierSegment2D > >& points ) override + { + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.createCompatibleBezierPolyPolygon( this, points ); + } + + virtual css::uno::Reference< css::rendering::XBitmap > SAL_CALL createCompatibleBitmap( const css::geometry::IntegerSize2D& size ) override + { + tools::verifyBitmapSize(size, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.createCompatibleBitmap( this, size ); + } + + virtual css::uno::Reference< css::rendering::XVolatileBitmap > SAL_CALL createVolatileBitmap( const css::geometry::IntegerSize2D& size ) override + { + tools::verifyBitmapSize(size, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.createVolatileBitmap( this, size ); + } + + virtual css::uno::Reference< css::rendering::XBitmap > SAL_CALL createCompatibleAlphaBitmap( const css::geometry::IntegerSize2D& size ) override + { + tools::verifyBitmapSize(size, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.createCompatibleAlphaBitmap( this, size ); + } + + virtual css::uno::Reference< css::rendering::XVolatileBitmap > SAL_CALL createVolatileAlphaBitmap( const css::geometry::IntegerSize2D& size ) override + { + tools::verifyBitmapSize(size, + OSL_THIS_FUNC, + static_cast< UnambiguousBaseType* >(this)); + + MutexType aGuard( BaseType::m_aMutex ); + + return maDeviceHelper.createVolatileAlphaBitmap( this, size ); + } + + virtual css::uno::Reference< css::lang::XMultiServiceFactory > SAL_CALL getParametricPolyPolygonFactory( ) override + { + return this; + } + + virtual sal_Bool SAL_CALL hasFullScreenMode( ) override + { + return false; + } + + virtual sal_Bool SAL_CALL enterFullScreenMode( sal_Bool ) override + { + return false; + } + + // XMultiServiceFactory + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance( const OUString& aServiceSpecifier ) override + { + return css::uno::Reference< css::rendering::XParametricPolyPolygon2D >( + ParametricPolyPolygon::create(this, + aServiceSpecifier, + css::uno::Sequence< css::uno::Any >())); + } + + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments( const OUString& aServiceSpecifier, const css::uno::Sequence< css::uno::Any >& Arguments ) override + { + return css::uno::Reference< css::rendering::XParametricPolyPolygon2D >( + ParametricPolyPolygon::create(this, + aServiceSpecifier, + Arguments)); + } + + virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServiceNames( ) override + { + return ParametricPolyPolygon::getAvailableServiceNames(); + } + + + // XUpdatable + virtual void SAL_CALL update() override + { + MutexType aGuard( BaseType::m_aMutex ); + + if( mbDumpScreenContent ) + maDeviceHelper.dumpScreenContent(); + } + + + // XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override + { + MutexType aGuard( BaseType::m_aMutex ); + return maPropHelper.getPropertySetInfo(); + } + + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, + const css::uno::Any& aValue ) override + { + MutexType aGuard( BaseType::m_aMutex ); + maPropHelper.setPropertyValue( aPropertyName, aValue ); + } + + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& aPropertyName ) override + { + MutexType aGuard( BaseType::m_aMutex ); + return maPropHelper.getPropertyValue( aPropertyName ); + } + + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, + const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override + { + MutexType aGuard( BaseType::m_aMutex ); + maPropHelper.addPropertyChangeListener( aPropertyName, + xListener ); + } + + virtual void SAL_CALL removePropertyChangeListener( const OUString& , + const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override + { + } + + virtual void SAL_CALL addVetoableChangeListener( const OUString& aPropertyName, + const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener ) override + { + MutexType aGuard( BaseType::m_aMutex ); + maPropHelper.addVetoableChangeListener( aPropertyName, + xListener ); + } + + virtual void SAL_CALL removeVetoableChangeListener( const OUString& , + const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override + { + } + + protected: + ~GraphicDeviceBase() {} // we're a ref-counted UNO class. _We_ destroy ourselves. + + css::uno::Any getDumpScreenContent() const + { + return css::uno::makeAny( mbDumpScreenContent ); + } + + void setDumpScreenContent( const css::uno::Any& rAny ) + { + // TODO(Q1): this was mbDumpScreenContent = + // rAny.get<bool>(), only that gcc3.3 wouldn't eat it + rAny >>= mbDumpScreenContent; + } + + DeviceHelper maDeviceHelper; + PropertySetHelper maPropHelper; + bool mbDumpScreenContent; + + private: + GraphicDeviceBase( const GraphicDeviceBase& ) = delete; + GraphicDeviceBase& operator=( const GraphicDeviceBase& ) = delete; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/integerbitmapbase.hxx b/canvas/inc/base/integerbitmapbase.hxx new file mode 100644 index 000000000..aca2551f2 --- /dev/null +++ b/canvas/inc/base/integerbitmapbase.hxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <com/sun/star/rendering/IntegerBitmapLayout.hpp> +#include <verifyinput.hxx> +#include <osl/diagnose.h> + + +namespace canvas +{ + /** Helper template to handle XIntegerBitmap method forwarding to + BitmapCanvasHelper + + Use this helper to handle the XIntegerBitmap part of your + implementation. + + @tpl Base + Either BitmapCanvasBase (just XBitmap) or BitmapCanvasBase2 (XBitmap and + XBitmapCanvas). + */ + template< class Base > class IntegerBitmapBase : + public Base + { + public: + // XIntegerBitmap + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getData( css::rendering::IntegerBitmapLayout& bitmapLayout, + const css::geometry::IntegerRectangle2D& rect ) override + { + tools::verifyArgs(rect, + OSL_THIS_FUNC, + static_cast< typename Base::UnambiguousBaseType* >(this)); + tools::verifyIndexRange(rect, Base::getSize() ); + + typename Base::MutexType aGuard( Base::m_aMutex ); + + return Base::maCanvasHelper.getData( bitmapLayout, + rect ); + } + + virtual void SAL_CALL setData( const css::uno::Sequence< sal_Int8 >&, + const css::rendering::IntegerBitmapLayout& bitmapLayout, + const css::geometry::IntegerRectangle2D& rect ) override + { + tools::verifyArgs(bitmapLayout, rect, + OSL_THIS_FUNC, + static_cast< typename Base::UnambiguousBaseType* >(this)); + tools::verifyIndexRange(rect, Base::getSize() ); + + typename Base::MutexType aGuard( Base::m_aMutex ); + + Base::mbSurfaceDirty = true; + } + + virtual void SAL_CALL setPixel( const css::uno::Sequence< sal_Int8 >&, + const css::rendering::IntegerBitmapLayout& bitmapLayout, + const css::geometry::IntegerPoint2D& pos ) override + { + tools::verifyArgs(bitmapLayout, pos, + OSL_THIS_FUNC, + static_cast< typename Base::UnambiguousBaseType* >(this)); + tools::verifyIndexRange(pos, Base::getSize() ); + + typename Base::MutexType aGuard( Base::m_aMutex ); + + Base::mbSurfaceDirty = true; + } + + virtual css::uno::Sequence< sal_Int8 > SAL_CALL getPixel( css::rendering::IntegerBitmapLayout& bitmapLayout, + const css::geometry::IntegerPoint2D& pos ) override + { + tools::verifyArgs(pos, + OSL_THIS_FUNC, + static_cast< typename Base::UnambiguousBaseType* >(this)); + tools::verifyIndexRange(pos, Base::getSize() ); + + typename Base::MutexType aGuard( Base::m_aMutex ); + + return Base::maCanvasHelper.getPixel( bitmapLayout, + pos ); + } + + virtual css::rendering::IntegerBitmapLayout SAL_CALL getMemoryLayout( ) override + { + typename Base::MutexType aGuard( Base::m_aMutex ); + + return Base::maCanvasHelper.getMemoryLayout(); + } + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/sprite.hxx b/canvas/inc/base/sprite.hxx new file mode 100644 index 000000000..8a89c9454 --- /dev/null +++ b/canvas/inc/base/sprite.hxx @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <rtl/ref.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <basegfx/point/b2dpoint.hxx> + +namespace basegfx +{ + class B2DVector; + class B2DRange; +} + +namespace canvas +{ + /* Definition of Sprite interface (as we mix with UNO here, has to + be XInterface - reference holders to a Sprite must be able to + control lifetime of reference target) + */ + + /** Helper interface to connect SpriteCanvas with various + sprite implementations. + + This interface should be implemented from every sprite class, + as it provides essential repaint and update area facilitates. + + @derive typically, each canvas implementation will derive + another interface from this one, that adds rendering + functionality (which, of course, is impossible here in a + generic way) + */ + class Sprite : public css::lang::XComponent + { + public: + typedef ::rtl::Reference< Sprite > Reference; + + /** Query whether sprite update will fully cover the given area. + + Use this method to determine whether any background + content (regardless of static or sprite) needs an update + before rendering this sprite. + + @return true, if sprite redraw will fully overwrite given + area (and thus, the background need not be redrawn + beforehand). + */ + virtual bool isAreaUpdateOpaque( const ::basegfx::B2DRange& rUpdateArea ) const = 0; + + /** Query whether content has changed + */ + virtual bool isContentChanged() const = 0; + + /** Query position of the left, top pixel of the sprite + */ + virtual ::basegfx::B2DPoint getPosPixel() const = 0; + + /** Query size of the sprite in pixel. + */ + virtual ::basegfx::B2DVector getSizePixel() const = 0; + + /** Get area that is currently covered by the sprite + + This area is already adapted to clipping, alpha and + transformation state of this sprite. + */ + virtual ::basegfx::B2DRange getUpdateArea() const = 0; + + /** Query sprite priority + */ + virtual double getPriority() const = 0; + + protected: + ~Sprite() {} + }; + + /** Functor providing a StrictWeakOrdering for sprite references + */ + struct SpriteWeakOrder + { + bool operator()( const Sprite::Reference& rLHS, + const Sprite::Reference& rRHS ) + { + const double nPrioL( rLHS->getPriority() ); + const double nPrioR( rRHS->getPriority() ); + + // if prios are equal, tie-break on ptr value + return nPrioL == nPrioR ? rLHS.get() < rRHS.get() : nPrioL < nPrioR; + } + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/spritecanvasbase.hxx b/canvas/inc/base/spritecanvasbase.hxx new file mode 100644 index 000000000..041a6d3be --- /dev/null +++ b/canvas/inc/base/spritecanvasbase.hxx @@ -0,0 +1,190 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <rtl/ref.hxx> +#include <com/sun/star/rendering/InterpolationMode.hpp> +#include <base/integerbitmapbase.hxx> +#include <base/bitmapcanvasbase.hxx> +#include <spriteredrawmanager.hxx> + +namespace com::sun::star::rendering { class XAnimation; } +namespace com::sun::star::rendering { class XAnimatedSprite; } +namespace com::sun::star::rendering { class XCustomSprite; } +namespace com::sun::star::rendering { class XSprite; } + + +namespace canvas +{ + /** Helper template to handle XIntegerBitmap method forwarding to + BitmapCanvasHelper + + Use this helper to handle the XIntegerBitmap part of your + implementation. + + @tpl Base + Base class to use, most probably one of the + WeakComponentImplHelperN templates with the appropriate + interfaces. At least XSpriteCanvas and SpriteSurface should be + among them (why else would you use this template, then?). Base + class must have a Base( const Mutex& ) constructor (like the + WeakComponentImplHelperN templates have). + + @tpl CanvasHelper + Canvas helper implementation for the backend in question + + @tpl Mutex + Lock strategy to use. Defaults to using the + BaseMutex-provided lock. Every time one of the methods is + entered, an object of type Mutex is created with m_aMutex as + the sole parameter, and destroyed again when the method scope + is left. + + @tpl UnambiguousBase + Optional unambiguous base class for XInterface of Base. It's + sometimes necessary to specify this parameter, e.g. if Base + derives from multiple UNO interface (were each provides its + own version of XInterface, making the conversion ambiguous) + + @see CanvasBase for further contractual requirements towards + the CanvasHelper type, and some examples. + */ + template< class Base, + class CanvasHelper, + class Mutex=::osl::MutexGuard, + class UnambiguousBase = css::uno::XInterface > class SpriteCanvasBase : + public IntegerBitmapBase< BitmapCanvasBase<Base, CanvasHelper, Mutex, UnambiguousBase> > + { + public: + typedef IntegerBitmapBase< BitmapCanvasBase<Base, CanvasHelper, Mutex, UnambiguousBase> > BaseType; + typedef ::rtl::Reference< SpriteCanvasBase > Reference; + + SpriteCanvasBase() : + maRedrawManager() + { + } + + virtual void disposeThis() override + { + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maRedrawManager.disposing(); + + // pass on to base class + BaseType::disposeThis(); + } + + // XSpriteCanvas + virtual css::uno::Reference< css::rendering::XAnimatedSprite > SAL_CALL createSpriteFromAnimation( const css::uno::Reference< css::rendering::XAnimation >& animation ) override + { + tools::verifyArgs(animation, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maCanvasHelper.createSpriteFromAnimation(animation); + } + + virtual css::uno::Reference< css::rendering::XAnimatedSprite > SAL_CALL createSpriteFromBitmaps( const css::uno::Sequence< css::uno::Reference< css::rendering::XBitmap > >& animationBitmaps, + sal_Int8 interpolationMode ) override + { + tools::verifyArgs(animationBitmaps, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + tools::verifyRange( interpolationMode, + css::rendering::InterpolationMode::NEAREST_NEIGHBOR, + css::rendering::InterpolationMode::BEZIERSPLINE4 ); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maCanvasHelper.createSpriteFromBitmaps(animationBitmaps, interpolationMode); + } + + virtual css::uno::Reference< css::rendering::XCustomSprite > SAL_CALL createCustomSprite( const css::geometry::RealSize2D& spriteSize ) override + { + tools::verifySpriteSize(spriteSize, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maCanvasHelper.createCustomSprite(spriteSize); + } + + virtual css::uno::Reference< css::rendering::XSprite > SAL_CALL createClonedSprite( const css::uno::Reference< css::rendering::XSprite >& original ) override + { + tools::verifyArgs(original, + OSL_THIS_FUNC, + static_cast< typename BaseType::UnambiguousBaseType* >(this)); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + return BaseType::maCanvasHelper.createClonedSprite(original); + } + + // SpriteSurface + virtual void showSprite( const Sprite::Reference& rSprite ) override + { + OSL_ASSERT( rSprite.is() ); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maRedrawManager.showSprite( rSprite ); + } + + virtual void hideSprite( const Sprite::Reference& rSprite ) override + { + OSL_ASSERT( rSprite.is() ); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maRedrawManager.hideSprite( rSprite ); + } + + virtual void moveSprite( const Sprite::Reference& rSprite, + const ::basegfx::B2DPoint& rOldPos, + const ::basegfx::B2DPoint& rNewPos, + const ::basegfx::B2DVector& rSpriteSize ) override + { + OSL_ASSERT( rSprite.is() ); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maRedrawManager.moveSprite( rSprite, rOldPos, rNewPos, rSpriteSize ); + } + + virtual void updateSprite( const Sprite::Reference& rSprite, + const ::basegfx::B2DPoint& rPos, + const ::basegfx::B2DRange& rUpdateArea ) override + { + OSL_ASSERT( rSprite.is() ); + + typename BaseType::MutexType aGuard( BaseType::m_aMutex ); + + maRedrawManager.updateSprite( rSprite, rPos, rUpdateArea ); + } + + protected: + SpriteRedrawManager maRedrawManager; + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/inc/base/spritesurface.hxx b/canvas/inc/base/spritesurface.hxx new file mode 100644 index 000000000..e49c82699 --- /dev/null +++ b/canvas/inc/base/spritesurface.hxx @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#pragma once + +#include <base/sprite.hxx> + +namespace canvas +{ + /* Definition of the SpriteSurface interface */ + + /** Canvas surface containing sprites + + Every canvas surface that contains sprites must implement this + interface, when employing the canvas base framework. The + methods provided here are used from the individual sprites to + notify the canvas about necessary screen updates. + */ + class SpriteSurface : public css::uno::XInterface + { + public: + typedef ::rtl::Reference< SpriteSurface > Reference; + + /// Sprites should call this from XSprite::show() + virtual void showSprite( const Sprite::Reference& rSprite ) = 0; + + /// Sprites should call this from XSprite::hide() + virtual void hideSprite( const Sprite::Reference& rSprite ) = 0; + + /// Sprites should call this from XSprite::move() + virtual void moveSprite( const Sprite::Reference& rSprite, + const ::basegfx::B2DPoint& rOldPos, + const ::basegfx::B2DPoint& rNewPos, + const ::basegfx::B2DVector& rSpriteSize ) = 0; + + /** Sprites should call this when some part of the content has + changed. + + That includes show/hide, i.e. for show, both showSprite() + and updateSprite() must be called. + */ + virtual void updateSprite( const Sprite::Reference& rSprite, + const ::basegfx::B2DPoint& rPos, + const ::basegfx::B2DRange& rUpdateArea ) = 0; + + protected: + ~SpriteSurface() {} + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |