loplugin:unocast (cairocanvas::SurfaceProvider)
(See the upcoming commit introducing that loplugin:unocast on why such dynamic_casts from UNO types are dangerous.) There are implementation classes whose getSomething already delegates to RepaintTarget, so they can't also delegate to SurfaceProvider. So introduce the concept of comphelper::getSomethingImpl additionally delegating to a sequence of mixin classes before delegating to the base. Change-Id: I9230f3dc06abbdd1ad92514a11473dae2624f7c1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144404 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
#include <com/sun/star/lang/NoSupportException.hpp>
|
#include <com/sun/star/lang/NoSupportException.hpp>
|
||||||
#include <osl/mutex.hxx>
|
#include <osl/mutex.hxx>
|
||||||
#include <comphelper/diagnose_ex.hxx>
|
#include <comphelper/diagnose_ex.hxx>
|
||||||
|
#include <comphelper/servicehelper.hxx>
|
||||||
#include <vcl/sysdata.hxx>
|
#include <vcl/sysdata.hxx>
|
||||||
#include <vcl/skia/SkiaHelper.hxx>
|
#include <vcl/skia/SkiaHelper.hxx>
|
||||||
#include <cppuhelper/supportsservice.hxx>
|
#include <cppuhelper/supportsservice.hxx>
|
||||||
@@ -129,7 +130,9 @@ namespace cairocanvas
|
|||||||
}
|
}
|
||||||
|
|
||||||
sal_Int64 Canvas::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
sal_Int64 Canvas::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
||||||
return RepaintTarget::getSomething(aIdentifier);
|
return comphelper::getSomethingImpl_skipDerived(
|
||||||
|
aIdentifier, this, comphelper::MixinToGetSomethingOf<SurfaceProvider>{},
|
||||||
|
comphelper::FallbackToGetSomethingOf<RepaintTarget>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canvas::repaint( const SurfaceSharedPtr& pSurface,
|
bool Canvas::repaint( const SurfaceSharedPtr& pSurface,
|
||||||
|
@@ -145,7 +145,8 @@ namespace cairocanvas
|
|||||||
|
|
||||||
sal_Int64 CanvasBitmap::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
sal_Int64 CanvasBitmap::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
||||||
return comphelper::getSomethingImpl(
|
return comphelper::getSomethingImpl(
|
||||||
aIdentifier, this, comphelper::FallbackToGetSomethingOf<RepaintTarget>{});
|
aIdentifier, this, comphelper::MixinToGetSomethingOf<SurfaceProvider>{},
|
||||||
|
comphelper::FallbackToGetSomethingOf<RepaintTarget>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
css::uno::Sequence<sal_Int8> const & CanvasBitmap::getUnoTunnelId() {
|
css::uno::Sequence<sal_Int8> const & CanvasBitmap::getUnoTunnelId() {
|
||||||
|
@@ -148,7 +148,9 @@ namespace cairocanvas
|
|||||||
}
|
}
|
||||||
|
|
||||||
sal_Int64 CanvasCustomSprite::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
sal_Int64 CanvasCustomSprite::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
||||||
return RepaintTarget::getSomething(aIdentifier);
|
return comphelper::getSomethingImpl_skipDerived(
|
||||||
|
aIdentifier, this, comphelper::MixinToGetSomethingOf<SurfaceProvider>{},
|
||||||
|
comphelper::FallbackToGetSomethingOf<RepaintTarget>{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -299,7 +299,8 @@ constexpr OUStringLiteral PARAMETRICPOLYPOLYGON_IMPLEMENTATION_NAME = u"Canvas::
|
|||||||
if( pBitmapImpl )
|
if( pBitmapImpl )
|
||||||
return pBitmapImpl->getSurface();
|
return pBitmapImpl->getSurface();
|
||||||
|
|
||||||
SurfaceProvider* pSurfaceProvider = dynamic_cast<SurfaceProvider*>( xBitmap.get() );
|
SurfaceProvider* pSurfaceProvider
|
||||||
|
= comphelper::getFromUnoTunnel<SurfaceProvider>( xBitmap );
|
||||||
if( pSurfaceProvider )
|
if( pSurfaceProvider )
|
||||||
return pSurfaceProvider->getSurface();
|
return pSurfaceProvider->getSurface();
|
||||||
|
|
||||||
|
@@ -152,7 +152,9 @@ namespace cairocanvas
|
|||||||
}
|
}
|
||||||
|
|
||||||
sal_Int64 SpriteCanvas::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
sal_Int64 SpriteCanvas::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
||||||
return RepaintTarget::getSomething(aIdentifier);
|
return comphelper::getSomethingImpl_skipDerived(
|
||||||
|
aIdentifier, this, comphelper::MixinToGetSomethingOf<SurfaceProvider>{},
|
||||||
|
comphelper::FallbackToGetSomethingOf<RepaintTarget>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceSharedPtr SpriteCanvas::getSurface()
|
SurfaceSharedPtr SpriteCanvas::getSurface()
|
||||||
|
@@ -20,7 +20,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <rtl/ref.hxx>
|
#include <rtl/ref.hxx>
|
||||||
|
#include <com/sun/star/uno/Sequence.hxx>
|
||||||
#include <com/sun/star/uno/XInterface.hpp>
|
#include <com/sun/star/uno/XInterface.hpp>
|
||||||
|
#include <comphelper/servicehelper.hxx>
|
||||||
|
#include <sal/types.h>
|
||||||
|
|
||||||
#include <basegfx/vector/b2isize.hxx>
|
#include <basegfx/vector/b2isize.hxx>
|
||||||
#include <vcl/cairo.hxx>
|
#include <vcl/cairo.hxx>
|
||||||
@@ -37,7 +40,7 @@ namespace cairocanvas
|
|||||||
This interface must be implemented on all canvas
|
This interface must be implemented on all canvas
|
||||||
implementations that hand out XCachedPrimitives
|
implementations that hand out XCachedPrimitives
|
||||||
*/
|
*/
|
||||||
class SAL_LOPLUGIN_ANNOTATE("crosscast") SurfaceProvider : public css::uno::XInterface
|
class SurfaceProvider : public css::uno::XInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~SurfaceProvider() {}
|
virtual ~SurfaceProvider() {}
|
||||||
@@ -62,6 +65,15 @@ namespace cairocanvas
|
|||||||
/** Provides the underlying vcl outputdevice this surface renders on
|
/** Provides the underlying vcl outputdevice this surface renders on
|
||||||
*/
|
*/
|
||||||
virtual OutputDevice* getOutputDevice() = 0;
|
virtual OutputDevice* getOutputDevice() = 0;
|
||||||
|
|
||||||
|
sal_Int64 getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
|
||||||
|
return comphelper::getSomethingImpl(aIdentifier, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static css::uno::Sequence<sal_Int8> const & getUnoTunnelId() {
|
||||||
|
static comphelper::UnoIdInit const id;
|
||||||
|
return id.getSeq();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ::rtl::Reference< SurfaceProvider > SurfaceProviderRef;
|
typedef ::rtl::Reference< SurfaceProvider > SurfaceProviderRef;
|
||||||
|
@@ -82,6 +82,16 @@ namespace comphelper {
|
|||||||
&& memcmp(T::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16) == 0;
|
&& memcmp(T::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> struct MixinToGetSomethingOf {
|
||||||
|
static bool get(css::uno::Sequence<sal_Int8> const & id, T * p, sal_Int64 * result) {
|
||||||
|
if (!isUnoTunnelId<T>(id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*result = getSomething_cast(p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class Base> struct FallbackToGetSomethingOf
|
template <class Base> struct FallbackToGetSomethingOf
|
||||||
{
|
{
|
||||||
static sal_Int64 get(const css::uno::Sequence<sal_Int8>& rId, Base* p)
|
static sal_Int64 get(const css::uno::Sequence<sal_Int8>& rId, Base* p)
|
||||||
@@ -95,12 +105,65 @@ namespace comphelper {
|
|||||||
static sal_Int64 get(const css::uno::Sequence<sal_Int8>&, void*) { return 0; }
|
static sal_Int64 get(const css::uno::Sequence<sal_Int8>&, void*) { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// There are five cases how to implement T::getSomething:
|
||||||
|
// (1) Delegate to Base:
|
||||||
|
// Either, if Base has only getUnoTunnelId but no getSomething:
|
||||||
|
// return getSomethingImpl<Base>(aIdentifier, this);
|
||||||
|
// Or, if Base has getSomething:
|
||||||
|
// return Base::getSomething(aIdentifier)
|
||||||
|
// (2) Check against T::getUnoTunnelId, else return 0:
|
||||||
|
// return getSomethingImpl(aIdentifier, this);
|
||||||
|
// (3) Check against T::getUnoTunnelId, else delegate to Base:
|
||||||
|
// return getSomethingImpl(aIdentifier, this, FallbackToGetSomethingOf<Base>{});
|
||||||
|
// (4) Check against T::getUnoTunnelId, else check against each Mixins::getUnoTunnelId, else
|
||||||
|
// delegate to Base:
|
||||||
|
// return getSomethingImpl(
|
||||||
|
// aIdentifier, this, MixinToGetSomethingOf<Mixin1>{}, ...,
|
||||||
|
// MixinToGetSomethingOf<MixinN>{}, FallbackToGetSomethingOf<Base>{});
|
||||||
|
// (5) Check against each Mixins::getUnoTunnelId, else delegate to Base:
|
||||||
|
// return getSomethingImpl_skipDerived(
|
||||||
|
// aIdentifier, this, MixinToGetSomethingOf<Mixin1>{}, ...,
|
||||||
|
// MixinToGetSomethingOf<MixinN>{}, FallbackToGetSomethingOf<Base>{});
|
||||||
|
|
||||||
template <class T, class Base = void>
|
template <class T, class Base = void>
|
||||||
sal_Int64 getSomethingImpl(const css::uno::Sequence<sal_Int8>& rId, T* pThis,
|
sal_Int64 getSomethingImpl(const css::uno::Sequence<sal_Int8>& rId, T* pThis,
|
||||||
FallbackToGetSomethingOf<Base> = {})
|
FallbackToGetSomethingOf<Base> = {})
|
||||||
{
|
{
|
||||||
if (isUnoTunnelId<T>(rId))
|
sal_Int64 res;
|
||||||
return getSomething_cast(pThis);
|
if (MixinToGetSomethingOf<T>::get(rId, pThis, &res)) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FallbackToGetSomethingOf<Base>::get(rId, pThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Mixin, class... Mixins, class Base>
|
||||||
|
sal_Int64 getSomethingImpl(const css::uno::Sequence<sal_Int8>& rId, T* pThis,
|
||||||
|
MixinToGetSomethingOf<Mixin>, MixinToGetSomethingOf<Mixins>...,
|
||||||
|
FallbackToGetSomethingOf<Base>)
|
||||||
|
{
|
||||||
|
sal_Int64 res;
|
||||||
|
if (((MixinToGetSomethingOf<T>::get(rId, pThis, &res)
|
||||||
|
|| MixinToGetSomethingOf<Mixin>::get(rId, pThis, &res)) || ...
|
||||||
|
|| MixinToGetSomethingOf<Mixins>::get(rId, pThis, &res)))
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FallbackToGetSomethingOf<Base>::get(rId, pThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Mixin, class... Mixins, class Base>
|
||||||
|
sal_Int64 getSomethingImpl_skipDerived(const css::uno::Sequence<sal_Int8>& rId, T* pThis,
|
||||||
|
MixinToGetSomethingOf<Mixin>, MixinToGetSomethingOf<Mixins>...,
|
||||||
|
FallbackToGetSomethingOf<Base>)
|
||||||
|
{
|
||||||
|
sal_Int64 res;
|
||||||
|
if ((MixinToGetSomethingOf<Mixin>::get(rId, pThis, &res) || ...
|
||||||
|
|| MixinToGetSomethingOf<Mixins>::get(rId, pThis, &res)))
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
return FallbackToGetSomethingOf<Base>::get(rId, pThis);
|
return FallbackToGetSomethingOf<Base>::get(rId, pThis);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user