summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2022-12-15 11:44:32 +0100
committerStephan Bergmann <sbergman@redhat.com>2022-12-18 18:31:37 +0000
commit4844c096a8ab6a9a620c410a0949d4499f12a504 (patch)
tree38967ed6ef03f90ae6cef48c313e77b7ba93b139
parent9a0b523e0a84d403b9092176ccec4b3e3efe42d0 (diff)
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>
-rw-r--r--canvas/source/cairo/cairo_canvas.cxx5
-rw-r--r--canvas/source/cairo/cairo_canvasbitmap.cxx3
-rw-r--r--canvas/source/cairo/cairo_canvascustomsprite.cxx4
-rw-r--r--canvas/source/cairo/cairo_canvashelper.cxx3
-rw-r--r--canvas/source/cairo/cairo_spritecanvas.cxx4
-rw-r--r--canvas/source/cairo/cairo_surfaceprovider.hxx14
-rw-r--r--include/comphelper/servicehelper.hxx67
7 files changed, 92 insertions, 8 deletions
diff --git a/canvas/source/cairo/cairo_canvas.cxx b/canvas/source/cairo/cairo_canvas.cxx
index 6c9e4fe296df..255b8d84d80c 100644
--- a/canvas/source/cairo/cairo_canvas.cxx
+++ b/canvas/source/cairo/cairo_canvas.cxx
@@ -24,6 +24,7 @@
#include <com/sun/star/lang/NoSupportException.hpp>
#include <osl/mutex.hxx>
#include <comphelper/diagnose_ex.hxx>
+#include <comphelper/servicehelper.hxx>
#include <vcl/sysdata.hxx>
#include <vcl/skia/SkiaHelper.hxx>
#include <cppuhelper/supportsservice.hxx>
@@ -129,7 +130,9 @@ namespace cairocanvas
}
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,
diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx
index 3e0bcae618f6..30ccb2cda8e8 100644
--- a/canvas/source/cairo/cairo_canvasbitmap.cxx
+++ b/canvas/source/cairo/cairo_canvasbitmap.cxx
@@ -145,7 +145,8 @@ namespace cairocanvas
sal_Int64 CanvasBitmap::getSomething(css::uno::Sequence<sal_Int8> const & aIdentifier) {
return comphelper::getSomethingImpl(
- aIdentifier, this, comphelper::FallbackToGetSomethingOf<RepaintTarget>{});
+ aIdentifier, this, comphelper::MixinToGetSomethingOf<SurfaceProvider>{},
+ comphelper::FallbackToGetSomethingOf<RepaintTarget>{});
}
css::uno::Sequence<sal_Int8> const & CanvasBitmap::getUnoTunnelId() {
diff --git a/canvas/source/cairo/cairo_canvascustomsprite.cxx b/canvas/source/cairo/cairo_canvascustomsprite.cxx
index 98ead7036b34..e5f22e9c4a9c 100644
--- a/canvas/source/cairo/cairo_canvascustomsprite.cxx
+++ b/canvas/source/cairo/cairo_canvascustomsprite.cxx
@@ -148,7 +148,9 @@ namespace cairocanvas
}
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>{});
}
}
diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx
index 9279a4c0781b..89a794bc6cd5 100644
--- a/canvas/source/cairo/cairo_canvashelper.cxx
+++ b/canvas/source/cairo/cairo_canvashelper.cxx
@@ -299,7 +299,8 @@ constexpr OUStringLiteral PARAMETRICPOLYPOLYGON_IMPLEMENTATION_NAME = u"Canvas::
if( pBitmapImpl )
return pBitmapImpl->getSurface();
- SurfaceProvider* pSurfaceProvider = dynamic_cast<SurfaceProvider*>( xBitmap.get() );
+ SurfaceProvider* pSurfaceProvider
+ = comphelper::getFromUnoTunnel<SurfaceProvider>( xBitmap );
if( pSurfaceProvider )
return pSurfaceProvider->getSurface();
diff --git a/canvas/source/cairo/cairo_spritecanvas.cxx b/canvas/source/cairo/cairo_spritecanvas.cxx
index e414f8d8d9b5..2d33d4a14c7a 100644
--- a/canvas/source/cairo/cairo_spritecanvas.cxx
+++ b/canvas/source/cairo/cairo_spritecanvas.cxx
@@ -152,7 +152,9 @@ namespace cairocanvas
}
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()
diff --git a/canvas/source/cairo/cairo_surfaceprovider.hxx b/canvas/source/cairo/cairo_surfaceprovider.hxx
index 1ff6f2aa7d3f..e0293373451f 100644
--- a/canvas/source/cairo/cairo_surfaceprovider.hxx
+++ b/canvas/source/cairo/cairo_surfaceprovider.hxx
@@ -20,7 +20,10 @@
#pragma once
#include <rtl/ref.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/XInterface.hpp>
+#include <comphelper/servicehelper.hxx>
+#include <sal/types.h>
#include <basegfx/vector/b2isize.hxx>
#include <vcl/cairo.hxx>
@@ -37,7 +40,7 @@ namespace cairocanvas
This interface must be implemented on all canvas
implementations that hand out XCachedPrimitives
*/
- class SAL_LOPLUGIN_ANNOTATE("crosscast") SurfaceProvider : public css::uno::XInterface
+ class SurfaceProvider : public css::uno::XInterface
{
public:
virtual ~SurfaceProvider() {}
@@ -62,6 +65,15 @@ namespace cairocanvas
/** Provides the underlying vcl outputdevice this surface renders on
*/
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;
diff --git a/include/comphelper/servicehelper.hxx b/include/comphelper/servicehelper.hxx
index c225494ccf1b..1d157cbf1482 100644
--- a/include/comphelper/servicehelper.hxx
+++ b/include/comphelper/servicehelper.hxx
@@ -82,6 +82,16 @@ namespace comphelper {
&& 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
{
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; }
};
+ // 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>
sal_Int64 getSomethingImpl(const css::uno::Sequence<sal_Int8>& rId, T* pThis,
FallbackToGetSomethingOf<Base> = {})
{
- if (isUnoTunnelId<T>(rId))
- return getSomething_cast(pThis);
+ sal_Int64 res;
+ 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);
}