diff options
Diffstat (limited to 'canvas/source')
103 files changed, 1308 insertions, 1535 deletions
diff --git a/canvas/source/cairo/cairo_cachedbitmap.cxx b/canvas/source/cairo/cairo_cachedbitmap.cxx index c907367a49af..e548778b2fe4 100644 --- a/canvas/source/cairo/cairo_cachedbitmap.cxx +++ b/canvas/source/cairo/cairo_cachedbitmap.cxx @@ -21,7 +21,8 @@ #include <com/sun/star/rendering/XCanvas.hpp> #include <com/sun/star/rendering/RepaintResult.hpp> -#include <tools/diagnose_ex.h> +#include <utility> +#include <comphelper/diagnose_ex.hxx> #include "cairo_cachedbitmap.hxx" #include "cairo_repainttarget.hxx" @@ -32,21 +33,19 @@ using namespace ::com::sun::star; namespace cairocanvas { - CachedBitmap::CachedBitmap( const SurfaceSharedPtr& pSurface, + CachedBitmap::CachedBitmap( SurfaceSharedPtr pSurface, const rendering::ViewState& rUsedViewState, - const rendering::RenderState& rUsedRenderState, + rendering::RenderState aUsedRenderState, const uno::Reference< rendering::XCanvas >& rTarget ) : CachedPrimitiveBase( rUsedViewState, rTarget ), - mpSurface( pSurface ), - maRenderState( rUsedRenderState ) + mpSurface(std::move( pSurface )), + maRenderState(std::move( aUsedRenderState )) {} - void SAL_CALL CachedBitmap::disposing() + void CachedBitmap::disposing(std::unique_lock<std::mutex>& rGuard) { - ::osl::MutexGuard aGuard( m_aMutex ); - mpSurface.reset(); - CachedPrimitiveBase::disposing(); + CachedPrimitiveBase::disposing(rGuard); } ::sal_Int8 CachedBitmap::doRedraw( const rendering::ViewState& rNewState, diff --git a/canvas/source/cairo/cairo_cachedbitmap.hxx b/canvas/source/cairo/cairo_cachedbitmap.hxx index 0af07c07a6c8..d7f4c58ef681 100644 --- a/canvas/source/cairo/cairo_cachedbitmap.hxx +++ b/canvas/source/cairo/cairo_cachedbitmap.hxx @@ -34,13 +34,13 @@ namespace cairocanvas /** Create an XCachedPrimitive for given GraphicObject */ - CachedBitmap( const ::cairo::SurfaceSharedPtr& pSurface, - const css::rendering::ViewState& rUsedViewState, - const css::rendering::RenderState& rUsedRenderState, - const css::uno::Reference< css::rendering::XCanvas >& rTarget ); + CachedBitmap( ::cairo::SurfaceSharedPtr pSurface, + const css::rendering::ViewState& rUsedViewState, + css::rendering::RenderState aUsedRenderState, + const css::uno::Reference< css::rendering::XCanvas >& rTarget ); /// Dispose all internal references - virtual void SAL_CALL disposing() override; + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; private: virtual ::sal_Int8 doRedraw( const css::rendering::ViewState& rNewState, diff --git a/canvas/source/cairo/cairo_canvas.cxx b/canvas/source/cairo/cairo_canvas.cxx index f8266cffe446..100ee51c0aa2 100644 --- a/canvas/source/cairo/cairo_canvas.cxx +++ b/canvas/source/cairo/cairo_canvas.cxx @@ -23,7 +23,7 @@ #include <com/sun/star/awt/Rectangle.hpp> #include <com/sun/star/lang/NoSupportException.hpp> #include <osl/mutex.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/sysdata.hxx> #include <vcl/skia/SkiaHelper.hxx> #include <cppuhelper/supportsservice.hxx> @@ -68,7 +68,6 @@ namespace cairocanvas sal_Int64 nPtr = 0; maArguments[0] >>= nPtr; OutputDevice* pOutDev = reinterpret_cast<OutputDevice*>(nPtr); - ENSURE_ARG_OR_THROW( pOutDev != nullptr, "Canvas::initialize: invalid OutDev pointer" ); @@ -111,7 +110,7 @@ namespace cairocanvas OUString SAL_CALL Canvas::getServiceName( ) { - return "com.sun.star.rendering.Canvas.Cairo"; + return u"com.sun.star.rendering.Canvas.Cairo"_ustr; } // XServiceInfo @@ -122,7 +121,7 @@ namespace cairocanvas } OUString Canvas::getImplementationName() { - return "com.sun.star.comp.rendering.Canvas.Cairo"; + return u"com.sun.star.comp.rendering.Canvas.Cairo"_ustr; } css::uno::Sequence< OUString > Canvas::getSupportedServiceNames() { @@ -176,16 +175,14 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* com_sun_star_comp_rendering_Canvas_Cairo_get_implementation( css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) { - auto p = new cairocanvas::Canvas(args, context); - p->acquire(); + rtl::Reference<cairocanvas::Canvas> p = new cairocanvas::Canvas(args, context); try { p->initialize(); } catch (css::uno::Exception&) { p->dispose(); - p->release(); throw; } - return static_cast<cppu::OWeakObject*>(p); + return cppu::acquire(p.get()); } diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx index 55f1603237b2..c4de75ee2fce 100644 --- a/canvas/source/cairo/cairo_canvasbitmap.cxx +++ b/canvas/source/cairo/cairo_canvasbitmap.cxx @@ -21,7 +21,8 @@ #include <sal/log.hxx> #include <cppuhelper/supportsservice.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> +#include <utility> #include <vcl/bitmapex.hxx> #include <vcl/BitmapTools.hxx> @@ -35,12 +36,10 @@ using namespace ::com::sun::star; namespace cairocanvas { CanvasBitmap::CanvasBitmap( const ::basegfx::B2ISize& rSize, - const SurfaceProviderRef& rSurfaceProvider, + SurfaceProviderRef rSurfaceProvider, rendering::XGraphicDevice* pDevice, bool bHasAlpha ) : - mpSurfaceProvider( rSurfaceProvider ), - mpBufferSurface(), - mpBufferCairo(), + mpSurfaceProvider(std::move( rSurfaceProvider )), maSize(rSize), mbHasAlpha(bHasAlpha) { @@ -49,7 +48,7 @@ namespace cairocanvas SAL_INFO( "canvas.cairo", - "bitmap size: " << rSize.getX() << "x" << rSize.getY()); + "bitmap size: " << rSize.getWidth() << "x" << rSize.getHeight()); mpBufferSurface = mpSurfaceProvider->createSurface( rSize, bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR ); mpBufferCairo = mpBufferSurface->getCairo(); @@ -120,7 +119,7 @@ namespace cairocanvas break; BitmapEx* pBitmapEx = vcl::bitmap::CreateFromCairoSurface( - ::Size( maSize.getX(), maSize.getY() ), + ::Size( maSize.getWidth(), maSize.getHeight() ), getSurface()->getCairoSurface().get()); if (pBitmapEx) aRV <<= reinterpret_cast<sal_Int64>( pBitmapEx ); @@ -146,7 +145,7 @@ namespace cairocanvas OUString SAL_CALL CanvasBitmap::getImplementationName( ) { - return "CairoCanvas.CanvasBitmap"; + return u"CairoCanvas.CanvasBitmap"_ustr; } sal_Bool SAL_CALL CanvasBitmap::supportsService( const OUString& ServiceName ) @@ -156,7 +155,7 @@ namespace cairocanvas uno::Sequence< OUString > SAL_CALL CanvasBitmap::getSupportedServiceNames( ) { - return { "com.sun.star.rendering.CanvasBitmap" }; + return { u"com.sun.star.rendering.CanvasBitmap"_ustr }; } } diff --git a/canvas/source/cairo/cairo_canvasbitmap.hxx b/canvas/source/cairo/cairo_canvasbitmap.hxx index a4e55f7b642a..f2371821023f 100644 --- a/canvas/source/cairo/cairo_canvasbitmap.hxx +++ b/canvas/source/cairo/cairo_canvasbitmap.hxx @@ -69,7 +69,7 @@ namespace cairocanvas Reference device, with which bitmap should be compatible */ CanvasBitmap( const ::basegfx::B2ISize& rSize, - const SurfaceProviderRef& rDevice, + SurfaceProviderRef rDevice, css::rendering::XGraphicDevice* pDevice, bool bHasAlpha ); @@ -106,10 +106,9 @@ namespace cairocanvas // 0 ... get pointer to BitmapEx // 1 ... get X pixmap handle to rgb content // 2 ... FIXME: leftover? ever called with this? always returns nothing (empty Any) - // returned any contains either BitmapEx pointer or array of three Any value + // returned any contains either BitmapEx pointer or array of two Any value // 1st a bool value: true - free the pixmap after used by XFreePixmap, false do nothing, the pixmap is used internally in the canvas // 2nd the pixmap handle (sal_Int64) - // 3rd the pixmap depth virtual css::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) override; virtual void SAL_CALL setFastPropertyValue(sal_Int32, const css::uno::Any&) override {} diff --git a/canvas/source/cairo/cairo_canvascustomsprite.cxx b/canvas/source/cairo/cairo_canvascustomsprite.cxx index b885071787d5..72fb291ebf35 100644 --- a/canvas/source/cairo/cairo_canvascustomsprite.cxx +++ b/canvas/source/cairo/cairo_canvascustomsprite.cxx @@ -22,7 +22,7 @@ #include <basegfx/point/b2dpoint.hxx> #include <cppuhelper/supportsservice.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> #include <cairo.h> @@ -134,7 +134,7 @@ namespace cairocanvas OUString SAL_CALL CanvasCustomSprite::getImplementationName() { - return "CairoCanvas.CanvasCustomSprite"; + return u"CairoCanvas.CanvasCustomSprite"_ustr; } sal_Bool SAL_CALL CanvasCustomSprite::supportsService( const OUString& ServiceName ) @@ -144,7 +144,7 @@ namespace cairocanvas uno::Sequence< OUString > SAL_CALL CanvasCustomSprite::getSupportedServiceNames() { - return { "com.sun.star.rendering.CanvasCustomSprite" }; + return { u"com.sun.star.rendering.CanvasCustomSprite"_ustr }; } } diff --git a/canvas/source/cairo/cairo_canvasfont.cxx b/canvas/source/cairo/cairo_canvasfont.cxx index cca052d167e0..a2650811b721 100644 --- a/canvas/source/cairo/cairo_canvasfont.cxx +++ b/canvas/source/cairo/cairo_canvasfont.cxx @@ -24,8 +24,11 @@ #include <cppuhelper/supportsservice.hxx> #include <i18nlangtag/languagetag.hxx> #include <rtl/math.hxx> +#include <utility> #include <vcl/metric.hxx> +#include <canvas/canvastools.hxx> + #include "cairo_canvasfont.hxx" #include "cairo_textlayout.hxx" @@ -35,16 +38,18 @@ namespace cairocanvas { CanvasFont::CanvasFont( const rendering::FontRequest& rFontRequest, - const uno::Sequence< beans::PropertyValue >& /*rExtraFontProperties*/, + const uno::Sequence< beans::PropertyValue >& rExtraFontProperties, const geometry::Matrix2D& rFontMatrix, - const SurfaceProviderRef& rDevice ) : - CanvasFont_Base( m_aMutex ), + SurfaceProviderRef rDevice ) : maFont( vcl::Font( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, Size( 0, ::basegfx::fround(rFontRequest.CellSize) ) ) ), maFontRequest( rFontRequest ), - mpRefDevice( rDevice ) + mpRefDevice(std::move( rDevice )), + mnEmphasisMark(0) { + ::canvas::tools::extractExtraFontProperties(rExtraFontProperties, mnEmphasisMark); + maFont->SetAlignment( ALIGN_BASELINE ); maFont->SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==css::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); maFont->SetVertical( rFontRequest.FontDescription.IsVertical==css::util::TriState_YES ); @@ -85,11 +90,14 @@ namespace cairocanvas pOutDev->EnableMapMode(bOldMapState); } - void SAL_CALL CanvasFont::disposing() + void CanvasFont::disposing(std::unique_lock<std::mutex>& rGuard) { - SolarMutexGuard aGuard; - - mpRefDevice.clear(); + rGuard.unlock(); + { + SolarMutexGuard aGuard; + mpRefDevice.clear(); + } + rGuard.lock(); } uno::Reference< rendering::XTextLayout > SAL_CALL CanvasFont::createTextLayout( const rendering::StringContext& aText, sal_Int8 nDirection, sal_Int64 nRandomSeed ) @@ -108,8 +116,6 @@ namespace cairocanvas rendering::FontRequest SAL_CALL CanvasFont::getFontRequest( ) { - SolarMutexGuard aGuard; - return maFontRequest; } @@ -133,7 +139,7 @@ namespace cairocanvas OUString SAL_CALL CanvasFont::getImplementationName() { - return "CairoCanvas::CanvasFont"; + return u"CairoCanvas::CanvasFont"_ustr; } sal_Bool SAL_CALL CanvasFont::supportsService( const OUString& ServiceName ) @@ -143,7 +149,7 @@ namespace cairocanvas uno::Sequence< OUString > SAL_CALL CanvasFont::getSupportedServiceNames() { - return { "com.sun.star.rendering.CanvasFont" }; + return { u"com.sun.star.rendering.CanvasFont"_ustr }; } vcl::Font const & CanvasFont::getVCLFont() const diff --git a/canvas/source/cairo/cairo_canvasfont.hxx b/canvas/source/cairo/cairo_canvasfont.hxx index 0c26bee66b72..d5e015006c98 100644 --- a/canvas/source/cairo/cairo_canvasfont.hxx +++ b/canvas/source/cairo/cairo_canvasfont.hxx @@ -19,8 +19,7 @@ #pragma once -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> +#include <comphelper/compbase.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/geometry/Matrix2D.hpp> @@ -38,11 +37,10 @@ namespace cairocanvas { - typedef ::cppu::WeakComponentImplHelper< css::rendering::XCanvasFont, + typedef ::comphelper::WeakComponentImplHelper< css::rendering::XCanvasFont, css::lang::XServiceInfo > CanvasFont_Base; - class CanvasFont : public ::cppu::BaseMutex, - public CanvasFont_Base + class CanvasFont : public CanvasFont_Base { public: typedef rtl::Reference<CanvasFont> Reference; @@ -51,12 +49,12 @@ namespace cairocanvas const CanvasFont& operator=(const CanvasFont&) = delete; CanvasFont( const css::rendering::FontRequest& fontRequest, - const css::uno::Sequence< css::beans::PropertyValue >& extraFontProperties, + const css::uno::Sequence< css::beans::PropertyValue >& extraFontProperties, const css::geometry::Matrix2D& rFontMatrix, - const SurfaceProviderRef& rDevice ); + SurfaceProviderRef rDevice ); /// Dispose all internal references - virtual void SAL_CALL disposing() override; + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; // XCanvasFont virtual css::uno::Reference< css::rendering::XTextLayout > SAL_CALL createTextLayout( const css::rendering::StringContext& aText, sal_Int8 nDirection, sal_Int64 nRandomSeed ) override; @@ -72,10 +70,13 @@ namespace cairocanvas vcl::Font const & getVCLFont() const; + sal_uInt32 getEmphasisMark() const { return mnEmphasisMark; } + private: ::canvas::vcltools::VCLObject<vcl::Font> maFont; css::rendering::FontRequest maFontRequest; SurfaceProviderRef mpRefDevice; + sal_uInt32 mnEmphasisMark; }; } diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx index 7d4cdba478f4..f09ce8c480bf 100644 --- a/canvas/source/cairo/cairo_canvashelper.cxx +++ b/canvas/source/cairo/cairo_canvashelper.cxx @@ -41,9 +41,8 @@ #include <com/sun/star/util/Endianness.hpp> #include <comphelper/sequence.hxx> #include <cppuhelper/implbase.hxx> -#include <rtl/instance.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/bitmapex.hxx> #include <vcl/BitmapTools.hxx> #include <vcl/canvastools.hxx> @@ -65,11 +64,7 @@ namespace cairocanvas CanvasHelper::CanvasHelper() : mpSurfaceProvider(nullptr), mpDevice(nullptr), - mpVirtualDevice(), - mbHaveAlpha(), - mpCairo(), - mpSurface(), - maSize() + mbHaveAlpha() { } @@ -214,7 +209,7 @@ namespace cairocanvas void CanvasHelper::clear() { - SAL_INFO( "canvas.cairo", "clear whole area: " << maSize.getX() << " x " << maSize.getY() ); + SAL_INFO( "canvas.cairo", "clear whole area: " << maSize.getWidth() << " x " << maSize.getHeight() ); if( !mpCairo ) return; @@ -231,7 +226,7 @@ namespace cairocanvas cairo_set_source_rgb( mpCairo.get(), 1.0, 1.0, 1.0 ); cairo_set_operator( mpCairo.get(), CAIRO_OPERATOR_SOURCE ); - cairo_rectangle( mpCairo.get(), 0, 0, maSize.getX(), maSize.getY() ); + cairo_rectangle( mpCairo.get(), 0, 0, maSize.getWidth(), maSize.getHeight() ); cairo_fill( mpCairo.get() ); cairo_restore( mpCairo.get() ); @@ -286,7 +281,7 @@ namespace cairocanvas cairo_restore( mpCairo.get() ); } -#define PARAMETRICPOLYPOLYGON_IMPLEMENTATION_NAME "Canvas::ParametricPolyPolygon" +constexpr OUStringLiteral PARAMETRICPOLYPOLYGON_IMPLEMENTATION_NAME = u"Canvas::ParametricPolyPolygon"; /** surfaceFromXBitmap Create a surface from XBitmap * @param xBitmap bitmap image that will be used for the surface @@ -316,7 +311,7 @@ namespace cairocanvas uno::Reference<rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW); ::BitmapEx aBmpEx = vcl::unotools::bitmapExFromXBitmap(xIntBmp); - if( !!aBmpEx ) + if( !aBmpEx.IsEmpty() ) return aBmpEx; // TODO(F1): extract pixel from XBitmap interface @@ -351,7 +346,7 @@ namespace cairocanvas // there's no pixmap for alpha bitmap. we might still // use rgb pixmap and only access alpha pixels the // slow way. now we just speedup rgb bitmaps - if( !aBmpEx.IsTransparent() && !aBmpEx.IsAlpha() ) + if( !aBmpEx.IsAlpha() ) { pSurface = rSurfaceProvider->createSurface( aBitmap ); data = nullptr; @@ -364,14 +359,13 @@ namespace cairocanvas tools::Long nHeight; vcl::bitmap::CanvasCairoExtractBitmapData(aBmpEx, aBitmap, data, bHasAlpha, nWidth, nHeight); - SurfaceSharedPtr pImageSurface = rSurfaceProvider->getOutputDevice()->CreateSurface( + pSurface = rSurfaceProvider->getOutputDevice()->CreateSurface( CairoSurfaceSharedPtr( cairo_image_surface_create_for_data( data, bHasAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, nWidth, nHeight, nWidth*4 ), &cairo_surface_destroy) ); - pSurface = pImageSurface; SAL_INFO( "canvas.cairo","image: " << nWidth << " x " << nHeight << " alpha: " << bHasAlpha); } @@ -405,23 +399,25 @@ namespace cairocanvas { if( rLeft.getLength() == 3 ) { - uno::Sequence<double> aRes(3); - aRes[0] = basegfx::utils::lerp(rLeft[0],rRight[0],fAlpha); - aRes[1] = basegfx::utils::lerp(rLeft[1],rRight[1],fAlpha); - aRes[2] = basegfx::utils::lerp(rLeft[2],rRight[2],fAlpha); - return aRes; + return + { + basegfx::utils::lerp(rLeft[0],rRight[0],fAlpha), + basegfx::utils::lerp(rLeft[1],rRight[1],fAlpha), + basegfx::utils::lerp(rLeft[2],rRight[2],fAlpha) + }; } else if( rLeft.getLength() == 4 ) { - uno::Sequence<double> aRes(4); - aRes[0] = basegfx::utils::lerp(rLeft[0],rRight[0],fAlpha); - aRes[1] = basegfx::utils::lerp(rLeft[1],rRight[1],fAlpha); - aRes[2] = basegfx::utils::lerp(rLeft[2],rRight[2],fAlpha); - aRes[3] = basegfx::utils::lerp(rLeft[3],rRight[3],fAlpha); - return aRes; + return + { + basegfx::utils::lerp(rLeft[0],rRight[0],fAlpha), + basegfx::utils::lerp(rLeft[1],rRight[1],fAlpha), + basegfx::utils::lerp(rLeft[2],rRight[2],fAlpha), + basegfx::utils::lerp(rLeft[3],rRight[3],fAlpha) + }; } - return uno::Sequence<double>(); + return {}; } static cairo_pattern_t* patternFromParametricPolyPolygon( ::canvas::ParametricPolyPolygon const & rPolygon ) @@ -492,7 +488,7 @@ namespace cairocanvas geometry::IntegerSize2D aSize = aTexture.Bitmap->getSize(); cairo_matrix_init_scale( &aScaleMatrix, 1.0/aSize.Width, 1.0/aSize.Height ); - cairo_matrix_multiply( &aScaledTextureMatrix, &aTextureMatrix, &aScaleMatrix ); + cairo_matrix_multiply( &aScaledTextureMatrix, &aScaleMatrix, &aTextureMatrix ); cairo_matrix_invert( &aScaledTextureMatrix ); // we don't care about repeat mode yet, so the workaround is disabled for now @@ -914,10 +910,12 @@ namespace cairocanvas useStates( viewState, renderState, true ); cairo_matrix_t aMatrix; - double w = strokeAttributes.StrokeWidth, h = 0; cairo_get_matrix( mpCairo.get(), &aMatrix ); - cairo_matrix_transform_distance( &aMatrix, &w, &h ); - cairo_set_line_width( mpCairo.get(), w ); + double scaleFactorX = 1; + double scaleFactorY = 0; + cairo_matrix_transform_distance( &aMatrix, &scaleFactorX, &scaleFactorY ); + double scaleFactor = basegfx::B2DVector( scaleFactorX, scaleFactorY ).getLength(); + cairo_set_line_width( mpCairo.get(), strokeAttributes.StrokeWidth * scaleFactor ); cairo_set_miter_limit( mpCairo.get(), strokeAttributes.MiterLimit ); @@ -953,14 +951,14 @@ namespace cairocanvas break; } - //tdf#103026 If the w scaling is 0, then all dashes become zero so + //tdf#103026 If the scaling is 0, then all dashes become zero so //cairo will set the cairo_t status to CAIRO_STATUS_INVALID_DASH //and no further drawing will occur - if (strokeAttributes.DashArray.hasElements() && w > 0.0) + if (strokeAttributes.DashArray.hasElements() && scaleFactor > 0.0) { auto aDashArray(comphelper::sequenceToContainer<std::vector<double>>(strokeAttributes.DashArray)); for (auto& rDash : aDashArray) - rDash *= w; + rDash *= scaleFactor; cairo_set_dash(mpCairo.get(), aDashArray.data(), aDashArray.size(), 0); } @@ -1089,7 +1087,7 @@ namespace cairocanvas { cairo_save( mpCairo.get() ); - cairo_rectangle( mpCairo.get(), 0, 0, maSize.getX(), maSize.getY() ); + cairo_rectangle( mpCairo.get(), 0, 0, maSize.getWidth(), maSize.getHeight() ); cairo_clip( mpCairo.get() ); useStates( viewState, renderState, true ); @@ -1148,8 +1146,8 @@ namespace cairocanvas // in case the bitmap doesn't have alpha and covers whole area // we try to change surface to plain rgb - SAL_INFO( "canvas.cairo","chance to change surface to rgb, " << x << ", " << y << ", " << width << " x " << height << " (" << maSize.getX() << " x " << maSize.getY() << ")" ); - if( x <= 0 && y <= 0 && x + width >= maSize.getX() && y + height >= maSize.getY() ) + SAL_INFO( "canvas.cairo","chance to change surface to rgb, " << x << ", " << y << ", " << width << " x " << height << " (" << maSize.getWidth() << " x " << maSize.getHeight() << ")" ); + if( x <= 0 && y <= 0 && x + width >= maSize.getWidth() && y + height >= maSize.getHeight() ) { SAL_INFO( "canvas.cairo","trying to change surface to rgb"); if( mpSurfaceProvider ) { @@ -1177,8 +1175,13 @@ namespace cairocanvas cairo_rectangle( mpCairo.get(), 0, 0, aBitmapSize.Width, aBitmapSize.Height ); cairo_clip( mpCairo.get() ); - int nPixelWidth = std::round(rSize.Width * aMatrix.xx); - int nPixelHeight = std::round(rSize.Height * aMatrix.yy); + // Use cairo_matrix_transform_distance() to determine the scaling, as that works even if + // the matrix also has rotation. + double fPixelWidth = rSize.Width; + double fPixelHeight = rSize.Height; + cairo_matrix_transform_distance(&aMatrix, &fPixelWidth, &fPixelHeight); + int nPixelWidth = std::round(fPixelWidth); + int nPixelHeight = std::round(fPixelHeight); if (std::abs(nPixelWidth) > 0 && std::abs(nPixelHeight) > 0) { // Only render the image if it's at least 1x1 px sized. @@ -1226,7 +1229,7 @@ namespace cairocanvas free( data ); } else - rv.set(nullptr); + rv.clear(); #ifdef CAIRO_CANVAS_PERF_TRACE mxDevice->stopPerfTrace( &aTimer, "drawBitmap" ); @@ -1259,7 +1262,7 @@ namespace cairocanvas free( data ); } else - rv.set(nullptr); + rv.clear(); #ifdef CAIRO_CANVAS_PERF_TRACE mxDevice->stopPerfTrace( &aTimer, "drawBitmap" ); @@ -1970,22 +1973,16 @@ namespace cairocanvas } }; - struct CairoNoAlphaColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>, - CairoNoAlphaColorSpaceHolder> + uno::Reference<rendering::XIntegerBitmapColorSpace>& GetCairoNoAlphaColorSpace() { - uno::Reference<rendering::XIntegerBitmapColorSpace> operator()() - { - return new CairoNoAlphaColorSpace(); - } + static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new CairoNoAlphaColorSpace(); + return SPACE; }; - struct CairoColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>, - CairoColorSpaceHolder> + uno::Reference<rendering::XIntegerBitmapColorSpace>& GetCairoColorSpace() { - uno::Reference<rendering::XIntegerBitmapColorSpace> operator()() - { - return new CairoColorSpace(); - } + static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new CairoColorSpace(); + return SPACE; }; } @@ -2009,7 +2006,7 @@ namespace cairocanvas aLayout.ScanLineBytes = nWidth*4; aLayout.ScanLineStride = aLayout.ScanLineBytes; aLayout.PlaneStride = 0; - aLayout.ColorSpace = mbHaveAlpha ? CairoColorSpaceHolder::get() : CairoNoAlphaColorSpaceHolder::get(); + aLayout.ColorSpace = mbHaveAlpha ? GetCairoColorSpace() : GetCairoNoAlphaColorSpace(); aLayout.Palette.clear(); aLayout.IsMsbFirst = false; @@ -2023,25 +2020,25 @@ namespace cairocanvas { SAL_INFO( "canvas.cairo", "CanvasHelper::repaint"); - if( mpCairo ) - { - cairo_save( mpCairo.get() ); + if( !mpCairo ) + return true; - cairo_rectangle( mpCairo.get(), 0, 0, maSize.getX(), maSize.getY() ); - cairo_clip( mpCairo.get() ); + cairo_save( mpCairo.get() ); - useStates( viewState, renderState, true ); + cairo_rectangle( mpCairo.get(), 0, 0, maSize.getWidth(), maSize.getHeight() ); + cairo_clip( mpCairo.get() ); - cairo_matrix_t aMatrix; + useStates( viewState, renderState, true ); - cairo_get_matrix( mpCairo.get(), &aMatrix ); - aMatrix.xx = aMatrix.yy = 1; - cairo_set_matrix( mpCairo.get(), &aMatrix ); + cairo_matrix_t aMatrix; - cairo_set_source_surface( mpCairo.get(), pSurface->getCairoSurface().get(), 0, 0 ); - cairo_paint( mpCairo.get() ); - cairo_restore( mpCairo.get() ); - } + cairo_get_matrix( mpCairo.get(), &aMatrix ); + aMatrix.xx = aMatrix.yy = 1; + cairo_set_matrix( mpCairo.get(), &aMatrix ); + + cairo_set_source_surface( mpCairo.get(), pSurface->getCairoSurface().get(), 0, 0 ); + cairo_paint( mpCairo.get() ); + cairo_restore( mpCairo.get() ); return true; } diff --git a/canvas/source/cairo/cairo_canvashelper_text.cxx b/canvas/source/cairo/cairo_canvashelper_text.cxx index 2763800d5283..c8498bddf3b7 100644 --- a/canvas/source/cairo/cairo_canvashelper_text.cxx +++ b/canvas/source/cairo/cairo_canvashelper_text.cxx @@ -23,7 +23,7 @@ #include <rtl/math.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/canvastools.hxx> #include <vcl/metric.hxx> #include <vcl/virdev.hxx> @@ -99,7 +99,7 @@ namespace cairocanvas io_rVCLFont.SetFontHeight( ::basegfx::fround(nFontHeight * aScale.getY()) ); } - io_rVCLFont.SetOrientation( Degree10(static_cast< sal_Int16 >( ::basegfx::fround(-fmod(nRotate, 2*M_PI)*(1800.0/M_PI)) )) ); + io_rVCLFont.SetOrientation( Degree10( ::basegfx::fround(-basegfx::rad2deg<10>(fmod(nRotate, 2*M_PI))) ) ); // TODO(F2): Missing functionality in VCL: shearing o_rPoint.setX( ::basegfx::fround(aTranslate.getX()) ); @@ -190,6 +190,9 @@ namespace cairocanvas aVCLFont.SetColor( aColor ); aVCLFont.SetFillColor( aColor ); + if (pFont->getEmphasisMark()) + aVCLFont.SetEmphasisMark(FontEmphasisMark(pFont->getEmphasisMark())); + // no need to replicate this for mp2ndOutDev, we're modifying only aVCLFont here. if( !setupFontTransform( rOutDev, o_rOutPos, aVCLFont, viewState, renderState ) ) return false; @@ -226,21 +229,21 @@ namespace cairocanvas return uno::Reference< rendering::XCachedPrimitive >(nullptr); // no output necessary // change text direction and layout mode - ComplexTextLayoutFlags nLayoutMode(ComplexTextLayoutFlags::Default); + vcl::text::ComplexTextLayoutFlags nLayoutMode(vcl::text::ComplexTextLayoutFlags::Default); switch( textDirection ) { case rendering::TextDirection::WEAK_LEFT_TO_RIGHT: case rendering::TextDirection::STRONG_LEFT_TO_RIGHT: - nLayoutMode |= ComplexTextLayoutFlags::BiDiStrong; - nLayoutMode |= ComplexTextLayoutFlags::TextOriginLeft; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::TextOriginLeft; break; case rendering::TextDirection::WEAK_RIGHT_TO_LEFT: - nLayoutMode |= ComplexTextLayoutFlags::BiDiRtl; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiRtl; [[fallthrough]]; case rendering::TextDirection::STRONG_RIGHT_TO_LEFT: - nLayoutMode |= ComplexTextLayoutFlags::BiDiRtl | ComplexTextLayoutFlags::BiDiStrong; - nLayoutMode |= ComplexTextLayoutFlags::TextOriginRight; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiRtl | vcl::text::ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::TextOriginRight; break; } diff --git a/canvas/source/cairo/cairo_devicehelper.cxx b/canvas/source/cairo/cairo_devicehelper.cxx index e802e79cc2dd..3d3f7ef8301c 100644 --- a/canvas/source/cairo/cairo_devicehelper.cxx +++ b/canvas/source/cairo/cairo_devicehelper.cxx @@ -39,8 +39,7 @@ namespace cairocanvas { DeviceHelper::DeviceHelper() : mpSurfaceProvider( nullptr ), - mpRefDevice( nullptr ), - mpSurface() + mpRefDevice( nullptr ) { } @@ -77,7 +76,7 @@ namespace cairocanvas { SAL_INFO( "canvas.cairo", - "device size " << rSize.getX() << " x " << rSize.getY()); + "device size " << rSize.getWidth() << " x " << rSize.getHeight()); if( !mpRefDevice ) return; // disposed @@ -86,15 +85,15 @@ namespace cairocanvas // X11 only bool bReuseSurface = mpSurface && - mpSurface->Resize(rSize.getX() + pOutDev->GetOutOffXPixel(), - rSize.getY() + pOutDev->GetOutOffYPixel()); + mpSurface->Resize(rSize.getWidth() + pOutDev->GetOutOffXPixel(), + rSize.getHeight() + pOutDev->GetOutOffYPixel()); if (!bReuseSurface) { mpSurface = pOutDev->CreateSurface( pOutDev->GetOutOffXPixel(), pOutDev->GetOutOffYPixel(), - rSize.getX(), rSize.getY() ); + rSize.getWidth(), rSize.getHeight() ); } } @@ -210,22 +209,11 @@ namespace cairocanvas return uno::Any(); } - namespace - { - struct DeviceColorSpace: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, - DeviceColorSpace> - { - uno::Reference<rendering::XColorSpace> operator()() - { - return vcl::unotools::createStandardColorSpace(); - } - }; - } - uno::Reference<rendering::XColorSpace> const & DeviceHelper::getColorSpace() const { + static uno::Reference<rendering::XColorSpace> SPACE = vcl::unotools::createStandardColorSpace(); // always the same - return DeviceColorSpace::get(); + return SPACE; } void DeviceHelper::dumpScreenContent() const @@ -252,7 +240,7 @@ namespace cairocanvas SurfaceSharedPtr DeviceHelper::createSurface( const ::basegfx::B2ISize& rSize, int aContent ) { if( mpSurface ) - return mpSurface->getSimilar( aContent, rSize.getX(), rSize.getY() ); + return mpSurface->getSimilar( aContent, rSize.getWidth(), rSize.getHeight() ); return SurfaceSharedPtr(); } diff --git a/canvas/source/cairo/cairo_repainttarget.hxx b/canvas/source/cairo/cairo_repainttarget.hxx index 558ec7921ecb..94d3d3845b3e 100644 --- a/canvas/source/cairo/cairo_repainttarget.hxx +++ b/canvas/source/cairo/cairo_repainttarget.hxx @@ -33,7 +33,7 @@ namespace cairocanvas This interface must be implemented on all canvas implementations that hand out XCachedPrimitives */ - class RepaintTarget + class SAL_LOPLUGIN_ANNOTATE("crosscast") RepaintTarget { public: virtual ~RepaintTarget() {} diff --git a/canvas/source/cairo/cairo_spritecanvas.cxx b/canvas/source/cairo/cairo_spritecanvas.cxx index ddb4491afdf2..be26b17774d7 100644 --- a/canvas/source/cairo/cairo_spritecanvas.cxx +++ b/canvas/source/cairo/cairo_spritecanvas.cxx @@ -27,7 +27,7 @@ #include <com/sun/star/lang/NoSupportException.hpp> #include <osl/mutex.hxx> #include <toolkit/helper/vclunohelper.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <cppuhelper/supportsservice.hxx> #include "cairo_spritecanvas.hxx" @@ -77,7 +77,7 @@ namespace cairocanvas throw lang::NoSupportException( "Parent window not VCL window, or canvas out-of-process!", nullptr); - bool bHasCairo = pParentWindow->SupportsCairo(); + bool bHasCairo = pParentWindow->GetOutDev()->SupportsCairo(); ENSURE_ARG_OR_THROW(bHasCairo, "CairoSpriteCanvas::SpriteCanvas: No Cairo capability"); @@ -144,7 +144,7 @@ namespace cairocanvas } OUString SpriteCanvas::getImplementationName() { - return "com.sun.star.comp.rendering.Canvas.Cairo"; + return u"com.sun.star.comp.rendering.SpriteCanvas.Cairo"_ustr; } css::uno::Sequence< OUString > SpriteCanvas::getSupportedServiceNames() { @@ -224,10 +224,9 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* com_sun_star_comp_rendering_SpriteCanvas_Cairo_get_implementation( css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) { - auto p = new cairocanvas::SpriteCanvas(args, context); - p->acquire(); + rtl::Reference<cairocanvas::SpriteCanvas> p = new cairocanvas::SpriteCanvas(args, context); p->initialize(); - return static_cast<cppu::OWeakObject*>(p); + return cppu::acquire(p.get()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/cairo/cairo_spritecanvashelper.cxx b/canvas/source/cairo/cairo_spritecanvashelper.cxx index 47bde21e6f25..3fcfd734ab2f 100644 --- a/canvas/source/cairo/cairo_spritecanvashelper.cxx +++ b/canvas/source/cairo/cairo_spritecanvashelper.cxx @@ -23,7 +23,7 @@ #include <boost/cast.hpp> #include <basegfx/range/b2irange.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> @@ -91,8 +91,6 @@ namespace cairocanvas SpriteCanvasHelper::SpriteCanvasHelper() : mpRedrawManager( nullptr ), mpOwningSpriteCanvas( nullptr ), - mpCompositingSurface(), - maCompositingSurfaceSize(), mbCompositingSurfaceDirty(true) { } @@ -187,7 +185,7 @@ namespace cairocanvas // background has changed, so we currently have no choice // but repaint everything (or caller requested that) - cairo_rectangle( pCompositingCairo.get(), 0, 0, rSize.getX(), rSize.getY() ); + cairo_rectangle( pCompositingCairo.get(), 0, 0, rSize.getWidth(), rSize.getHeight() ); cairo_clip( pCompositingCairo.get() ); cairo_save( pCompositingCairo.get() ); cairo_set_source_surface( pCompositingCairo.get(), @@ -205,7 +203,7 @@ namespace cairocanvas ); // flush to screen - cairo_rectangle( pWindowCairo.get(), 0, 0, rSize.getX(), rSize.getY() ); + cairo_rectangle( pWindowCairo.get(), 0, 0, rSize.getWidth(), rSize.getHeight() ); cairo_clip( pWindowCairo.get() ); cairo_set_source_surface( pWindowCairo.get(), pCompositingSurface->getCairoSurface().get(), @@ -247,8 +245,8 @@ namespace cairocanvas const ::basegfx::B2ISize& rSize = mpOwningSpriteCanvas->getSizePixel(); const ::basegfx::B2IRange aOutputBounds( 0,0, - rSize.getX(), - rSize.getY() ); + rSize.getWidth(), + rSize.getHeight() ); SurfaceSharedPtr pCompositingSurface = getCompositingSurface(rSize); SurfaceSharedPtr pWindowSurface = mpOwningSpriteCanvas->getWindowSurface(); @@ -314,7 +312,7 @@ namespace cairocanvas aDestPos.getY() - aSourceUpperLeftPos.getY() ); cairo_rectangle( pScrollCairo.get(), aDestPos.getX(), aDestPos.getY(), - aScrollSize.getX(), aScrollSize.getY() ); + aScrollSize.getWidth(), aScrollSize.getHeight() ); cairo_clip( pScrollCairo.get() ); cairo_set_operator( pScrollCairo.get(), CAIRO_OPERATOR_SOURCE ); cairo_paint( pScrollCairo.get() ); @@ -327,7 +325,7 @@ namespace cairocanvas 0, 0 ); cairo_rectangle( pCompositingCairo.get(), aDestPos.getX(), aDestPos.getY(), - aScrollSize.getX(), aScrollSize.getY() ); + aScrollSize.getWidth(), aScrollSize.getHeight() ); cairo_clip( pCompositingCairo.get() ); cairo_set_operator( pCompositingCairo.get(), CAIRO_OPERATOR_SOURCE ); cairo_paint( pCompositingCairo.get() ); @@ -361,7 +359,7 @@ namespace cairocanvas repaintBackground( pCompositingCairo, mpOwningSpriteCanvas->getBufferSurface(), rArea ); - cairo_rectangle( pWindowCairo.get(), 0, 0, rSize.getX(), rSize.getY() ); + cairo_rectangle( pWindowCairo.get(), 0, 0, rSize.getWidth(), rSize.getHeight() ); cairo_clip( pWindowCairo.get() ); cairo_set_source_surface( pWindowCairo.get(), pCompositingSurface->getCairoSurface().get(), @@ -386,7 +384,7 @@ namespace cairocanvas CairoSharedPtr pCompositingCairo = pCompositingSurface->getCairo(); CairoSharedPtr pWindowCairo = pWindowSurface->getCairo(); - cairo_rectangle( pCompositingCairo.get(), 0, 0, rDeviceSize.getX(), rDeviceSize.getY() ); + cairo_rectangle( pCompositingCairo.get(), 0, 0, rDeviceSize.getWidth(), rDeviceSize.getHeight() ); cairo_clip( pCompositingCairo.get() ); ::basegfx::B2DVector aPos( ceil( rTotalArea.getMinX() ), ceil( rTotalArea.getMinY() ) ); @@ -404,7 +402,7 @@ namespace cairocanvas } // flush to screen - cairo_rectangle( pWindowCairo.get(), 0, 0, rDeviceSize.getX(), rDeviceSize.getY() ); + cairo_rectangle( pWindowCairo.get(), 0, 0, rDeviceSize.getWidth(), rDeviceSize.getHeight() ); cairo_clip( pWindowCairo.get() ); cairo_rectangle( pWindowCairo.get(), aPos.getX(), aPos.getY(), aSize.getX(), aSize.getY() ); cairo_clip( pWindowCairo.get() ); @@ -446,9 +444,9 @@ namespace cairocanvas // fraction of a sprite pixel... Limit size of VDev to output // device's area. const Size aOutputSize( - std::min( rSize.getX(), + std::min( rSize.getWidth(), ::canvas::tools::roundUp( rRequestedArea.getMaxX() - aOutputPosition.X()) ), - std::min( rSize.getY(), + std::min( rSize.getHeight(), ::canvas::tools::roundUp( rRequestedArea.getMaxY() - aOutputPosition.Y()) ) ); cairo_rectangle( pCompositingCairo.get(), aOutputPosition.X(), aOutputPosition.Y(), aOutputSize.Width(), aOutputSize.Height() ); @@ -484,8 +482,8 @@ namespace cairocanvas ::cairo::SurfaceSharedPtr const & SpriteCanvasHelper::getCompositingSurface( const ::basegfx::B2ISize& rNeededSize ) { - if( rNeededSize.getX() > maCompositingSurfaceSize.getX() || - rNeededSize.getY() > maCompositingSurfaceSize.getY() ) + if( rNeededSize.getWidth() > maCompositingSurfaceSize.getWidth() || + rNeededSize.getHeight() > maCompositingSurfaceSize.getHeight() ) { // need to give buffer more size mpCompositingSurface.reset(); @@ -513,7 +511,7 @@ namespace cairocanvas { return mpOwningSpriteCanvas->getWindowSurface()->getSimilar( CAIRO_CONTENT_COLOR, - rNeededSize.getX(), rNeededSize.getY() ); + rNeededSize.getWidth(), rNeededSize.getHeight() ); } } diff --git a/canvas/source/cairo/cairo_spritedevicehelper.cxx b/canvas/source/cairo/cairo_spritedevicehelper.cxx index 825d6f343b43..69a057c9918f 100644 --- a/canvas/source/cairo/cairo_spritedevicehelper.cxx +++ b/canvas/source/cairo/cairo_spritedevicehelper.cxx @@ -35,8 +35,6 @@ namespace cairocanvas SpriteDeviceHelper::SpriteDeviceHelper() : mpSpriteCanvas( nullptr ), - mpBufferSurface(), - maSize(), mbFullScreen( false ) {} @@ -46,7 +44,7 @@ namespace cairocanvas bool bFullscreen ) { DeviceHelper::init(rSpriteCanvas, - rOutputWindow); + *rOutputWindow.GetOutDev()); mpSpriteCanvas = &rSpriteCanvas; mbFullScreen = bFullscreen; @@ -92,7 +90,7 @@ namespace cairocanvas { SAL_INFO( "canvas.cairo", - "device size " << rSize.getX() << " x " << rSize.getY()); + "device size " << rSize.getWidth() << " x " << rSize.getHeight()); if( !mpSpriteCanvas ) return; // disposed @@ -104,7 +102,7 @@ namespace cairocanvas if( !mpBufferSurface ) mpBufferSurface = getWindowSurface()->getSimilar( CAIRO_CONTENT_COLOR, - rSize.getX(), rSize.getY() ); + rSize.getWidth(), rSize.getHeight() ); if( maSize != rSize ) maSize = rSize; @@ -126,7 +124,7 @@ namespace cairocanvas SurfaceSharedPtr SpriteDeviceHelper::createSurface( const ::basegfx::B2ISize& rSize, int aContent ) { if( mpBufferSurface ) - return mpBufferSurface->getSimilar( aContent, rSize.getX(), rSize.getY() ); + return mpBufferSurface->getSimilar( aContent, rSize.getWidth(), rSize.getHeight() ); return SurfaceSharedPtr(); } diff --git a/canvas/source/cairo/cairo_spritehelper.cxx b/canvas/source/cairo/cairo_spritehelper.cxx index 1fe9eb9152e0..4e536261989c 100644 --- a/canvas/source/cairo/cairo_spritehelper.cxx +++ b/canvas/source/cairo/cairo_spritehelper.cxx @@ -25,9 +25,10 @@ #include <basegfx/point/b2dpoint.hxx> #include <basegfx/utils/canvastools.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <cairo.h> +#include <pixman.h> #include "cairo_spritehelper.hxx" @@ -37,8 +38,6 @@ using namespace ::com::sun::star; namespace cairocanvas { SpriteHelper::SpriteHelper() : - mpSpriteCanvas(), - mpBufferSurface(), mbTextureDirty(true) {} @@ -52,8 +51,7 @@ namespace cairocanvas mbTextureDirty = true; // also init base class - CanvasCustomSpriteHelper::init( rSpriteSize, - rSpriteCanvas.get() ); + CanvasCustomSpriteHelper::init( rSpriteSize, rSpriteCanvas ); } void SpriteHelper::setSurface( const SurfaceSharedPtr& pBufferSurface ) @@ -131,7 +129,7 @@ namespace cairocanvas rClip )); doPolyPolygonImplementation( aClipPoly, Clip, pCairo.get(), - nullptr, SurfaceProviderRef(mpSpriteCanvas.get()), + nullptr, SurfaceProviderRef(mpSpriteCanvas), rClip->getFillRule() ); } @@ -140,6 +138,37 @@ namespace cairocanvas cairo_clip( pCairo.get() ); cairo_set_matrix( pCairo.get(), &aOrigMatrix ); + cairo_matrix_t aInverseMatrix = aOrigMatrix; + bool matrixProblem = false; + // tdf#125949: Cairo internally uses the pixman library, and _cairo_matrix_to_pixman_matrix() + // checks all matrix components to fix PIXMAN_MAX_INT, which is about 32k. Which means that + // if our transformation is large, such as an initial step of some zooming animations, + // the conversion will fail. To make things worse, once something in cairo fails, it's treated + // as a fatal error, the error status of that cairo_t gets set, and there's no way to reset it + // besides recreating the whole cairo_t + // (https://lists.cairographics.org/archives/cairo/2006-September/007892.html). + // So copy&paste PIXMAN_MAX_INT here, and if our matrix could fail, bail out. +#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ + if(cairo_matrix_invert(&aInverseMatrix) == CAIRO_STATUS_SUCCESS) + { + if(abs(aOrigMatrix.xx) > PIXMAN_MAX_INT || abs(aOrigMatrix.xx) > PIXMAN_MAX_INT + || abs(aOrigMatrix.xy) > PIXMAN_MAX_INT || abs(aOrigMatrix.yx) > PIXMAN_MAX_INT + || abs(aOrigMatrix.x0) > PIXMAN_MAX_INT || abs(aOrigMatrix.y0) > PIXMAN_MAX_INT + || abs(aInverseMatrix.xx) > PIXMAN_MAX_INT || abs(aInverseMatrix.xx) > PIXMAN_MAX_INT + || abs(aInverseMatrix.xy) > PIXMAN_MAX_INT || abs(aInverseMatrix.yx) > PIXMAN_MAX_INT + || abs(aInverseMatrix.x0) > PIXMAN_MAX_INT || abs(aInverseMatrix.y0) > PIXMAN_MAX_INT) + matrixProblem = true; +#undef PIXMAN_MAX_INT + } + else + matrixProblem = true; + if(matrixProblem) + { + SAL_WARN( "canvas.cairo", "matrix would overflow PIXMAN_MAX_INT, avoiding drawing" ); + cairo_restore( pCairo.get() ); + return; + } + if( isContentFullyOpaque() ) cairo_set_operator( pCairo.get(), CAIRO_OPERATOR_SOURCE ); cairo_set_source_surface( pCairo.get(), diff --git a/canvas/source/cairo/cairo_surfaceprovider.hxx b/canvas/source/cairo/cairo_surfaceprovider.hxx index a5115a507863..1ff6f2aa7d3f 100644 --- a/canvas/source/cairo/cairo_surfaceprovider.hxx +++ b/canvas/source/cairo/cairo_surfaceprovider.hxx @@ -37,7 +37,7 @@ namespace cairocanvas This interface must be implemented on all canvas implementations that hand out XCachedPrimitives */ - class SurfaceProvider : public css::uno::XInterface + class SAL_LOPLUGIN_ANNOTATE("crosscast") SurfaceProvider : public css::uno::XInterface { public: virtual ~SurfaceProvider() {} diff --git a/canvas/source/cairo/cairo_textlayout.cxx b/canvas/source/cairo/cairo_textlayout.cxx index 4094bd605e47..e033040d01b2 100644 --- a/canvas/source/cairo/cairo_textlayout.cxx +++ b/canvas/source/cairo/cairo_textlayout.cxx @@ -21,18 +21,18 @@ #include <sal/log.hxx> #include <math.h> -#include <memory> #include <com/sun/star/rendering/TextDirection.hpp> #include <canvas/canvastools.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/numeric/ftools.hxx> #include <cppuhelper/supportsservice.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> +#include <utility> +#include <vcl/kernarray.hxx> #include <vcl/metric.hxx> #include <vcl/virdev.hxx> - #include "cairo_textlayout.hxx" using namespace ::cairo; @@ -46,19 +46,19 @@ namespace cairocanvas sal_Int8 nTextDirection ) { // TODO(P3): avoid if already correctly set - ComplexTextLayoutFlags nLayoutMode = ComplexTextLayoutFlags::Default; + vcl::text::ComplexTextLayoutFlags nLayoutMode = vcl::text::ComplexTextLayoutFlags::Default; switch( nTextDirection ) { case rendering::TextDirection::WEAK_LEFT_TO_RIGHT: break; case rendering::TextDirection::STRONG_LEFT_TO_RIGHT: - nLayoutMode = ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode = vcl::text::ComplexTextLayoutFlags::BiDiStrong; break; case rendering::TextDirection::WEAK_RIGHT_TO_LEFT: - nLayoutMode = ComplexTextLayoutFlags::BiDiRtl; + nLayoutMode = vcl::text::ComplexTextLayoutFlags::BiDiRtl; break; case rendering::TextDirection::STRONG_RIGHT_TO_LEFT: - nLayoutMode = ComplexTextLayoutFlags::BiDiRtl | ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode = vcl::text::ComplexTextLayoutFlags::BiDiRtl | vcl::text::ComplexTextLayoutFlags::BiDiStrong; break; default: break; @@ -66,20 +66,18 @@ namespace cairocanvas // set calculated layout mode. Origin is always the left edge, // as required at the API spec - rOutDev.SetLayoutMode( nLayoutMode | ComplexTextLayoutFlags::TextOriginLeft ); + rOutDev.SetLayoutMode( nLayoutMode | vcl::text::ComplexTextLayoutFlags::TextOriginLeft ); } } - TextLayout::TextLayout( const rendering::StringContext& aText, - sal_Int8 nDirection, - sal_Int64 /*nRandomSeed*/, - const CanvasFont::Reference& rFont, - const SurfaceProviderRef& rRefDevice ) : - TextLayout_Base( m_aMutex ), - maText( aText ), - maLogicalAdvancements(), - mpFont( rFont ), - mpRefDevice( rRefDevice ), + TextLayout::TextLayout( rendering::StringContext aText, + sal_Int8 nDirection, + sal_Int64 /*nRandomSeed*/, + CanvasFont::Reference rFont, + SurfaceProviderRef rRefDevice ) : + maText(std::move( aText )), + mpFont(std::move( rFont )), + mpRefDevice(std::move( rRefDevice )), mnTextDirection( nDirection ) { } @@ -88,10 +86,8 @@ namespace cairocanvas { } - void SAL_CALL TextLayout::disposing() + void TextLayout::disposing(std::unique_lock<std::mutex>& /*rGuard*/) { - ::osl::MutexGuard aGuard( m_aMutex ); - mpFont.clear(); mpRefDevice.clear(); } @@ -117,27 +113,47 @@ namespace cairocanvas uno::Sequence< double > SAL_CALL TextLayout::queryLogicalAdvancements( ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maLogicalAdvancements; } void SAL_CALL TextLayout::applyLogicalAdvancements( const uno::Sequence< double >& aAdvancements ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); if( aAdvancements.getLength() != maText.Length ) { SAL_WARN("canvas.cairo", "TextLayout::applyLogicalAdvancements(): mismatching number of advancements" ); - throw lang::IllegalArgumentException("mismatching number of advancements", static_cast<cppu::OWeakObject*>(this), 1); + throw lang::IllegalArgumentException("mismatching number of advancements", getXWeak(), 1); } maLogicalAdvancements = aAdvancements; } + uno::Sequence< sal_Bool > SAL_CALL TextLayout::queryKashidaPositions( ) + { + std::unique_lock aGuard( m_aMutex ); + + return maKashidaPositions; + } + + void SAL_CALL TextLayout::applyKashidaPositions( const uno::Sequence< sal_Bool >& aPositions ) + { + std::unique_lock aGuard( m_aMutex ); + + if( aPositions.hasElements() && aPositions.getLength() != maText.Length ) + { + SAL_WARN("canvas.cairo", "TextLayout::applyKashidaPositions(): mismatching number of positions" ); + throw lang::IllegalArgumentException("mismatching number of positions", getXWeak(), 1); + } + + maKashidaPositions = aPositions; + } + geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds( ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); OutputDevice* pOutDev = mpRefDevice->getOutputDevice(); if( !pOutDev ) @@ -228,22 +244,18 @@ namespace cairocanvas sal_Int8 SAL_CALL TextLayout::getMainTextDirection( ) { - ::osl::MutexGuard aGuard( m_aMutex ); - return mnTextDirection; } uno::Reference< rendering::XCanvasFont > SAL_CALL TextLayout::getFont( ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); - return mpFont.get(); + return mpFont; } rendering::StringContext SAL_CALL TextLayout::getText( ) { - ::osl::MutexGuard aGuard( m_aMutex ); - return maText; } @@ -261,17 +273,15 @@ namespace cairocanvas const rendering::ViewState& viewState, const rendering::RenderState& renderState ) const { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); setupLayoutMode( rOutDev, mnTextDirection ); - std::unique_ptr< tools::Long []> aOffsets(new tools::Long[maLogicalAdvancements.getLength()]); - - if( maLogicalAdvancements.hasElements() ) - setupTextOffsets( aOffsets.get(), maLogicalAdvancements, viewState, renderState ); - if (maLogicalAdvancements.hasElements()) { - rOutDev.DrawTextArray( rOutpos, maText.Text, aOffsets.get(), + KernArray aOffsets(setupTextOffsets(maLogicalAdvancements, viewState, renderState)); + std::span<const sal_Bool> aKashidaArray(maKashidaPositions.getConstArray(), maKashidaPositions.getLength()); + + rOutDev.DrawTextArray( rOutpos, maText.Text, aOffsets, aKashidaArray, ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition), ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) ); } @@ -288,8 +298,8 @@ namespace cairocanvas class OffsetTransformer { public: - explicit OffsetTransformer( const ::basegfx::B2DHomMatrix& rMat ) : - maMatrix( rMat ) + explicit OffsetTransformer( ::basegfx::B2DHomMatrix aMat ) : + maMatrix(std::move( aMat )) { } @@ -315,14 +325,11 @@ namespace cairocanvas }; } - void TextLayout::setupTextOffsets( tools::Long* outputOffsets, + KernArray TextLayout::setupTextOffsets( const uno::Sequence< double >& inputOffsets, const rendering::ViewState& viewState, const rendering::RenderState& renderState ) const { - ENSURE_OR_THROW( outputOffsets!=nullptr, - "TextLayout::setupTextOffsets offsets NULL" ); - ::basegfx::B2DHomMatrix aMatrix; ::canvas::tools::mergeViewAndRenderTransform(aMatrix, @@ -330,15 +337,16 @@ namespace cairocanvas renderState); // fill integer offsets - std::transform( inputOffsets.begin(), - inputOffsets.end(), - outputOffsets, - OffsetTransformer( aMatrix ) ); + KernArray outputOffsets; + OffsetTransformer aTransform(aMatrix); + std::for_each(inputOffsets.begin(), inputOffsets.end(), + [&outputOffsets, &aTransform](double n) {outputOffsets.push_back(aTransform(n)); } ); + return outputOffsets; } OUString SAL_CALL TextLayout::getImplementationName() { - return "CairoCanvas::TextLayout"; + return u"CairoCanvas::TextLayout"_ustr; } sal_Bool SAL_CALL TextLayout::supportsService( const OUString& ServiceName ) @@ -348,7 +356,7 @@ namespace cairocanvas uno::Sequence< OUString > SAL_CALL TextLayout::getSupportedServiceNames() { - return { "com.sun.star.rendering.TextLayout" }; + return { u"com.sun.star.rendering.TextLayout"_ustr }; } } diff --git a/canvas/source/cairo/cairo_textlayout.hxx b/canvas/source/cairo/cairo_textlayout.hxx index b4159e737e48..ed8265e8b391 100644 --- a/canvas/source/cairo/cairo_textlayout.hxx +++ b/canvas/source/cairo/cairo_textlayout.hxx @@ -19,8 +19,7 @@ #pragma once -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> +#include <comphelper/compbase.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/rendering/RenderState.hpp> @@ -36,25 +35,24 @@ namespace cairocanvas { - typedef ::cppu::WeakComponentImplHelper< css::rendering::XTextLayout, + typedef ::comphelper::WeakComponentImplHelper< css::rendering::XTextLayout, css::lang::XServiceInfo > TextLayout_Base; - class TextLayout : public ::cppu::BaseMutex, - public TextLayout_Base + class TextLayout : public TextLayout_Base { public: /// make noncopyable TextLayout(const TextLayout&) = delete; const TextLayout& operator=(const TextLayout&) = delete; - TextLayout( const css::rendering::StringContext& aText, - sal_Int8 nDirection, - sal_Int64 nRandomSeed, - const CanvasFont::Reference& rFont, - const SurfaceProviderRef& rRefDevice ); + TextLayout( css::rendering::StringContext aText, + sal_Int8 nDirection, + sal_Int64 nRandomSeed, + CanvasFont::Reference rFont, + SurfaceProviderRef rRefDevice ); /// Dispose all internal references - virtual void SAL_CALL disposing() override; + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; // XTextLayout virtual css::uno::Sequence< css::uno::Reference< css::rendering::XPolyPolygon2D > > SAL_CALL queryTextShapes( ) override; @@ -62,6 +60,8 @@ namespace cairocanvas virtual css::uno::Sequence< css::geometry::RealRectangle2D > SAL_CALL queryMeasures( ) override; virtual css::uno::Sequence< double > SAL_CALL queryLogicalAdvancements( ) override; virtual void SAL_CALL applyLogicalAdvancements( const css::uno::Sequence< double >& aAdvancements ) override; + virtual css::uno::Sequence< sal_Bool > SAL_CALL queryKashidaPositions( ) override; + virtual void SAL_CALL applyKashidaPositions( const css::uno::Sequence< sal_Bool >& aPositions ) override; virtual css::geometry::RealRectangle2D SAL_CALL queryTextBounds( ) override; virtual double SAL_CALL justify( double nSize ) override; virtual double SAL_CALL combinedJustify( const css::uno::Sequence< css::uno::Reference< css::rendering::XTextLayout > >& aNextLayouts, double nSize ) override; @@ -85,7 +85,7 @@ namespace cairocanvas const css::rendering::ViewState& viewState, const css::rendering::RenderState& renderState ) const; - void setupTextOffsets( tools::Long* outputOffsets, + KernArray setupTextOffsets( const css::uno::Sequence< double >& inputOffsets, const css::rendering::ViewState& viewState, const css::rendering::RenderState& renderState ) const; @@ -96,6 +96,7 @@ namespace cairocanvas private: css::rendering::StringContext maText; css::uno::Sequence< double > maLogicalAdvancements; + css::uno::Sequence< sal_Bool > maKashidaPositions; CanvasFont::Reference mpFont; SurfaceProviderRef mpRefDevice; sal_Int8 mnTextDirection; diff --git a/canvas/source/directx/dx_9rm.cxx b/canvas/source/directx/dx_9rm.cxx index 0c8667c5f7ea..93738b3455cf 100644 --- a/canvas/source/directx/dx_9rm.cxx +++ b/canvas/source/directx/dx_9rm.cxx @@ -31,7 +31,7 @@ #include <com/sun/star/lang/NoSupportException.hpp> #include <osl/thread.hxx> #include <osl/time.h> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/syschild.hxx> #include <vcl/sysdata.hxx> #include <vcl/window.hxx> @@ -92,7 +92,7 @@ namespace dxcanvas virtual bool update( const ::basegfx::B2IPoint& rDestPos, const ::basegfx::B2IRange& rSourceRect, ::canvas::IColorBuffer& rSource ) override; - virtual ::basegfx::B2IVector getSize(); + virtual ::basegfx::B2ISize getSize(); private: /// Guard local methods against concurrent access to RenderModule @@ -111,9 +111,9 @@ namespace dxcanvas }; DXRenderModule& mrRenderModule; - COMReference<IDirect3DTexture9> mpTexture; + sal::systools::COMReference<IDirect3DTexture9> mpTexture; - ::basegfx::B2IVector maSize; + ::basegfx::B2ISize maSize; }; @@ -130,8 +130,8 @@ namespace dxcanvas virtual void lock() const override { maMutex.acquire(); } virtual void unlock() const override { maMutex.release(); } - virtual COMReference<IDirect3DSurface9> - createSystemMemorySurface( const ::basegfx::B2IVector& rSize ) override; + virtual sal::systools::COMReference<IDirect3DSurface9> + createSystemMemorySurface(const ::basegfx::B2ISize& rSize) override; virtual void disposing() override; virtual HWND getHWND() const override { return mhWnd; } virtual void screenShot() override; @@ -147,7 +147,7 @@ namespace dxcanvas virtual void pushVertex( const ::canvas::Vertex& vertex ) override; virtual bool isError() override; - COMReference<IDirect3DDevice9> getDevice() { return mpDevice; } + sal::systools::COMReference<IDirect3DDevice9> getDevice() { return mpDevice; } void flushVertexCache(); void commitVertexCache(); @@ -166,13 +166,13 @@ namespace dxcanvas static ::osl::Mutex maMutex; HWND mhWnd; - COMReference<IDirect3DDevice9> mpDevice; - COMReference<IDirect3D9> mpDirect3D9; - COMReference<IDirect3DSwapChain9> mpSwapChain; - COMReference<IDirect3DVertexBuffer9> mpVertexBuffer; + sal::systools::COMReference<IDirect3DDevice9> mpDevice; + sal::systools::COMReference<IDirect3D9> mpDirect3D9; + sal::systools::COMReference<IDirect3DSwapChain9> mpSwapChain; + sal::systools::COMReference<IDirect3DVertexBuffer9> mpVertexBuffer; std::shared_ptr<canvas::ISurface> mpTexture; VclPtr<SystemChildWindow> mpWindow; - ::basegfx::B2IVector maSize; + ::basegfx::B2ISize maSize; typedef std::vector<canvas::Vertex> vertexCache_t; vertexCache_t maVertexCache; std::size_t mnCount; @@ -225,8 +225,7 @@ namespace dxcanvas DXSurface::DXSurface( DXRenderModule& rRenderModule, const ::basegfx::B2ISize& rSize ) : mrRenderModule(rRenderModule), - mpTexture(nullptr), - maSize() + mpTexture(nullptr) { ImplRenderModuleGuard aGuard( mrRenderModule ); @@ -237,27 +236,27 @@ namespace dxcanvas #endif #ifdef FAKE_MAX_TEXTURE_SIZE - if(rSize.getX() > FAKE_MAX_TEXTURE_SIZE) + if(rSize.getWidth() > FAKE_MAX_TEXTURE_SIZE) return; - if(rSize.getY() > FAKE_MAX_TEXTURE_SIZE) + if(rSize.getHeight() > FAKE_MAX_TEXTURE_SIZE) return; #endif - ENSURE_ARG_OR_THROW(rSize.getX() > 0 && rSize.getY() > 0, + ENSURE_ARG_OR_THROW(rSize.getWidth() > 0 && rSize.getHeight() > 0, "DXSurface::DXSurface(): request for zero-sized surface"); - COMReference<IDirect3DDevice9> pDevice(rRenderModule.getDevice()); + sal::systools::COMReference<IDirect3DDevice9> pDevice(rRenderModule.getDevice()); IDirect3DTexture9 *pTexture(nullptr); if(FAILED(pDevice->CreateTexture( - rSize.getX(), - rSize.getY(), + rSize.getWidth(), + rSize.getHeight(), 1,0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture,nullptr))) return; - mpTexture=COMReference<IDirect3DTexture9>(pTexture); + mpTexture = sal::systools::COMReference<IDirect3DTexture9>(pTexture, false); maSize = rSize; } @@ -282,7 +281,7 @@ namespace dxcanvas { ImplRenderModuleGuard aGuard( mrRenderModule ); mrRenderModule.flushVertexCache(); - COMReference<IDirect3DDevice9> pDevice(mrRenderModule.getDevice()); + sal::systools::COMReference<IDirect3DDevice9> pDevice(mrRenderModule.getDevice()); if( FAILED(pDevice->SetTexture(0,mpTexture.get())) ) return false; @@ -325,12 +324,12 @@ namespace dxcanvas // to avoid interpolation artifacts from other textures, // the surface manager allocates one pixel gap between // them. Clear that to transparent. - rect.right = std::min(maSize.getX(), + rect.right = std::min(maSize.getWidth(), rect.left + sal_Int32(rSourceRect.getWidth()+1)); - rect.bottom = std::min(maSize.getY(), + rect.bottom = std::min(maSize.getHeight(), rect.top + sal_Int32(rSourceRect.getHeight()+1)); - const bool bClearRightColumn( rect.right < maSize.getX() ); - const bool bClearBottomRow( rect.bottom < maSize.getY() ); + const bool bClearRightColumn( rect.right < maSize.getWidth() ); + const bool bClearBottomRow( rect.bottom < maSize.getHeight() ); if(SUCCEEDED(mpTexture->LockRect(0,&aLockedRect,&rect,D3DLOCK_NOSYSLOCK))) { @@ -427,18 +426,11 @@ namespace dxcanvas return true; } - - // DXSurface::getSize - - - ::basegfx::B2IVector DXSurface::getSize() + ::basegfx::B2ISize DXSurface::getSize() { return maSize; } - // DXRenderModule::DXRenderModule - - DXRenderModule::DXRenderModule( const vcl::Window& rWindow ) : mhWnd(nullptr), mpDevice(), @@ -446,14 +438,12 @@ namespace dxcanvas mpSwapChain(), mpVertexBuffer(), mpTexture(), - maSize(), maVertexCache(), mnCount(0), mnBeginSceneCount(0), mbCanUseDynamicTextures(false), mbError( false ), meType( PrimitiveType::Unknown ), - maPageSize(), mad3dpp(), maNumVertices( VERTEX_BUFFER_SIZE ), maWriteIndex(0), @@ -469,10 +459,10 @@ namespace dxcanvas // allocate a single texture surface which can be used later. // we also use this to calibrate the page size. - ::basegfx::B2IVector aPageSize(maPageSize); + basegfx::B2IVector aPageSize(maPageSize); while(true) { - mpTexture = std::make_shared<DXSurface>(*this,aPageSize); + mpTexture = std::make_shared<DXSurface>(*this, basegfx::B2ISize(aPageSize.getX(), aPageSize.getY())); if(mpTexture->isValid()) break; @@ -499,7 +489,7 @@ namespace dxcanvas "Could not create DirectX device - out of memory!" ); } - mpVertexBuffer=COMReference<IDirect3DVertexBuffer9>(pVB); + mpVertexBuffer = sal::systools::COMReference<IDirect3DVertexBuffer9>(pVB, false); } @@ -542,8 +532,8 @@ namespace dxcanvas // TODO(F2): since we would like to share precious hardware // resources, the direct3d9 object should be global. each new // request for a canvas should only create a new swapchain. - mpDirect3D9 = COMReference<IDirect3D9>( - Direct3DCreate9(D3D_SDK_VERSION)); + mpDirect3D9 = sal::systools::COMReference<IDirect3D9>( + Direct3DCreate9(D3D_SDK_VERSION), false); if(!mpDirect3D9.is()) return false; @@ -569,7 +559,7 @@ namespace dxcanvas const HWND hwnd(reinterpret_cast<HWND>(pData->hWnd)); mhWnd = hwnd; - ENSURE_OR_THROW( IsWindow( reinterpret_cast<HWND>(mhWnd) ), + ENSURE_OR_THROW( IsWindow( mhWnd ), "DXRenderModule::create() No valid HWND given." ); // retrieve position and size of the parent window @@ -577,11 +567,11 @@ namespace dxcanvas // remember the size of the parent window, since we // need to use this for our child window. - maSize.setX(static_cast<sal_Int32>(rSizePixel.Width())); - maSize.setY(static_cast<sal_Int32>(rSizePixel.Height())); + maSize.setWidth(sal_Int32(rSizePixel.Width())); + maSize.setHeight(sal_Int32(rSizePixel.Height())); // let the child window cover the same size as the parent window. - mpWindow->setPosSizePixel(0,0,maSize.getX(),maSize.getY()); + mpWindow->setPosSizePixel(0, 0, maSize.getWidth(),maSize.getHeight()); // create a device from the direct3d9 object. if(!(createDevice())) @@ -697,10 +687,8 @@ namespace dxcanvas // a back buffer, and no way of falling back to a // different canvas implementation. ZeroMemory( &mad3dpp, sizeof(mad3dpp) ); - mad3dpp.BackBufferWidth = std::max(maSize.getX(), - sal_Int32(d3ddm.Width)); - mad3dpp.BackBufferHeight = std::max(maSize.getY(), - sal_Int32(d3ddm.Height)); + mad3dpp.BackBufferWidth = std::max(maSize.getWidth(), sal_Int32(d3ddm.Width)); + mad3dpp.BackBufferHeight = std::max(maSize.getHeight(), sal_Int32(d3ddm.Height)); mad3dpp.BackBufferCount = 1; mad3dpp.Windowed = TRUE; mad3dpp.SwapEffect = D3DSWAPEFFECT_COPY; @@ -730,12 +718,12 @@ namespace dxcanvas return false; // got it, store it in a safe place... - mpDevice=COMReference<IDirect3DDevice9>(pDevice); + mpDevice = sal::systools::COMReference<IDirect3DDevice9>(pDevice, false); // After CreateDevice, the first swap chain already exists, so just get it... IDirect3DSwapChain9 *pSwapChain(nullptr); pDevice->GetSwapChain(0,&pSwapChain); - mpSwapChain=COMReference<IDirect3DSwapChain9>(pSwapChain); + mpSwapChain = sal::systools::COMReference<IDirect3DSwapChain9>(pSwapChain, false); if( !mpSwapChain.is() ) return false; @@ -757,18 +745,18 @@ namespace dxcanvas // DXRenderModule::createSystemMemorySurface - COMReference<IDirect3DSurface9> DXRenderModule::createSystemMemorySurface( const ::basegfx::B2IVector& rSize ) + sal::systools::COMReference<IDirect3DSurface9> DXRenderModule::createSystemMemorySurface(const ::basegfx::B2ISize& rSize) { if(isDisposed()) - return COMReference<IDirect3DSurface9>(nullptr); + return sal::systools::COMReference<IDirect3DSurface9>(nullptr); // please note that D3DFMT_X8R8G8B8 is the only format we're // able to choose here, since GetDC() doesn't support any // other 32bit-format. IDirect3DSurface9 *pSurface(nullptr); if( FAILED(mpDevice->CreateOffscreenPlainSurface( - rSize.getX(), - rSize.getY(), + rSize.getWidth(), + rSize.getHeight(), D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &pSurface, @@ -778,7 +766,7 @@ namespace dxcanvas "Could not create offscreen surface - out of mem!" ); } - return COMReference<IDirect3DSurface9>(pSurface); + return sal::systools::COMReference<IDirect3DSurface9>(pSurface, false); } @@ -815,7 +803,7 @@ namespace dxcanvas // DX was kind enough to really reset the device... do { - mpVertexBuffer.reset(); + mpVertexBuffer.clear(); hr = mpDevice->Reset(&mad3dpp); if(SUCCEEDED(hr)) { @@ -830,7 +818,7 @@ namespace dxcanvas throw lang::NoSupportException( "Could not create DirectX device - out of memory!" ); } - mpVertexBuffer=COMReference<IDirect3DVertexBuffer9>(pVB); + mpVertexBuffer = sal::systools::COMReference<IDirect3DVertexBuffer9>(pVB, false); // retry after the restore if(SUCCEEDED(mpSwapChain->Present(&aRect,&aRect,nullptr,nullptr,0))) @@ -868,41 +856,41 @@ namespace dxcanvas return; // don't do anything if the size didn't change. - if(maSize.getX() == static_cast<sal_Int32>(rect.getWidth()) && - maSize.getY() == static_cast<sal_Int32>(rect.getHeight())) + if(maSize.getWidth() == static_cast<sal_Int32>(rect.getWidth()) && + maSize.getHeight() == static_cast<sal_Int32>(rect.getHeight())) return; // TODO(Q2): use numeric cast to prevent overflow - maSize.setX(static_cast<sal_Int32>(rect.getWidth())); - maSize.setY(static_cast<sal_Int32>(rect.getHeight())); + maSize.setWidth(sal_Int32(rect.getWidth())); + maSize.setHeight(sal_Int32(rect.getHeight())); - mpWindow->setPosSizePixel(0,0,maSize.getX(),maSize.getY()); + mpWindow->setPosSizePixel(0, 0, maSize.getWidth(), maSize.getHeight()); // resize back buffer, if necessary // don't attempt to create anything if the // requested size is NULL. - if(!(maSize.getX())) + if(!(maSize.getWidth())) return; - if(!(maSize.getY())) + if(!(maSize.getHeight())) return; // backbuffer too small (might happen, if window is // maximized across multiple monitors) - if( sal_Int32(mad3dpp.BackBufferWidth) < maSize.getX() || - sal_Int32(mad3dpp.BackBufferHeight) < maSize.getY() ) + if( sal_Int32(mad3dpp.BackBufferWidth) < maSize.getWidth() || + sal_Int32(mad3dpp.BackBufferHeight) < maSize.getHeight() ) { - mad3dpp.BackBufferWidth = maSize.getX(); - mad3dpp.BackBufferHeight = maSize.getY(); + mad3dpp.BackBufferWidth = maSize.getWidth(); + mad3dpp.BackBufferHeight = maSize.getHeight(); // clear before, save resources - mpSwapChain.reset(); + mpSwapChain.clear(); IDirect3DSwapChain9 *pSwapChain(nullptr); if(FAILED(mpDevice->CreateAdditionalSwapChain(&mad3dpp,&pSwapChain))) return; - mpSwapChain=COMReference<IDirect3DSwapChain9>(pSwapChain); + mpSwapChain = sal::systools::COMReference<IDirect3DSwapChain9>(pSwapChain, false); // clear the render target [which is the backbuffer in this case]. // we are forced to do this once, and furthermore right now. @@ -942,10 +930,10 @@ namespace dxcanvas const ::basegfx::B2IVector& rPageSize( getPageSize() ); ::basegfx::B2ISize aSize(surfaceSize); - if(!(aSize.getX())) - aSize.setX(rPageSize.getX()); - if(!(aSize.getY())) - aSize.setY(rPageSize.getY()); + if(!(aSize.getWidth())) + aSize.setWidth(rPageSize.getX()); + if(!(aSize.getHeight())) + aSize.setHeight(rPageSize.getY()); if(mpTexture.use_count() == 1) return mpTexture; diff --git a/canvas/source/directx/dx_bitmap.cxx b/canvas/source/directx/dx_bitmap.cxx index 2f42170d6d77..9e5f2348fa4f 100644 --- a/canvas/source/directx/dx_bitmap.cxx +++ b/canvas/source/directx/dx_bitmap.cxx @@ -23,7 +23,7 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/range/b2irange.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include "dx_bitmap.hxx" #include "dx_graphicsprovider.hxx" @@ -47,8 +47,8 @@ namespace dxcanvas { } - DXBitmap::DXBitmap( const ::basegfx::B2IVector& rSize, - bool bWithAlpha ) : + DXBitmap::DXBitmap( const ::basegfx::B2ISize& rSize, + bool bWithAlpha ) : mpGdiPlusUser( GDIPlusUser::createInstance() ), maSize(rSize), mpBitmap(), @@ -59,15 +59,15 @@ namespace dxcanvas if(mbAlpha) { mpBitmap = std::make_shared<Gdiplus::Bitmap>( - maSize.getX(), - maSize.getY(), + maSize.getWidth(), + maSize.getHeight(), PixelFormat32bppARGB); } else { mpBitmap = std::make_shared<Gdiplus::Bitmap>( - maSize.getX(), - maSize.getY(), + maSize.getWidth(), + maSize.getHeight(), PixelFormat24bppRGB); } @@ -84,7 +84,7 @@ namespace dxcanvas return mpGraphics; } - ::basegfx::B2IVector DXBitmap::getSize() const + ::basegfx::B2ISize DXBitmap::getSize() const { return maSize; } @@ -154,7 +154,7 @@ namespace dxcanvas // getMemoryLayout &aBmpData ) ) { - throw uno::RuntimeException(); + throw uno::RuntimeException("Internal error while writing BitmapData into Bitmap"); } // commit data to bitmap @@ -165,7 +165,7 @@ namespace dxcanvas const rendering::IntegerBitmapLayout& /*bitmapLayout*/, const geometry::IntegerPoint2D& pos ) { - const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); + const geometry::IntegerSize2D aSize( maSize.getWidth(),maSize.getHeight() ); ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, "CanvasHelper::setPixel: X coordinate out of bounds" ); @@ -177,14 +177,14 @@ namespace dxcanvas if( Gdiplus::Ok != mpBitmap->SetPixel( pos.X, pos.Y, Gdiplus::Color( tools::sequenceToArgb( color )))) { - throw uno::RuntimeException(); + throw uno::RuntimeException("SetPixel called with invalid x,y points or color"); } } uno::Sequence< sal_Int8 > DXBitmap::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/, const geometry::IntegerPoint2D& pos ) { - const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); + const geometry::IntegerSize2D aSize( maSize.getWidth(),maSize.getHeight() ); ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, "CanvasHelper::getPixel: X coordinate out of bounds" ); diff --git a/canvas/source/directx/dx_bitmap.hxx b/canvas/source/directx/dx_bitmap.hxx index 127ee5fc5b39..b27da5cfa683 100644 --- a/canvas/source/directx/dx_bitmap.hxx +++ b/canvas/source/directx/dx_bitmap.hxx @@ -35,15 +35,13 @@ namespace dxcanvas class DXBitmap : public IBitmap { public: - DXBitmap( const BitmapSharedPtr& rBitmap, - bool bWithAlpha ); - DXBitmap( const ::basegfx::B2IVector& rSize, - bool bWithAlpha ); + DXBitmap( const BitmapSharedPtr& rBitmap, bool bWithAlpha ); + DXBitmap( const ::basegfx::B2ISize& rSize, bool bWithAlpha ); virtual GraphicsSharedPtr getGraphics() override; virtual BitmapSharedPtr getBitmap() const override; - virtual ::basegfx::B2IVector getSize() const override; + virtual ::basegfx::B2ISize getSize() const override; virtual bool hasAlpha() const override; css::uno::Sequence< sal_Int8 > getData( @@ -69,7 +67,7 @@ namespace dxcanvas GDIPlusUserSharedPtr mpGdiPlusUser; // size of this image in pixels [integral unit] - ::basegfx::B2IVector maSize; + ::basegfx::B2ISize maSize; BitmapSharedPtr mpBitmap; GraphicsSharedPtr mpGraphics; diff --git a/canvas/source/directx/dx_bitmapcanvashelper.cxx b/canvas/source/directx/dx_bitmapcanvashelper.cxx index 9733853f5958..f82fa0ac3ad3 100644 --- a/canvas/source/directx/dx_bitmapcanvashelper.cxx +++ b/canvas/source/directx/dx_bitmapcanvashelper.cxx @@ -31,7 +31,7 @@ #include <com/sun/star/rendering/RepaintResult.hpp> #include <com/sun/star/rendering/TexturingMode.hpp> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> @@ -141,7 +141,6 @@ namespace dxcanvas { if( !mpTarget ) return geometry::IntegerSize2D(1, 1); - return basegfx::unotools::integerSize2DFromB2ISize(mpTarget->getSize()); } diff --git a/canvas/source/directx/dx_canvas.cxx b/canvas/source/directx/dx_canvas.cxx index 3d5bda00288b..c19ea1ea9017 100644 --- a/canvas/source/directx/dx_canvas.cxx +++ b/canvas/source/directx/dx_canvas.cxx @@ -36,9 +36,10 @@ #include <com/sun/star/uno/XComponentContext.hpp> #include <cppuhelper/supportsservice.hxx> #include <osl/mutex.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/sysdata.hxx> #include <vcl/skia/SkiaHelper.hxx> +#include <vcl/window.hxx> #include <canvas/canvastools.hxx> @@ -239,8 +240,7 @@ namespace dxcanvas { rtl::Reference<Canvas> xCanvas(new Canvas(args, context)); xCanvas->initialize(); - xCanvas->acquire(); - return static_cast<cppu::OWeakObject*>(xCanvas.get()); + return cppu::acquire(xCanvas.get()); } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* @@ -249,8 +249,7 @@ namespace dxcanvas { rtl::Reference<BitmapCanvas> xCanvas(new BitmapCanvas(args, context)); xCanvas->initialize(); - xCanvas->acquire(); - return static_cast<cppu::OWeakObject*>(xCanvas.get()); + return cppu::acquire(xCanvas.get()); } } diff --git a/canvas/source/directx/dx_canvasbitmap.cxx b/canvas/source/directx/dx_canvasbitmap.cxx index adc4b741a4c3..fb06288ada86 100644 --- a/canvas/source/directx/dx_canvasbitmap.cxx +++ b/canvas/source/directx/dx_canvasbitmap.cxx @@ -22,7 +22,7 @@ #include <memory> #include <cppuhelper/supportsservice.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/bitmapex.hxx> #include <canvas/canvastools.hxx> @@ -97,9 +97,7 @@ namespace dxcanvas HBITMAP aHBmp; mpBitmap->getBitmap()->GetHBITMAP(Gdiplus::Color(), &aHBmp ); - uno::Sequence< uno::Any > args(1); - args[0] <<= reinterpret_cast<sal_Int64>(aHBmp); - + uno::Sequence< uno::Any > args{ uno::Any(reinterpret_cast<sal_Int64>(aHBmp)) }; aRes <<= args; } else @@ -107,18 +105,18 @@ namespace dxcanvas // need to copy&convert the bitmap, since dx // canvas uses inline alpha channel HDC hScreenDC=GetDC(nullptr); - const basegfx::B2IVector aSize(mpBitmap->getSize()); + const basegfx::B2ISize aSize = mpBitmap->getSize(); HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC, - aSize.getX(), - aSize.getY() ); + aSize.getWidth(), + aSize.getHeight() ); if( !hBmpBitmap ) return aRes; BITMAPINFOHEADER aBIH; aBIH.biSize = sizeof( BITMAPINFOHEADER ); - aBIH.biWidth = aSize.getX(); - aBIH.biHeight = -aSize.getY(); + aBIH.biWidth = aSize.getWidth(); + aBIH.biHeight = -aSize.getHeight(); aBIH.biPlanes = 1; aBIH.biBitCount = 32; aBIH.biCompression = BI_RGB; // expects pixel in @@ -131,12 +129,12 @@ namespace dxcanvas aBIH.biClrImportant = 0; Gdiplus::BitmapData aBmpData; - aBmpData.Width = aSize.getX(); - aBmpData.Height = aSize.getY(); + aBmpData.Width = aSize.getWidth(); + aBmpData.Height = aSize.getHeight(); aBmpData.Stride = 4*aBmpData.Width; aBmpData.PixelFormat = PixelFormat32bppARGB; aBmpData.Scan0 = nullptr; - const Gdiplus::Rect aRect( 0,0,aSize.getX(),aSize.getY() ); + const Gdiplus::Rect aRect( 0,0,aSize.getWidth(),aSize.getHeight() ); BitmapSharedPtr pGDIPlusBitmap=mpBitmap->getBitmap(); if( Gdiplus::Ok != pGDIPlusBitmap->LockBits( &aRect, Gdiplus::ImageLockModeRead, @@ -149,13 +147,11 @@ namespace dxcanvas // now aBmpData.Scan0 contains our bits - push // them into HBITMAP, ignoring alpha - SetDIBits( hScreenDC, hBmpBitmap, 0, aSize.getY(), aBmpData.Scan0, reinterpret_cast<PBITMAPINFO>(&aBIH), DIB_RGB_COLORS ); + SetDIBits( hScreenDC, hBmpBitmap, 0, aSize.getHeight(), aBmpData.Scan0, reinterpret_cast<PBITMAPINFO>(&aBIH), DIB_RGB_COLORS ); pGDIPlusBitmap->UnlockBits( &aBmpData ); - uno::Sequence< uno::Any > args(1); - args[0] <<= reinterpret_cast<sal_Int64>(hBmpBitmap); - + uno::Sequence< uno::Any > args{ uno::Any(reinterpret_cast<sal_Int64>(hBmpBitmap)) }; aRes <<= args; } } @@ -174,14 +170,14 @@ namespace dxcanvas // need to copy&convert the bitmap, since dx // canvas uses inline alpha channel HDC hScreenDC=GetDC(nullptr); - const basegfx::B2IVector aSize(mpBitmap->getSize()); - HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC, aSize.getX(), aSize.getY() ); + const basegfx::B2ISize aSize = mpBitmap->getSize(); + HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC, aSize.getWidth(), aSize.getHeight() ); if( !hBmpBitmap ) return aRes; aDIB.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); - aDIB.bmiHeader.biWidth = aSize.getX(); - aDIB.bmiHeader.biHeight = -aSize.getY(); + aDIB.bmiHeader.biWidth = aSize.getWidth(); + aDIB.bmiHeader.biHeight = -aSize.getHeight(); aDIB.bmiHeader.biPlanes = 1; aDIB.bmiHeader.biBitCount = 8; aDIB.bmiHeader.biCompression = BI_RGB; @@ -192,12 +188,12 @@ namespace dxcanvas aDIB.bmiHeader.biClrImportant = 0; Gdiplus::BitmapData aBmpData; - aBmpData.Width = aSize.getX(); - aBmpData.Height = aSize.getY(); + aBmpData.Width = aSize.getWidth(); + aBmpData.Height = aSize.getHeight(); aBmpData.Stride = 4*aBmpData.Width; aBmpData.PixelFormat = PixelFormat32bppARGB; aBmpData.Scan0 = nullptr; - const Gdiplus::Rect aRect( 0,0,aSize.getX(),aSize.getY() ); + const Gdiplus::Rect aRect( 0,0,aSize.getWidth(),aSize.getHeight() ); BitmapSharedPtr pGDIPlusBitmap=mpBitmap->getBitmap(); if( Gdiplus::Ok != pGDIPlusBitmap->LockBits( &aRect, Gdiplus::ImageLockModeRead, @@ -209,16 +205,16 @@ namespace dxcanvas } // copy only alpha channel to pAlphaBits - const sal_Int32 nScanWidth((aSize.getX() + 3) & ~3); - std::unique_ptr<sal_uInt8[]> pAlphaBits( new sal_uInt8[nScanWidth*aSize.getY()] ); + const sal_Int32 nScanWidth((aSize.getWidth() + 3) & ~3); + std::unique_ptr<sal_uInt8[]> pAlphaBits( new sal_uInt8[nScanWidth*aSize.getHeight()] ); const sal_uInt8* pInBits=static_cast<sal_uInt8*>(aBmpData.Scan0); pInBits+=3; - for( sal_Int32 y=0; y<aSize.getY(); ++y ) + for( sal_Int32 y=0; y<aSize.getHeight(); ++y ) { sal_uInt8* pOutBits=pAlphaBits.get()+y*nScanWidth; - for( sal_Int32 x=0; x<aSize.getX(); ++x ) + for( sal_Int32 x=0; x<aSize.getWidth(); ++x ) { - *pOutBits++ = 255-*pInBits; + *pOutBits++ = *pInBits; pInBits += 4; } } @@ -227,12 +223,10 @@ namespace dxcanvas // set bits to newly create HBITMAP SetDIBits( hScreenDC, hBmpBitmap, 0, - aSize.getY(), pAlphaBits.get(), + aSize.getHeight(), pAlphaBits.get(), reinterpret_cast<PBITMAPINFO>(&aDIB), DIB_RGB_COLORS ); - uno::Sequence< uno::Any > args(1); - args[0] <<= reinterpret_cast<sal_Int64>(hBmpBitmap); - + uno::Sequence< uno::Any > args{ uno::Any(reinterpret_cast<sal_Int64>(hBmpBitmap)) }; aRes <<= args; } } diff --git a/canvas/source/directx/dx_canvascustomsprite.cxx b/canvas/source/directx/dx_canvascustomsprite.cxx index a0e58f29d4f9..b9e79fdc0654 100644 --- a/canvas/source/directx/dx_canvascustomsprite.cxx +++ b/canvas/source/directx/dx_canvascustomsprite.cxx @@ -25,7 +25,7 @@ #include <basegfx/point/b2dpoint.hxx> #include <cppuhelper/supportsservice.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> @@ -49,7 +49,7 @@ namespace dxcanvas "CanvasCustomSprite::CanvasCustomSprite(): Invalid sprite canvas" ); mpSurface = std::make_shared<DXSurfaceBitmap>( - ::basegfx::B2IVector( + ::basegfx::B2ISize( ::canvas::tools::roundUp( rSpriteSize.Width ), ::canvas::tools::roundUp( rSpriteSize.Height )), rSurfaceProxy, diff --git a/canvas/source/directx/dx_canvashelper.cxx b/canvas/source/directx/dx_canvashelper.cxx index de4969c6dd48..1184886784c9 100644 --- a/canvas/source/directx/dx_canvashelper.cxx +++ b/canvas/source/directx/dx_canvashelper.cxx @@ -34,7 +34,7 @@ #include <comphelper/sequence.hxx> #include <o3tl/char16_t2wchar_t.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> @@ -51,7 +51,7 @@ namespace dxcanvas { namespace { - Gdiplus::LineCap gdiCapFromCap( sal_Int8 nCapType ) + Gdiplus::LineCap gdiLineCapFromCap( sal_Int8 nCapType ) { switch( nCapType ) { @@ -66,12 +66,35 @@ namespace dxcanvas default: ENSURE_OR_THROW( false, - "gdiCapFromCap(): Unexpected cap type" ); + "gdiLineCapFromCap(): Unexpected cap type" ); } return Gdiplus::LineCapFlat; } + Gdiplus::DashCap gdiDashCapFromCap( sal_Int8 nCapType ) + { + switch( nCapType ) + { + case rendering::PathCapType::BUTT: + return Gdiplus::DashCapFlat; + + case rendering::PathCapType::ROUND: + return Gdiplus::DashCapRound; + + // Gdiplus does not know square, using flat would make short + // dashes disappear, so use triangle as the closest one. + case rendering::PathCapType::SQUARE: + return Gdiplus::DashCapTriangle; + + default: + ENSURE_OR_THROW( false, + "gdiDashCapFromCap(): Unexpected cap type" ); + } + + return Gdiplus::DashCapFlat; + } + Gdiplus::LineJoin gdiJoinFromJoin( sal_Int8 nJoinType ) { switch( nJoinType ) @@ -368,9 +391,9 @@ namespace dxcanvas aPen.SetDashPattern( rDashArray.data(), rDashArray.size() ); } - aPen.SetLineCap( gdiCapFromCap(strokeAttributes.StartCapType), - gdiCapFromCap(strokeAttributes.EndCapType), - Gdiplus::DashCapFlat ); + aPen.SetLineCap( gdiLineCapFromCap(strokeAttributes.StartCapType), + gdiLineCapFromCap(strokeAttributes.EndCapType), + gdiDashCapFromCap(strokeAttributes.StartCapType)); if(!bIsNone) aPen.SetLineJoin( gdiJoinFromJoin(strokeAttributes.JoinType) ); @@ -712,7 +735,7 @@ namespace dxcanvas if( !maOutputOffset.equalZero() ) { const basegfx::B2DHomMatrix aOutputOffset(basegfx::utils::createTranslateB2DHomMatrix( - maOutputOffset.getX(), maOutputOffset.getY())); + maOutputOffset.getWidth(), maOutputOffset.getHeight())); aTransform = aOutputOffset * aTransform; } @@ -751,7 +774,7 @@ namespace dxcanvas if( !maOutputOffset.equalZero() ) { const basegfx::B2DHomMatrix aOutputOffset(basegfx::utils::createTranslateB2DHomMatrix( - maOutputOffset.getX(), maOutputOffset.getY())); + maOutputOffset.getWidth(), maOutputOffset.getHeight())); aTransform = aOutputOffset * aTransform; } diff --git a/canvas/source/directx/dx_canvashelper_texturefill.cxx b/canvas/source/directx/dx_canvashelper_texturefill.cxx index 0bea70fc83a2..c64773539e9d 100644 --- a/canvas/source/directx/dx_canvashelper_texturefill.cxx +++ b/canvas/source/directx/dx_canvashelper_texturefill.cxx @@ -35,7 +35,7 @@ #include <basegfx/utils/tools.hxx> #include <com/sun/star/rendering/TexturingMode.hpp> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <parametricpolypolygon.hxx> diff --git a/canvas/source/directx/dx_config.cxx b/canvas/source/directx/dx_config.cxx index 48609d8c500e..c1d9020845a2 100644 --- a/canvas/source/directx/dx_config.cxx +++ b/canvas/source/directx/dx_config.cxx @@ -26,7 +26,7 @@ #include <comphelper/anytostring.hxx> #include <cppuhelper/exc_hlp.hxx> #include <osl/diagnose.h> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include "dx_config.hxx" @@ -45,9 +45,7 @@ namespace dxcanvas { try { - uno::Sequence< OUString > aName { "DeviceDenylist" }; - - uno::Sequence< uno::Any > aProps( GetProperties( aName )); + uno::Sequence< uno::Any > aProps( GetProperties( { "DeviceDenylist" } )); uno::Sequence< sal_Int32 > aValues; if( aProps.getLength() > 0 && @@ -70,13 +68,11 @@ namespace dxcanvas } } - aName[0] = "DenylistCurrentDevice"; - aProps = GetProperties( aName ); + aProps = GetProperties( { "DenylistCurrentDevice" } ); if( aProps.getLength() > 0 ) aProps[0] >>= mbDenylistCurrentDevice; - aName[0] = "MaxTextureSize"; - aProps = GetProperties( aName ); + aProps = GetProperties( { "MaxTextureSize" } ); if( aProps.getLength() > 0 ) maMaxTextureSize = aProps[0].get<sal_Int32>(); else diff --git a/canvas/source/directx/dx_devicehelper.cxx b/canvas/source/directx/dx_devicehelper.cxx index 1c724bca5513..dada6238e0eb 100644 --- a/canvas/source/directx/dx_devicehelper.cxx +++ b/canvas/source/directx/dx_devicehelper.cxx @@ -23,11 +23,10 @@ #include <basegfx/utils/canvastools.hxx> #include <com/sun/star/lang/NoSupportException.hpp> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/canvastools.hxx> #include <vcl/outdev.hxx> #include <vcl/sysdata.hxx> -#include <vcl/window.hxx> #include <canvas/canvastools.hxx> @@ -189,22 +188,11 @@ namespace dxcanvas return uno::Any(); } - namespace - { - struct DeviceColorSpace: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, - DeviceColorSpace> - { - uno::Reference<rendering::XColorSpace> operator()() - { - return vcl::unotools::createStandardColorSpace(); - } - }; - } - uno::Reference<rendering::XColorSpace> DeviceHelper::getColorSpace() const { // always the same - return DeviceColorSpace::get(); + static uno::Reference<rendering::XColorSpace> theSpace = vcl::unotools::createStandardColorSpace(); + return theSpace; } } diff --git a/canvas/source/directx/dx_ibitmap.hxx b/canvas/source/directx/dx_ibitmap.hxx index 6d3f4d6f6a0d..9669f6767495 100644 --- a/canvas/source/directx/dx_ibitmap.hxx +++ b/canvas/source/directx/dx_ibitmap.hxx @@ -21,6 +21,7 @@ #include <com/sun/star/rendering/XCanvas.hpp> #include <com/sun/star/rendering/XIntegerBitmap.hpp> +#include <basegfx/vector/b2isize.hxx> #include <basegfx/vector/b2ivector.hxx> #include <basegfx/point/b2dpoint.hxx> #include <basegfx/range/b2drange.hxx> @@ -33,7 +34,7 @@ namespace dxcanvas struct IBitmap : public GraphicsProvider { virtual BitmapSharedPtr getBitmap() const = 0; - virtual ::basegfx::B2IVector getSize() const = 0; + virtual ::basegfx::B2ISize getSize() const = 0; virtual bool hasAlpha() const = 0; virtual css::uno::Sequence< sal_Int8 > getData( diff --git a/canvas/source/directx/dx_impltools.cxx b/canvas/source/directx/dx_impltools.cxx index 27b98364bad1..0364ebcbdd52 100644 --- a/canvas/source/directx/dx_impltools.cxx +++ b/canvas/source/directx/dx_impltools.cxx @@ -35,7 +35,7 @@ #include <com/sun/star/geometry/RealPoint2D.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> #include <verifyinput.hxx> @@ -349,14 +349,13 @@ namespace dxcanvas::tools uno::Sequence< sal_Int8 > argbToIntSequence( Gdiplus::ARGB rColor ) { // TODO(F1): handle color space conversions, when defined on canvas/graphicDevice - uno::Sequence< sal_Int8 > aRet(4); - - aRet[0] = static_cast<sal_Int8>((rColor >> 16) & 0xFF); // red - aRet[1] = static_cast<sal_Int8>((rColor >> 8) & 0xFF); // green - aRet[2] = static_cast<sal_Int8>(rColor & 0xFF); // blue - aRet[3] = static_cast<sal_Int8>((rColor >> 24) & 0xFF); // alpha - - return aRet; + return + { + static_cast<sal_Int8>((rColor >> 16) & 0xFF), // red + static_cast<sal_Int8>((rColor >> 8) & 0xFF), // green + static_cast<sal_Int8>(rColor & 0xFF), // blue + static_cast<sal_Int8>((rColor >> 24) & 0xFF) // alpha + }; } Gdiplus::ARGB sequenceToArgb( const uno::Sequence< sal_Int8 >& rColor ) diff --git a/canvas/source/directx/dx_rendermodule.hxx b/canvas/source/directx/dx_rendermodule.hxx index d8ea283b0791..4b13937967a2 100644 --- a/canvas/source/directx/dx_rendermodule.hxx +++ b/canvas/source/directx/dx_rendermodule.hxx @@ -60,9 +60,9 @@ namespace dxcanvas /// Write a snapshot of the screen to disk virtual void screenShot() = 0; - virtual COMReference<surface_type> + virtual sal::systools::COMReference<surface_type> createSystemMemorySurface( - const ::basegfx::B2IVector& rSize ) = 0; + const ::basegfx::B2ISize& rSize) = 0; virtual void disposing() = 0; virtual HWND getHWND() const = 0; diff --git a/canvas/source/directx/dx_spritecanvas.cxx b/canvas/source/directx/dx_spritecanvas.cxx index 24e8ffa1b545..f4fe39203f4b 100644 --- a/canvas/source/directx/dx_spritecanvas.cxx +++ b/canvas/source/directx/dx_spritecanvas.cxx @@ -31,8 +31,7 @@ #include <cppuhelper/supportsservice.hxx> #include <osl/mutex.hxx> #include <toolkit/helper/vclunohelper.hxx> -#include <tools/diagnose_ex.h> -#include <vcl/window.hxx> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> @@ -184,8 +183,7 @@ namespace dxcanvas { rtl::Reference<SpriteCanvas> xCanvas(new SpriteCanvas(args, context)); xCanvas->initialize(); - xCanvas->acquire(); - return static_cast<cppu::OWeakObject*>(xCanvas.get()); + return cppu::acquire(xCanvas.get()); } } diff --git a/canvas/source/directx/dx_spritecanvashelper.cxx b/canvas/source/directx/dx_spritecanvashelper.cxx index 416c66ba5fca..d676fa2a802f 100644 --- a/canvas/source/directx/dx_spritecanvashelper.cxx +++ b/canvas/source/directx/dx_spritecanvashelper.cxx @@ -24,7 +24,7 @@ #include <basegfx/range/b2drectangle.hxx> #include <basegfx/utils/canvastools.hxx> #include <comphelper/scopeguard.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> diff --git a/canvas/source/directx/dx_spritedevicehelper.cxx b/canvas/source/directx/dx_spritedevicehelper.cxx index ee339c8af0ee..622246bc2adc 100644 --- a/canvas/source/directx/dx_spritedevicehelper.cxx +++ b/canvas/source/directx/dx_spritedevicehelper.cxx @@ -27,7 +27,7 @@ #include <canvas/canvastools.hxx> #include <com/sun/star/lang/NoSupportException.hpp> #include <toolkit/helper/vclunohelper.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/sysdata.hxx> #include <vcl/window.hxx> @@ -80,7 +80,7 @@ namespace dxcanvas catch (...) { throw lang::NoSupportException( "Could not create DirectX device!", - static_cast< ::cppu::OWeakObject* >(&rSpriteCanvas) ); + rSpriteCanvas.getXWeak() ); } // create the surfaceproxy manager @@ -88,7 +88,7 @@ namespace dxcanvas // #i60490# ensure backbuffer has sensible minimal size mpBackBuffer = std::make_shared<DXSurfaceBitmap>( - ::basegfx::B2ISize(w,h), + basegfx::B2ISize(w,h), mpSurfaceProxyManager, mpRenderModule, false); diff --git a/canvas/source/directx/dx_spritehelper.cxx b/canvas/source/directx/dx_spritehelper.cxx index 8f436283387c..3cb211886a3c 100644 --- a/canvas/source/directx/dx_spritehelper.cxx +++ b/canvas/source/directx/dx_spritehelper.cxx @@ -29,7 +29,7 @@ #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/utils/canvastools.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <canvas/canvastools.hxx> @@ -67,7 +67,7 @@ namespace dxcanvas // also init base class CanvasCustomSpriteHelper::init( rSpriteSize, - rSpriteCanvas.get() ); + rSpriteCanvas ); } void SpriteHelper::disposing() diff --git a/canvas/source/directx/dx_surfacebitmap.cxx b/canvas/source/directx/dx_surfacebitmap.cxx index e8eb44566c8f..5a3992eea221 100644 --- a/canvas/source/directx/dx_surfacebitmap.cxx +++ b/canvas/source/directx/dx_surfacebitmap.cxx @@ -26,7 +26,7 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/range/b2irange.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <rendering/icolorbuffer.hxx> #include "dx_graphicsprovider.hxx" @@ -47,8 +47,8 @@ namespace dxcanvas struct DXColorBuffer : public canvas::IColorBuffer { public: - DXColorBuffer( const COMReference<surface_type>& rSurface, - const ::basegfx::B2IVector& rSize ) + DXColorBuffer( const sal::systools::COMReference<surface_type>& rSurface, + const ::basegfx::B2ISize& rSize ) : maSize(rSize) , maLockedRect{} , mpSurface(rSurface) @@ -67,9 +67,9 @@ namespace dxcanvas private: - ::basegfx::B2IVector maSize; + ::basegfx::B2ISize maSize; mutable D3DLOCKED_RECT maLockedRect; - mutable COMReference<surface_type> mpSurface; + sal::systools::COMReference<surface_type> mpSurface; }; sal_uInt8* DXColorBuffer::lock() const @@ -86,12 +86,12 @@ namespace dxcanvas sal_uInt32 DXColorBuffer::getWidth() const { - return maSize.getX(); + return maSize.getWidth(); } sal_uInt32 DXColorBuffer::getHeight() const { - return maSize.getY(); + return maSize.getHeight(); } sal_uInt32 DXColorBuffer::getStride() const @@ -113,7 +113,7 @@ namespace dxcanvas public: GDIColorBuffer( const BitmapSharedPtr& rSurface, - const ::basegfx::B2IVector& rSize ) + const ::basegfx::B2ISize& rSize ) : maSize(rSize) , aBmpData{} , mpGDIPlusBitmap(rSurface) @@ -132,15 +132,15 @@ namespace dxcanvas private: - ::basegfx::B2IVector maSize; + ::basegfx::B2ISize maSize; mutable Gdiplus::BitmapData aBmpData; BitmapSharedPtr mpGDIPlusBitmap; }; sal_uInt8* GDIColorBuffer::lock() const { - aBmpData.Width = maSize.getX(); - aBmpData.Height = maSize.getY(); + aBmpData.Width = maSize.getWidth(); + aBmpData.Height = maSize.getHeight(); aBmpData.Stride = 4*aBmpData.Width; aBmpData.PixelFormat = PixelFormat32bppARGB; aBmpData.Scan0 = nullptr; @@ -163,12 +163,12 @@ namespace dxcanvas sal_uInt32 GDIColorBuffer::getWidth() const { - return maSize.getX(); + return maSize.getWidth(); } sal_uInt32 GDIColorBuffer::getHeight() const { - return maSize.getY(); + return maSize.getHeight(); } sal_uInt32 GDIColorBuffer::getStride() const @@ -186,10 +186,10 @@ namespace dxcanvas // DXSurfaceBitmap::DXSurfaceBitmap - DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2IVector& rSize, + DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2ISize& rSize, const std::shared_ptr<canvas::ISurfaceProxyManager>& rMgr, - const IDXRenderModuleSharedPtr& rRenderModule, - bool bWithAlpha ) : + const IDXRenderModuleSharedPtr& rRenderModule, + bool bWithAlpha ) : mpGdiPlusUser( GDIPlusUser::createInstance() ), maSize(rSize), mpRenderModule(rRenderModule), @@ -209,7 +209,7 @@ namespace dxcanvas // DXSurfaceBitmap::getSize - ::basegfx::B2IVector DXSurfaceBitmap::getSize() const + ::basegfx::B2ISize DXSurfaceBitmap::getSize() const { return maSize; } @@ -224,8 +224,8 @@ namespace dxcanvas if(mbAlpha) { mpGDIPlusBitmap = std::make_shared<Gdiplus::Bitmap>( - maSize.getX(), - maSize.getY(), + maSize.getWidth(), + maSize.getHeight(), PixelFormat32bppARGB ); mpGraphics = tools::createGraphicsFromBitmap(mpGDIPlusBitmap); @@ -234,7 +234,7 @@ namespace dxcanvas // wrapper around the directx surface. the colorbuffer is the // interface which is used by the surfaceproxy to support any // kind of underlying structure for the pixel data container. - mpColorBuffer = std::make_shared<GDIColorBuffer>(mpGDIPlusBitmap,maSize); + mpColorBuffer = std::make_shared<GDIColorBuffer>(mpGDIPlusBitmap, maSize); } else { @@ -244,7 +244,7 @@ namespace dxcanvas // wrapper around the directx surface. the colorbuffer is the // interface which is used by the surfaceproxy to support any // kind of underlying structure for the pixel data container. - mpColorBuffer = std::make_shared<DXColorBuffer>(mpSurface,maSize); + mpColorBuffer = std::make_shared<DXColorBuffer>(mpSurface, maSize); } // create a (possibly hardware accelerated) mirror surface. @@ -255,7 +255,7 @@ namespace dxcanvas // DXSurfaceBitmap::resize - bool DXSurfaceBitmap::resize( const ::basegfx::B2IVector& rSize ) + bool DXSurfaceBitmap::resize(const ::basegfx::B2ISize& rSize) { if(maSize != rSize) { @@ -324,7 +324,7 @@ namespace dxcanvas Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB; // construct a gdi+ bitmap from the raw pixel data. - pResult = std::make_shared<Gdiplus::Bitmap>( maSize.getX(),maSize.getY(), + pResult = std::make_shared<Gdiplus::Bitmap>(maSize.getWidth(), maSize.getHeight(), aLockedRect.Pitch, nFormat, static_cast<BYTE *>(aLockedRect.pBits) ); @@ -568,7 +568,7 @@ namespace dxcanvas { if(hasAlpha()) { - const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); + const geometry::IntegerSize2D aSize( maSize.getWidth(), maSize.getHeight() ); ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, "CanvasHelper::setPixel: X coordinate out of bounds" ); @@ -585,9 +585,9 @@ namespace dxcanvas } else { - ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(), + ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getWidth(), "CanvasHelper::setPixel: X coordinate out of bounds" ); - ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(), + ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getHeight(), "CanvasHelper::setPixel: Y coordinate out of bounds" ); ENSURE_ARG_OR_THROW( color.getLength() > 3, "CanvasHelper::setPixel: not enough color components" ); @@ -616,7 +616,7 @@ namespace dxcanvas { if(hasAlpha()) { - const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); + const geometry::IntegerSize2D aSize(maSize.getWidth(), maSize.getHeight()); ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, "CanvasHelper::getPixel: X coordinate out of bounds" ); @@ -632,9 +632,9 @@ namespace dxcanvas } else { - ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(), + ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getWidth(), "CanvasHelper::getPixel: X coordinate out of bounds" ); - ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(), + ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getHeight(), "CanvasHelper::getPixel: Y coordinate out of bounds" ); // lock the directx surface to receive the pointer to the surface memory. diff --git a/canvas/source/directx/dx_surfacebitmap.hxx b/canvas/source/directx/dx_surfacebitmap.hxx index 323a3b7f1737..f39ebb5b9727 100644 --- a/canvas/source/directx/dx_surfacebitmap.hxx +++ b/canvas/source/directx/dx_surfacebitmap.hxx @@ -31,21 +31,21 @@ namespace dxcanvas class DXSurfaceBitmap : public IBitmap { public: - DXSurfaceBitmap( const ::basegfx::B2IVector& rSize, + DXSurfaceBitmap( const ::basegfx::B2ISize& rSize, const std::shared_ptr<canvas::ISurfaceProxyManager>& rMgr, const IDXRenderModuleSharedPtr& rRenderModule, bool bWithAlpha ); - bool resize( const ::basegfx::B2IVector& rSize ); + bool resize(const ::basegfx::B2ISize& rSize); void clear(); virtual GraphicsSharedPtr getGraphics() override; virtual BitmapSharedPtr getBitmap() const override; - virtual ::basegfx::B2IVector getSize() const override; + virtual ::basegfx::B2ISize getSize() const override; virtual bool hasAlpha() const override; - COMReference<surface_type> getSurface() const { return mpSurface; } + sal::systools::COMReference<surface_type> getSurface() const { return mpSurface; } bool draw( double fAlpha, const ::basegfx::B2DPoint& rPos, @@ -88,7 +88,7 @@ namespace dxcanvas GDIPlusUserSharedPtr mpGdiPlusUser; // size of this image in pixels [integral unit] - ::basegfx::B2IVector maSize; + ::basegfx::B2ISize maSize; // pointer to the rendermodule, needed to create surfaces // which are used as container for the actual pixel data. @@ -107,7 +107,7 @@ namespace dxcanvas // container for pixel data, we need to use a directx // surface since GDI+ sucks... - COMReference<surface_type> mpSurface; + sal::systools::COMReference<surface_type> mpSurface; // since GDI+ does not work correctly in case we // run on a 16bit display [don't ask me why] we need diff --git a/canvas/source/directx/dx_surfacegraphics.cxx b/canvas/source/directx/dx_surfacegraphics.cxx index a496b41017dd..075f2fc15341 100644 --- a/canvas/source/directx/dx_surfacegraphics.cxx +++ b/canvas/source/directx/dx_surfacegraphics.cxx @@ -30,10 +30,10 @@ namespace dxcanvas { struct GraphicsDeleter { - COMReference<surface_type> mpSurface; + sal::systools::COMReference<surface_type> mpSurface; HDC maHDC; - GraphicsDeleter(const COMReference<surface_type>& rSurface, HDC hdc) : + GraphicsDeleter(const sal::systools::COMReference<surface_type>& rSurface, HDC hdc) : mpSurface(rSurface), maHDC(hdc) {} @@ -52,7 +52,7 @@ namespace dxcanvas }; } - GraphicsSharedPtr createSurfaceGraphics(const COMReference<surface_type>& rSurface ) + GraphicsSharedPtr createSurfaceGraphics(const sal::systools::COMReference<surface_type>& rSurface ) { GraphicsSharedPtr pRet; HDC aHDC; diff --git a/canvas/source/directx/dx_surfacegraphics.hxx b/canvas/source/directx/dx_surfacegraphics.hxx index 5f4e1a742ac5..4260383e2ed8 100644 --- a/canvas/source/directx/dx_surfacegraphics.hxx +++ b/canvas/source/directx/dx_surfacegraphics.hxx @@ -30,7 +30,7 @@ namespace dxcanvas GraphicsSharedPtr returned has a deleter that does all the necessary DX cleanup work). */ -GraphicsSharedPtr createSurfaceGraphics(const COMReference<surface_type>& rSurface); +GraphicsSharedPtr createSurfaceGraphics(const sal::systools::COMReference<surface_type>& rSurface); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/directx/dx_textlayout.cxx b/canvas/source/directx/dx_textlayout.cxx index 5e69f70df624..e64dde596693 100644 --- a/canvas/source/directx/dx_textlayout.cxx +++ b/canvas/source/directx/dx_textlayout.cxx @@ -93,6 +93,26 @@ namespace dxcanvas maLogicalAdvancements = aAdvancements; } + uno::Sequence< sal_Bool > SAL_CALL TextLayout::queryKashidaPositions( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + return maKashidaPositions; + } + + void SAL_CALL TextLayout::applyKashidaPositions( const uno::Sequence< sal_Bool >& aPositions ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if( aPositions.hasElements() && aPositions.getLength() != maText.Length ) + { + SAL_WARN("canvas.directx", "TextLayout::applyKashidaPositions(): mismatching number of positions" ); + throw lang::IllegalArgumentException("mismatching number of positions", getXWeak(), 1); + } + + maKashidaPositions = aPositions; + } + geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds( ) { ::osl::MutexGuard aGuard( m_aMutex ); @@ -105,7 +125,7 @@ namespace dxcanvas aDrawHelper.queryTextBounds( maText, maLogicalAdvancements, - mpFont.get(), + mpFont, mpFont->getFontMatrix())); return aBounds; @@ -176,7 +196,7 @@ namespace dxcanvas { ::osl::MutexGuard aGuard( m_aMutex ); - return mpFont.get(); + return mpFont; } rendering::StringContext SAL_CALL TextLayout::getText( ) @@ -205,7 +225,8 @@ namespace dxcanvas rOutputOffset, maText, maLogicalAdvancements, - mpFont.get(), + maKashidaPositions, + mpFont, mpFont->getFontMatrix(), bAlphaSurface, mnTextDirection != 0); diff --git a/canvas/source/directx/dx_textlayout.hxx b/canvas/source/directx/dx_textlayout.hxx index 24d37e2107a4..f0ae523e7b6a 100644 --- a/canvas/source/directx/dx_textlayout.hxx +++ b/canvas/source/directx/dx_textlayout.hxx @@ -61,6 +61,8 @@ namespace dxcanvas virtual css::uno::Sequence< css::geometry::RealRectangle2D > SAL_CALL queryMeasures( ) override; virtual css::uno::Sequence< double > SAL_CALL queryLogicalAdvancements( ) override; virtual void SAL_CALL applyLogicalAdvancements( const css::uno::Sequence< double >& aAdvancements ) override; + virtual css::uno::Sequence< sal_Bool > SAL_CALL queryKashidaPositions( ) override; + virtual void SAL_CALL applyKashidaPositions( const css::uno::Sequence< sal_Bool >& aPositions ) override; virtual css::geometry::RealRectangle2D SAL_CALL queryTextBounds( ) override; virtual double SAL_CALL justify( double nSize ) override; virtual double SAL_CALL combinedJustify( const css::uno::Sequence< css::uno::Reference< css::rendering::XTextLayout > >& aNextLayouts, double nSize ) override; @@ -95,6 +97,7 @@ namespace dxcanvas css::rendering::StringContext maText; css::uno::Sequence< double > maLogicalAdvancements; + css::uno::Sequence< sal_Bool > maKashidaPositions; CanvasFont::ImplRef mpFont; sal_Int8 mnTextDirection; }; diff --git a/canvas/source/directx/dx_textlayout_drawhelper.cxx b/canvas/source/directx/dx_textlayout_drawhelper.cxx index 1ffeb612de3d..efdf8bf03cfb 100644 --- a/canvas/source/directx/dx_textlayout_drawhelper.cxx +++ b/canvas/source/directx/dx_textlayout_drawhelper.cxx @@ -21,6 +21,7 @@ #include <memory> +#include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/utils/canvastools.hxx> #include <com/sun/star/rendering/FontRequest.hpp> @@ -30,9 +31,10 @@ #include <i18nlangtag/languagetag.hxx> #include <rtl/math.hxx> #include <tools/color.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <tools/poly.hxx> #include <vcl/canvastools.hxx> +#include <vcl/kernarray.hxx> #include <vcl/metric.hxx> #include <vcl/sysdata.hxx> #include <vcl/virdev.hxx> @@ -66,6 +68,7 @@ namespace dxcanvas const ::basegfx::B2ISize& rOutputOffset, const css::rendering::StringContext& rText, const css::uno::Sequence< double >& rLogicalAdvancements, + const css::uno::Sequence< sal_Bool >& rKashidaPositions, const css::uno::Reference< css::rendering::XCanvasFont >& rCanvasFont, const css::geometry::Matrix2D& rFontMatrix, @@ -81,7 +84,7 @@ namespace dxcanvas SystemGraphicsData aSystemGraphicsData; aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); aSystemGraphicsData.hDC = reinterpret_cast< ::HDC >(hdc); - ScopedVclPtrInstance<VirtualDevice> xVirtualDevice(aSystemGraphicsData, Size(1, 1), DeviceFormat::DEFAULT); + ScopedVclPtrInstance<VirtualDevice> xVirtualDevice(aSystemGraphicsData, Size(1, 1), DeviceFormat::WITHOUT_ALPHA); // disable font antialiasing - GDI does not handle alpha // surfaces properly. @@ -109,7 +112,7 @@ namespace dxcanvas vcl::Font aFont( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + Size( 0, ::basegfx::fround<::tools::Long>(rFontRequest.CellSize))); aFont.SetAlignment( ALIGN_BASELINE ); aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==css::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); @@ -154,7 +157,7 @@ namespace dxcanvas if(!rOutputOffset.equalZero()) { - aWorldTransform.translate(rOutputOffset.getX(), rOutputOffset.getY()); + aWorldTransform.translate(rOutputOffset.getWidth(), rOutputOffset.getHeight()); } // set ViewState clipping @@ -166,7 +169,7 @@ namespace dxcanvas if(!rOutputOffset.equalZero()) { - aMatrix.translate(rOutputOffset.getX(), rOutputOffset.getY()); + aMatrix.translate(rOutputOffset.getWidth(), rOutputOffset.getHeight()); } aClipPoly.transform(aMatrix); @@ -206,14 +209,18 @@ namespace dxcanvas { // create the DXArray const sal_Int32 nLen( rLogicalAdvancements.getLength() ); - std::unique_ptr<::tools::Long[]> pDXArray( new ::tools::Long[nLen] ); + KernArray DXArray; + DXArray.reserve(nLen); for( sal_Int32 i=0; i<nLen; ++i ) - pDXArray[i] = basegfx::fround( rLogicalAdvancements[i] ); + DXArray.push_back(basegfx::fround(rLogicalAdvancements[i])); + + std::span<const sal_Bool> aKashidaArray(rKashidaPositions.getConstArray(), rKashidaPositions.getLength()); // draw the String xVirtualDevice->DrawTextArray( aEmptyPoint, aText, - pDXArray.get(), + DXArray, + aKashidaArray, rText.StartPosition, rText.Length, bIsRTL ? SalLayoutFlags::BiDiRtl : SalLayoutFlags::NONE); @@ -242,14 +249,14 @@ namespace dxcanvas SystemGraphicsData aSystemGraphicsData; aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); aSystemGraphicsData.hDC = reinterpret_cast< ::HDC >(GetDC( nullptr )); - ScopedVclPtrInstance<VirtualDevice> xVirtualDevice(aSystemGraphicsData, Size(1, 1), DeviceFormat::DEFAULT); + ScopedVclPtrInstance<VirtualDevice> xVirtualDevice(aSystemGraphicsData, Size(1, 1), DeviceFormat::WITHOUT_ALPHA); // create the font const css::rendering::FontRequest& rFontRequest = rCanvasFont->getFontRequest(); vcl::Font aFont( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + Size( 0, ::basegfx::fround<::tools::Long>(rFontRequest.CellSize))); aFont.SetAlignment( ALIGN_BASELINE ); aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==css::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); diff --git a/canvas/source/directx/dx_textlayout_drawhelper.hxx b/canvas/source/directx/dx_textlayout_drawhelper.hxx index d5820451fb53..8e9383a8aee9 100644 --- a/canvas/source/directx/dx_textlayout_drawhelper.hxx +++ b/canvas/source/directx/dx_textlayout_drawhelper.hxx @@ -26,8 +26,9 @@ #include <com/sun/star/rendering/XCanvasFont.hpp> #include <com/sun/star/geometry/Matrix2D.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> +#include <com/sun/star/rendering/ViewState.hpp> +#include <com/sun/star/rendering/RenderState.hpp> -#include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/vector/b2isize.hxx> namespace com::sun::star::rendering { class XCanvasFont; } @@ -51,6 +52,7 @@ namespace dxcanvas const ::basegfx::B2ISize& rOutputOffset, const css::rendering::StringContext& rText, const css::uno::Sequence< double >& rLogicalAdvancements, + const css::uno::Sequence< sal_Bool >& rKashidaPositions, const css::uno::Reference< css::rendering::XCanvasFont >& rCanvasFont, const css::geometry::Matrix2D& rFontMatrix, diff --git a/canvas/source/directx/dx_vcltools.cxx b/canvas/source/directx/dx_vcltools.cxx index 968b15b1dca3..31b05be58e9c 100644 --- a/canvas/source/directx/dx_vcltools.cxx +++ b/canvas/source/directx/dx_vcltools.cxx @@ -22,7 +22,7 @@ #include <basegfx/numeric/ftools.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/rendering/XIntegerBitmap.hpp> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/bitmap.hxx> #include <vcl/bitmapex.hxx> #include <vcl/BitmapReadAccess.hxx> @@ -66,7 +66,6 @@ namespace dxcanvas::tools const void* hDIB ) { bool bRet( false ); - BitmapSharedPtr pBitmap; const BITMAPINFO* pBI = static_cast<BITMAPINFO*>(GlobalLock( const_cast<void *>(hDIB) )); @@ -101,7 +100,7 @@ namespace dxcanvas::tools { // first of all, ensure that Bitmap contains a DIB, by // acquiring a read access - BitmapReadAccess* pReadAcc = rBmp.AcquireReadAccess(); + BitmapScopedReadAccess pReadAcc(rBmp); // TODO(P2): Acquiring a read access can actually // force a read from VRAM, thus, avoiding this @@ -117,8 +116,6 @@ namespace dxcanvas::tools return drawDIBits( rGraphics, aBmpSysData.pDIB ); } - - Bitmap::ReleaseAccess( pReadAcc ); } } else @@ -131,7 +128,7 @@ namespace dxcanvas::tools return false; } - /** Create a chunk of raw RGBA data GDI+ Bitmap from VCL BbitmapEX + /** Create a chunk of raw RGBA data GDI+ Bitmap from VCL BitmapEx */ RawRGBABitmap bitmapFromVCLBitmapEx( const ::BitmapEx& rBmpEx ) { @@ -141,9 +138,9 @@ namespace dxcanvas::tools // make the local bitmap copy unique, effectively // duplicating the memory used) - ENSURE_OR_THROW( rBmpEx.IsTransparent(), + ENSURE_OR_THROW( rBmpEx.IsAlpha(), "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " - "BmpEx not transparent" ); + "BmpEx has no alpha" ); // convert transparent bitmap to 32bit RGBA // ======================================== @@ -157,7 +154,7 @@ namespace dxcanvas::tools Bitmap aBitmap( rBmpEx.GetBitmap() ); - Bitmap::ScopedReadAccess pReadAccess( aBitmap ); + BitmapScopedReadAccess pReadAccess( aBitmap ); const sal_Int32 nWidth( aBmpSize.Width() ); const sal_Int32 nHeight( aBmpSize.Height() ); @@ -166,44 +163,41 @@ namespace dxcanvas::tools "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " "Unable to acquire read access to bitmap" ); - if( rBmpEx.IsAlpha() || rBmpEx.GetMask().GetBitCount() == 8 ) - { - Bitmap aAlpha( rBmpEx.IsAlpha() ? rBmpEx.GetAlpha().GetBitmap() : rBmpEx.GetMask()); + Bitmap aAlpha( rBmpEx.GetAlphaMask().GetBitmap() ); - Bitmap::ScopedReadAccess pAlphaReadAccess( aAlpha ); + BitmapScopedReadAccess pAlphaReadAccess( aAlpha ); - // By convention, the access buffer always has - // one of the following formats: + // By convention, the access buffer always has + // one of the following formats: - // ScanlineFormat::N1BitMsbPal - // ScanlineFormat::N4BitMsnPal - // ScanlineFormat::N8BitPal - // ScanlineFormat::N24BitTcBgr - // ScanlineFormat::N32BitTcMask + // ScanlineFormat::N1BitMsbPal + // ScanlineFormat::N8BitPal + // ScanlineFormat::N24BitTcBgr + // ScanlineFormat::N32BitTcMask - // and is always ScanlineFormat::BottomUp + // and is always ScanlineFormat::BottomUp - // This is the way - // WinSalBitmap::AcquireBuffer() sets up the - // buffer + // This is the way + // WinSalBitmap::AcquireBuffer() sets up the + // buffer - ENSURE_OR_THROW( pAlphaReadAccess.get() != nullptr, - "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " - "Unable to acquire read access to alpha" ); + ENSURE_OR_THROW( pAlphaReadAccess.get() != nullptr, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unable to acquire read access to alpha" ); - ENSURE_OR_THROW( pAlphaReadAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal, - "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " - "Unsupported alpha scanline format" ); + ENSURE_OR_THROW( pAlphaReadAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unsupported alpha scanline format" ); - BitmapColor aCol; - sal_uInt8* pCurrOutput(aBmpData.maBitmapData.data()); - int x, y; + BitmapColor aCol; + sal_uInt8* pCurrOutput(aBmpData.maBitmapData.data()); + int x, y; - for( y=0; y<nHeight; ++y ) + for( y=0; y<nHeight; ++y ) + { + switch( pReadAccess->GetScanlineFormat() ) { - switch( pReadAccess->GetScanlineFormat() ) - { - case ScanlineFormat::N8BitPal: + case ScanlineFormat::N8BitPal: { Scanline pScan = pReadAccess->GetScanline( y ); Scanline pAScan = pAlphaReadAccess->GetScanline( y ); @@ -215,16 +209,12 @@ namespace dxcanvas::tools *pCurrOutput++ = aCol.GetBlue(); *pCurrOutput++ = aCol.GetGreen(); *pCurrOutput++ = aCol.GetRed(); - - // out notion of alpha is - // different from the rest - // of the world's - *pCurrOutput++ = 255 - static_cast<BYTE>(*pAScan++); + *pCurrOutput++ = static_cast<BYTE>(*pAScan++); } } break; - case ScanlineFormat::N24BitTcBgr: + case ScanlineFormat::N24BitTcBgr: { Scanline pScan = pReadAccess->GetScanline( y ); Scanline pAScan = pAlphaReadAccess->GetScanline( y ); @@ -235,11 +225,7 @@ namespace dxcanvas::tools *pCurrOutput++ = *pScan++; *pCurrOutput++ = *pScan++; *pCurrOutput++ = *pScan++; - - // out notion of alpha is - // different from the rest - // of the world's - *pCurrOutput++ = 255 - static_cast<BYTE>(*pAScan++); + *pCurrOutput++ = static_cast<BYTE>(*pAScan++); } } break; @@ -247,9 +233,8 @@ namespace dxcanvas::tools // TODO(P2): Might be advantageous // to hand-formulate the following // formats, too. - case ScanlineFormat::N1BitMsbPal: - case ScanlineFormat::N4BitMsnPal: - case ScanlineFormat::N32BitTcMask: + case ScanlineFormat::N1BitMsbPal: + case ScanlineFormat::N32BitTcMask: { Scanline pAScan = pAlphaReadAccess->GetScanline( y ); @@ -263,162 +248,21 @@ namespace dxcanvas::tools *pCurrOutput++ = aCol.GetBlue(); *pCurrOutput++ = aCol.GetGreen(); *pCurrOutput++ = aCol.GetRed(); - - // out notion of alpha is - // different from the rest - // of the world's - *pCurrOutput++ = 255 - static_cast<BYTE>(*pAScan++); - } - } - break; - - case ScanlineFormat::N1BitLsbPal: - case ScanlineFormat::N4BitLsnPal: - case ScanlineFormat::N24BitTcRgb: - case ScanlineFormat::N32BitTcAbgr: - case ScanlineFormat::N32BitTcArgb: - case ScanlineFormat::N32BitTcBgra: - case ScanlineFormat::N32BitTcRgba: - default: - ENSURE_OR_THROW( false, - "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " - "Unexpected scanline format - has " - "WinSalBitmap::AcquireBuffer() changed?" ); - } - } - } - else - { - Bitmap aMask( rBmpEx.GetMask() ); - - Bitmap::ScopedReadAccess pMaskReadAccess( aMask ); - - // By convention, the access buffer always has - // one of the following formats: - - // ScanlineFormat::N1BitMsbPal - // ScanlineFormat::N4BitMsnPal - // ScanlineFormat::N8BitPal - // ScanlineFormat::N24BitTcBgr - // ScanlineFormat::N32BitTcMask - - // and is always ScanlineFormat::BottomUp - - // This is the way - // WinSalBitmap::AcquireBuffer() sets up the - // buffer - - ENSURE_OR_THROW( pMaskReadAccess.get() != nullptr, - "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " - "Unable to acquire read access to mask" ); - - ENSURE_OR_THROW( pMaskReadAccess->GetScanlineFormat() == ScanlineFormat::N1BitMsbPal, - "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " - "Unsupported mask scanline format" ); - - BitmapColor aCol; - int nCurrBit; - const int nMask( 1 ); - const int nInitialBit(7); - sal_uInt8* pCurrOutput(aBmpData.maBitmapData.data()); - int x, y; - - // mapping table, to get from mask index color to - // alpha value (which depends on the mask's palette) - sal_uInt8 aColorMap[2]; - - const BitmapColor& rCol0( pMaskReadAccess->GetPaletteColor( 0 ) ); - const BitmapColor& rCol1( pMaskReadAccess->GetPaletteColor( 1 ) ); - - // shortcut for true luminance calculation - // (assumes that palette is grey-level). Note the - // swapped the indices here, to account for the - // fact that VCL's notion of alpha is inverted to - // the rest of the world's. - aColorMap[0] = rCol1.GetRed(); - aColorMap[1] = rCol0.GetRed(); - - for( y=0; y<nHeight; ++y ) - { - switch( pReadAccess->GetScanlineFormat() ) - { - case ScanlineFormat::N8BitPal: - { - Scanline pScan = pReadAccess->GetScanline( y ); - Scanline pMScan = pMaskReadAccess->GetScanline( y ); - - for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x ) - { - aCol = pReadAccess->GetPaletteColor( *pScan++ ); - - *pCurrOutput++ = aCol.GetBlue(); - *pCurrOutput++ = aCol.GetGreen(); - *pCurrOutput++ = aCol.GetRed(); - - *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7) >> 3 ] >> nCurrBit ) & nMask ]; - nCurrBit = ((nCurrBit - 1) % 8) & 7; - } - } - break; - - case ScanlineFormat::N24BitTcBgr: - { - Scanline pScan = pReadAccess->GetScanline( y ); - Scanline pMScan = pMaskReadAccess->GetScanline( y ); - - for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x ) - { - // store as RGBA - *pCurrOutput++ = *pScan++; - *pCurrOutput++ = *pScan++; - *pCurrOutput++ = *pScan++; - - *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7) >> 3 ] >> nCurrBit ) & nMask ]; - nCurrBit = ((nCurrBit - 1) % 8) & 7; - } - } - break; - - // TODO(P2): Might be advantageous - // to hand-formulate the following - // formats, too. - case ScanlineFormat::N1BitMsbPal: - case ScanlineFormat::N4BitMsnPal: - case ScanlineFormat::N32BitTcMask: - { - Scanline pMScan = pMaskReadAccess->GetScanline( y ); - - // using fallback for those - // seldom formats - for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x ) - { - // yes. x and y are swapped on Get/SetPixel - aCol = pReadAccess->GetColor(y,x); - - // store as RGBA - *pCurrOutput++ = aCol.GetBlue(); - *pCurrOutput++ = aCol.GetGreen(); - *pCurrOutput++ = aCol.GetRed(); - - *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7) >> 3 ] >> nCurrBit ) & nMask ]; - nCurrBit = ((nCurrBit - 1) % 8) & 7; + *pCurrOutput++ = static_cast<BYTE>(*pAScan++); } } break; - case ScanlineFormat::N1BitLsbPal: - case ScanlineFormat::N4BitLsnPal: - case ScanlineFormat::N24BitTcRgb: - case ScanlineFormat::N32BitTcAbgr: - case ScanlineFormat::N32BitTcArgb: - case ScanlineFormat::N32BitTcBgra: - case ScanlineFormat::N32BitTcRgba: - default: - ENSURE_OR_THROW( false, - "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " - "Unexpected scanline format - has " - "WinSalBitmap::AcquireBuffer() changed?" ); - } + case ScanlineFormat::N24BitTcRgb: + case ScanlineFormat::N32BitTcAbgr: + case ScanlineFormat::N32BitTcArgb: + case ScanlineFormat::N32BitTcBgra: + case ScanlineFormat::N32BitTcRgba: + default: + ENSURE_OR_THROW( false, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unexpected scanline format - has " + "WinSalBitmap::AcquireBuffer() changed?" ); } } @@ -428,7 +272,7 @@ namespace dxcanvas::tools bool drawVCLBitmapEx( const std::shared_ptr< Gdiplus::Graphics >& rGraphics, const ::BitmapEx& rBmpEx ) { - if( !rBmpEx.IsTransparent() ) + if( !rBmpEx.IsAlpha() ) { Bitmap aBmp( rBmpEx.GetBitmap() ); return drawVCLBitmap( rGraphics, aBmp ); @@ -452,7 +296,7 @@ namespace dxcanvas::tools return false; ::BitmapEx aBmpEx = vcl::unotools::bitmapExFromXBitmap( xIntBmp ); - if( !aBmpEx ) + if( aBmpEx.IsEmpty() ) return false; return drawVCLBitmapEx( rGraphics, aBmpEx ); diff --git a/canvas/source/directx/dx_vcltools.hxx b/canvas/source/directx/dx_vcltools.hxx index a54ec3b90bd3..433afa618eb7 100644 --- a/canvas/source/directx/dx_vcltools.hxx +++ b/canvas/source/directx/dx_vcltools.hxx @@ -20,8 +20,9 @@ #pragma once #include <com/sun/star/uno/Reference.hxx> -#include <com/sun/star/util/TriState.hpp> +#include <com/sun/star/rendering/XBitmap.hpp> #include <memory> +#include <vector> namespace Gdiplus { class Graphics; } diff --git a/canvas/source/directx/dx_winstuff.hxx b/canvas/source/directx/dx_winstuff.hxx index b4c54c780971..4cd0007fa955 100644 --- a/canvas/source/directx/dx_winstuff.hxx +++ b/canvas/source/directx/dx_winstuff.hxx @@ -24,8 +24,6 @@ #include <basegfx/numeric/ftools.hxx> - -#define WIN32_LEAN_AND_MEAN #include <prewin.h> // Enabling Direct3D Debug Information Further more, with registry key @@ -62,89 +60,11 @@ namespace dxcanvas typedef std::shared_ptr< Gdiplus::Bitmap > BitmapSharedPtr; typedef std::shared_ptr< Gdiplus::Font > FontSharedPtr; typedef std::shared_ptr< Gdiplus::TextureBrush > TextureBrushSharedPtr; - - /** COM object RAII wrapper - - This template wraps a Windows COM object, transparently - handling lifetime issues the C++ way (i.e. releasing the - reference when the object is destroyed) - */ - template< typename T > class COMReference - { - public: - typedef T Wrappee; - - COMReference() : - mp( nullptr ) - { - } - - /** Create from raw pointer - - @attention This constructor assumes the interface is - already acquired (unless p is NULL), no additional AddRef - is called here. - - This caters e.g. for all DirectX factory methods, which - return the created interfaces pre-acquired, into a raw - pointer. Simply pass the pointer to this class, but don't - call Release manually on it! - - @example IDirectDrawSurface* pSurface; - pDD->CreateSurface(&aSurfaceDesc, &pSurface, NULL); - mpSurface = COMReference< IDirectDrawSurface >(pSurface); - - */ - explicit COMReference( T* p ) : - mp( p ) - { - } - - COMReference( const COMReference& rNew ) : - mp( nullptr ) - { - if( rNew.mp == nullptr ) - return; - - rNew.mp->AddRef(); // do that _before_ assigning the - // pointer. Just in case... - mp = rNew.mp; - } - - COMReference& operator=( const COMReference& rRHS ) - { - COMReference aTmp(rRHS); - std::swap( mp, aTmp.mp ); - - return *this; - } - - ~COMReference() - { - reset(); - } - - int reset() - { - int refcount = 0; - if( mp ) - refcount = mp->Release(); - - mp = nullptr; - return refcount; - } - - bool is() const { return mp != nullptr; } - T* get() const { return mp; } - T* operator->() const { return mp; } - T& operator*() const { return *mp; } - - private: - T* mp; - }; - } +#include <systools/win32/comtools.hxx> // for COMReference; must be inside prewin...postwin +// Attention! All DirectX factory methods return the created interfaces pre-acquired, into a raw +// pointer. Do not call AddRef on them when constructing COMReference! #include <postwin.h> diff --git a/canvas/source/factory/cf_service.cxx b/canvas/source/factory/cf_service.cxx index 4e31197de2be..94f7069e267a 100644 --- a/canvas/source/factory/cf_service.cxx +++ b/canvas/source/factory/cf_service.cxx @@ -21,6 +21,7 @@ #include <sal/log.hxx> #include <algorithm> +#include <mutex> #include <utility> #include <vector> @@ -34,11 +35,10 @@ #include <comphelper/propertysequence.hxx> #include <cppuhelper/implbase.hxx> #include <cppuhelper/supportsservice.hxx> -#include <osl/mutex.hxx> #include <o3tl/functional.hxx> -#include <config_features.h> +#include <o3tl/string_view.hxx> #include <vcl/skia/SkiaHelper.hxx> -#include <unotools/configmgr.hxx> +#include <comphelper/configuration.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -58,7 +58,7 @@ class CanvasFactory typedef std::vector< CachePair > CacheVector; - mutable ::osl::Mutex m_mutex; + mutable std::mutex m_mutex; Reference<XComponentContext> m_xContext; Reference<container::XNameAccess> m_xCanvasConfigNameAccess; AvailVector m_aAvailableImplementations; @@ -108,18 +108,12 @@ public: }; CanvasFactory::CanvasFactory( Reference<XComponentContext> const & xContext ) : - m_mutex(), m_xContext(xContext), - m_xCanvasConfigNameAccess(), - m_aAvailableImplementations(), - m_aAcceleratedImplementations(), - m_aAAImplementations(), - m_aCachedImplementations(), m_bCacheHasForcedLastImpl(), m_bCacheHasUseAcceleratedEntry(), m_bCacheHasUseAAEntry() { - if (!utl::ConfigManager::IsFuzzing()) + if (!comphelper::IsFuzzing()) { try { @@ -191,13 +185,11 @@ CanvasFactory::CanvasFactory( Reference<XComponentContext> const & xContext ) : { // Ugh. Looks like configuration is borked. Fake minimal // setup. - Sequence<OUString> aServices { "com.sun.star.comp.rendering.Canvas.VCL" }; m_aAvailableImplementations.emplace_back(OUString("com.sun.star.rendering.Canvas"), - aServices ); + Sequence<OUString>{ "com.sun.star.comp.rendering.Canvas.VCL" } ); - aServices[0] = "com.sun.star.comp.rendering.SpriteCanvas.VCL"; m_aAvailableImplementations.emplace_back(OUString("com.sun.star.rendering.SpriteCanvas"), - aServices ); + Sequence<OUString>{ "com.sun.star.comp.rendering.SpriteCanvas.VCL" } ); } } @@ -288,7 +280,7 @@ Reference<XInterface> CanvasFactory::lookupAndUse( OUString const & serviceName, Sequence<Any> const & args, Reference<XComponentContext> const & xContext ) const { - ::osl::MutexGuard guard(m_mutex); + std::scoped_lock guard(m_mutex); // forcing last entry from impl list, if config flag set bool bForceLastEntry(false); @@ -381,7 +373,7 @@ Reference<XInterface> CanvasFactory::lookupAndUse( const bool bIsAcceleratedImpl( std::any_of(aAccelImpls.begin(), aAccelImpls.end(), [&aCurrName](OUString const& src) - { return aCurrName == src.trim(); } + { return aCurrName == o3tl::trim(src); } )); // check whether given canvas service is listed in the @@ -389,7 +381,7 @@ Reference<XInterface> CanvasFactory::lookupAndUse( const bool bIsAAImpl( std::any_of(aAAImpls.begin(), aAAImpls.end(), [&aCurrName](OUString const& src) - { return aCurrName == src.trim(); } + { return aCurrName == o3tl::trim(src); } )); // try to instantiate canvas *only* if either accel and AA diff --git a/canvas/source/opengl/ogl_canvasbitmap.cxx b/canvas/source/opengl/ogl_canvasbitmap.cxx index 2a476ec91e58..0020cc39a9cd 100644 --- a/canvas/source/opengl/ogl_canvasbitmap.cxx +++ b/canvas/source/opengl/ogl_canvasbitmap.cxx @@ -9,7 +9,9 @@ #include <sal/config.h> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> + +#include <utility> #include "ogl_canvasbitmap.hxx" @@ -19,9 +21,9 @@ using namespace ::com::sun::star; namespace oglcanvas { CanvasBitmap::CanvasBitmap( const geometry::IntegerSize2D& rSize, - const SpriteCanvasRef& rDevice, + SpriteCanvasRef rDevice, SpriteDeviceHelper& rDeviceHelper ) : - mpDevice( rDevice ) + mpDevice(std::move( rDevice )) { ENSURE_OR_THROW( mpDevice.is(), "CanvasBitmap::CanvasBitmap(): Invalid surface or device" ); diff --git a/canvas/source/opengl/ogl_canvasbitmap.hxx b/canvas/source/opengl/ogl_canvasbitmap.hxx index 55564c66d018..5cc41bb192bc 100644 --- a/canvas/source/opengl/ogl_canvasbitmap.hxx +++ b/canvas/source/opengl/ogl_canvasbitmap.hxx @@ -46,9 +46,9 @@ namespace oglcanvas @param rDevice Reference device, with which bitmap should be compatible */ - CanvasBitmap( const css::geometry::IntegerSize2D& rSize, - const SpriteCanvasRef& rDevice, - SpriteDeviceHelper& rDeviceHelper ); + CanvasBitmap( const css::geometry::IntegerSize2D& rSize, + SpriteCanvasRef rDevice, + SpriteDeviceHelper& rDeviceHelper ); /** Create verbatim copy (including all recorded actions) */ diff --git a/canvas/source/opengl/ogl_canvascustomsprite.cxx b/canvas/source/opengl/ogl_canvascustomsprite.cxx index 2e930611f5bf..0c03b4491037 100644 --- a/canvas/source/opengl/ogl_canvascustomsprite.cxx +++ b/canvas/source/opengl/ogl_canvascustomsprite.cxx @@ -13,11 +13,13 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/polygon/b2dpolygontriangulator.hxx> #include <basegfx/utils/canvastools.hxx> #include <canvas/canvastools.hxx> +#include <o3tl/safeint.hxx> #include <verifyinput.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include "ogl_canvascustomsprite.hxx" #include "ogl_canvastools.hxx" @@ -32,9 +34,6 @@ namespace oglcanvas SpriteDeviceHelper& rDeviceHelper ) : mpSpriteCanvas( rRefDevice ), maSize(rSpriteSize), - mxClip(), - maTransformation(), - maPosition(), mfAlpha(0.0), mfPriority(0.0) { @@ -70,7 +69,7 @@ namespace oglcanvas { canvas::tools::verifyArgs(aNewPos, viewState, renderState, __func__, - static_cast< ::cppu::OWeakObject* >(this)); + getXWeak()); ::osl::MutexGuard aGuard( m_aMutex ); ::basegfx::B2DHomMatrix aTransform; @@ -194,9 +193,9 @@ namespace oglcanvas ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(mxClip))); glBegin(GL_TRIANGLES); - for( size_t i=0; i<rTriangulatedPolygon.size(); i++ ) + for(const auto& i : rTriangulatedPolygon) { - const::basegfx::triangulator::B2DTriangle& rCandidate(rTriangulatedPolygon[i]); + const::basegfx::triangulator::B2DTriangle& rCandidate(i); glTexCoord2f( rCandidate.getA().getX()/fWidth, rCandidate.getA().getY()/fHeight); @@ -217,7 +216,7 @@ namespace oglcanvas glVertex2d( rCandidate.getC().getX(), rCandidate.getC().getY()); - } + } glEnd(); } else @@ -248,10 +247,7 @@ namespace oglcanvas glVertex2d(maSize.Width+4,maSize.Height+4); glEnd(); - std::vector<double> aVec; - aVec.push_back(mfAlpha); - aVec.push_back(mfPriority); - aVec.push_back(maCanvasHelper.getRecordedActionCount()); + std::vector<double> aVec { mfAlpha, mfPriority, o3tl::narrowing<double>(maCanvasHelper.getRecordedActionCount()) }; renderOSD( aVec, 10 ); return true; diff --git a/canvas/source/opengl/ogl_canvasfont.cxx b/canvas/source/opengl/ogl_canvasfont.cxx index 764b848cfa83..43a9d860b5ca 100644 --- a/canvas/source/opengl/ogl_canvasfont.cxx +++ b/canvas/source/opengl/ogl_canvasfont.cxx @@ -11,6 +11,7 @@ #include <com/sun/star/rendering/FontMetrics.hpp> #include <canvas/canvastools.hxx> +#include <utility> #include "ogl_canvasfont.hxx" #include "ogl_textlayout.hxx" @@ -19,11 +20,10 @@ using namespace ::com::sun::star; namespace oglcanvas { - CanvasFont::CanvasFont( const rendering::FontRequest& rFontRequest, + CanvasFont::CanvasFont( rendering::FontRequest aFontRequest, const uno::Sequence< beans::PropertyValue >& extraFontProperties, const geometry::Matrix2D& fontMatrix ) : - CanvasFontBaseT( m_aMutex ), - maFontRequest( rFontRequest ), + maFontRequest(std::move( aFontRequest )), mnEmphasisMark(0), maFontMatrix( fontMatrix ) { @@ -34,7 +34,7 @@ namespace oglcanvas sal_Int8 nDirection, sal_Int64 nRandomSeed ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return new TextLayout( aText, nDirection, nRandomSeed, ImplRef( this ) ); } @@ -53,8 +53,6 @@ namespace oglcanvas rendering::FontRequest SAL_CALL CanvasFont::getFontRequest( ) { - ::osl::MutexGuard aGuard( m_aMutex ); - return maFontRequest; } diff --git a/canvas/source/opengl/ogl_canvasfont.hxx b/canvas/source/opengl/ogl_canvasfont.hxx index 75eda6b0fb31..92e9d337b7a2 100644 --- a/canvas/source/opengl/ogl_canvasfont.hxx +++ b/canvas/source/opengl/ogl_canvasfont.hxx @@ -9,8 +9,7 @@ #pragma once -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> +#include <comphelper/compbase.hxx> #include <com/sun/star/rendering/XCanvasFont.hpp> #include <com/sun/star/geometry/Matrix2D.hpp> @@ -24,10 +23,9 @@ namespace oglcanvas { class SpriteCanvas; - typedef ::cppu::WeakComponentImplHelper< css::rendering::XCanvasFont > CanvasFontBaseT; + typedef ::comphelper::WeakComponentImplHelper< css::rendering::XCanvasFont > CanvasFontBaseT; - class CanvasFont : public ::cppu::BaseMutex, - public CanvasFontBaseT + class CanvasFont : public CanvasFontBaseT { public: typedef rtl::Reference<CanvasFont> ImplRef; @@ -36,9 +34,9 @@ namespace oglcanvas CanvasFont(const CanvasFont&) = delete; const CanvasFont& operator=(const CanvasFont&) = delete; - CanvasFont( const css::rendering::FontRequest& fontRequest, + CanvasFont( css::rendering::FontRequest fontRequest, const css::uno::Sequence< css::beans::PropertyValue >& extraFontProperties, - const css::geometry::Matrix2D& fontMatrix ); + const css::geometry::Matrix2D& fontMatrix ); // XCanvasFont virtual css::uno::Reference< css::rendering::XTextLayout > SAL_CALL createTextLayout( const css::rendering::StringContext& aText, sal_Int8 nDirection, sal_Int64 nRandomSeed ) override; diff --git a/canvas/source/opengl/ogl_canvashelper.cxx b/canvas/source/opengl/ogl_canvashelper.cxx index d64e1ba1d7f0..df85d1ab428f 100644 --- a/canvas/source/opengl/ogl_canvashelper.cxx +++ b/canvas/source/opengl/ogl_canvashelper.cxx @@ -20,8 +20,9 @@ #include <com/sun/star/rendering/CompositeOperation.hpp> #include <rtl/crc.h> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/font.hxx> +#include <vcl/kernarray.hxx> #include <vcl/metric.hxx> #include <vcl/virdev.hxx> @@ -342,8 +343,7 @@ namespace oglcanvas CanvasHelper::CanvasHelper() : mpDevice( nullptr ), - mpDeviceHelper( nullptr ), - mpRecordedActions() + mpDeviceHelper( nullptr ) {} CanvasHelper::~CanvasHelper() @@ -679,7 +679,8 @@ namespace oglcanvas ScopedVclPtrInstance< VirtualDevice > pVDev; pVDev->EnableOutput(false); - CanvasFont* pFont=dynamic_cast<CanvasFont*>(xLayoutetText->getFont().get()); + auto pLayoutFont = xLayoutetText->getFont(); + CanvasFont* pFont=dynamic_cast<CanvasFont*>(pLayoutFont.get()); const rendering::StringContext& rTxt=xLayoutetText->getText(); if( pFont && rTxt.Length ) { @@ -689,7 +690,7 @@ namespace oglcanvas vcl::Font aFont( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + Size( 0, ::basegfx::fround<tools::Long>(rFontRequest.CellSize))); aFont.SetAlignment( ALIGN_BASELINE ); aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); @@ -729,9 +730,13 @@ namespace oglcanvas { // create the DXArray const sal_Int32 nLen( aLogicalAdvancements.getLength() ); - std::unique_ptr<tools::Long[]> pDXArray( new tools::Long[nLen] ); + KernArray aDXArray; + aDXArray.resize(nLen); for( sal_Int32 i=0; i<nLen; ++i ) - pDXArray[i] = basegfx::fround( aLogicalAdvancements[i] ); + aDXArray.set(i, basegfx::fround(aLogicalAdvancements[i])); + + uno::Sequence<sal_Bool> aKashidaPositions=xLayoutetText->queryKashidaPositions(); + std::span<const sal_Bool> aKashidaArray(aKashidaPositions.getConstArray(), aKashidaPositions.getLength()); // get the glyphs pVDev->GetTextOutlines(rAct.maPolyPolys, @@ -740,7 +745,8 @@ namespace oglcanvas rTxt.StartPosition, rTxt.Length, 0, - pDXArray.get() ); + aDXArray, + aKashidaArray); } else { diff --git a/canvas/source/opengl/ogl_canvastools.cxx b/canvas/source/opengl/ogl_canvastools.cxx index c5fbe0255760..97e7377c0a60 100644 --- a/canvas/source/opengl/ogl_canvastools.cxx +++ b/canvas/source/opengl/ogl_canvastools.cxx @@ -35,9 +35,9 @@ namespace oglcanvas const ::basegfx::triangulator::B2DTriangleVector rTriangulatedPolygon( ::basegfx::triangulator::triangulate(aPolyPoly)); - for( size_t i=0; i<rTriangulatedPolygon.size(); i++ ) + for( auto const& rTriangulatedPolygonItem : rTriangulatedPolygon ) { - const::basegfx::triangulator::B2DTriangle& rCandidate(rTriangulatedPolygon[i]); + const::basegfx::triangulator::B2DTriangle& rCandidate(rTriangulatedPolygonItem); glTexCoord2f( rCandidate.getA().getX()/nWidth, rCandidate.getA().getY()/nHeight); diff --git a/canvas/source/opengl/ogl_spritecanvas.cxx b/canvas/source/opengl/ogl_spritecanvas.cxx index d55625b47668..2b9588667517 100644 --- a/canvas/source/opengl/ogl_spritecanvas.cxx +++ b/canvas/source/opengl/ogl_spritecanvas.cxx @@ -13,8 +13,9 @@ #include <com/sun/star/lang/NoSupportException.hpp> #include <osl/mutex.hxx> #include <toolkit/helper/vclunohelper.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/opengl/OpenGLHelper.hxx> +#include <vcl/window.hxx> #include "ogl_canvascustomsprite.hxx" #include "ogl_spritecanvas.hxx" @@ -157,10 +158,9 @@ com_sun_star_comp_rendering_SpriteCanvas_OGL_get_implementation( { if( !OpenGLHelper::supportsOpenGL()) return nullptr; - auto p = new oglcanvas::SpriteCanvas(args, context); - cppu::acquire(p); + rtl::Reference<oglcanvas::SpriteCanvas> p = new oglcanvas::SpriteCanvas(args, context); p->initialize(); - return static_cast<cppu::OWeakObject*>(p); + return cppu::acquire(p.get()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/opengl/ogl_spritedevicehelper.cxx b/canvas/source/opengl/ogl_spritedevicehelper.cxx index bcca03d0bd45..8cb0a6934f66 100644 --- a/canvas/source/opengl/ogl_spritedevicehelper.cxx +++ b/canvas/source/opengl/ogl_spritedevicehelper.cxx @@ -74,8 +74,6 @@ namespace oglcanvas SpriteDeviceHelper::SpriteDeviceHelper() : mpSpriteCanvas(nullptr), - maActiveSprites(), - maLastUpdate(), mpTextureCache(std::make_shared<TextureCache>()), mnLinearTwoColorGradientProgram(0), mnLinearMultiColorGradientProgram(0), @@ -301,11 +299,10 @@ namespace oglcanvas maLastUpdate.reset(); const double fps(denominator == 0.0 ? 100.0 : 1.0/denominator); - std::vector<double> aVec; aVec.push_back(fps); - aVec.push_back(maActiveSprites.size()); - aVec.push_back(mpTextureCache->getCacheSize()); - aVec.push_back(mpTextureCache->getCacheMissCount()); - aVec.push_back(mpTextureCache->getCacheHitCount()); + std::vector<double> aVec { fps, static_cast<double>(maActiveSprites.size()), + static_cast<double>(mpTextureCache->getCacheSize()), + static_cast<double>(mpTextureCache->getCacheMissCount()), + static_cast<double>(mpTextureCache->getCacheHitCount()) }; renderOSD( aVec, 20 ); /* @@ -343,7 +340,8 @@ namespace oglcanvas uno::Any SpriteDeviceHelper::getDeviceHandle() const { const SystemChildWindow* pChildWindow = mxContext->getChildWindow(); - return uno::Any( reinterpret_cast< sal_Int64 >(pChildWindow) ); + const OutputDevice* pDevice = pChildWindow ? pChildWindow->GetOutDev() : nullptr; + return uno::Any(reinterpret_cast<sal_Int64>(pDevice)); } uno::Any SpriteDeviceHelper::getSurfaceHandle() const diff --git a/canvas/source/opengl/ogl_textlayout.cxx b/canvas/source/opengl/ogl_textlayout.cxx index 89e7a16a681f..a87365275436 100644 --- a/canvas/source/opengl/ogl_textlayout.cxx +++ b/canvas/source/opengl/ogl_textlayout.cxx @@ -9,8 +9,9 @@ #include <sal/config.h> #include <sal/log.hxx> +#include <utility> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include "ogl_textlayout.hxx" @@ -18,19 +19,17 @@ using namespace ::com::sun::star; namespace oglcanvas { - TextLayout::TextLayout( const rendering::StringContext& aText, - sal_Int8 nDirection, - sal_Int64 /*nRandomSeed*/, - const CanvasFont::ImplRef& rFont ) : - TextLayoutBaseT( m_aMutex ), - maText( aText ), - maLogicalAdvancements(), - mpFont( rFont ), + TextLayout::TextLayout( rendering::StringContext aText, + sal_Int8 nDirection, + sal_Int64 /*nRandomSeed*/, + CanvasFont::ImplRef rFont ) : + maText(std::move( aText )), + mpFont(std::move( rFont )), mnTextDirection( nDirection ) { } - void SAL_CALL TextLayout::disposing() + void TextLayout::disposing(std::unique_lock<std::mutex>& /*rGuard*/) { mpFont.clear(); } @@ -56,14 +55,14 @@ namespace oglcanvas uno::Sequence< double > SAL_CALL TextLayout::queryLogicalAdvancements( ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maLogicalAdvancements; } void SAL_CALL TextLayout::applyLogicalAdvancements( const uno::Sequence< double >& aAdvancements ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); if( aAdvancements.getLength() != maText.Length ) { @@ -74,9 +73,29 @@ namespace oglcanvas maLogicalAdvancements = aAdvancements; } + uno::Sequence< sal_Bool > SAL_CALL TextLayout::queryKashidaPositions( ) + { + std::unique_lock aGuard( m_aMutex ); + + return maKashidaPositions; + } + + void SAL_CALL TextLayout::applyKashidaPositions( const uno::Sequence< sal_Bool >& aPositions ) + { + std::unique_lock aGuard( m_aMutex ); + + if( aPositions.hasElements() && aPositions.getLength() != maText.Length ) + { + SAL_WARN("canvas.ogl", "TextLayout::applyKashidaPositions(): mismatching number of positions" ); + throw lang::IllegalArgumentException("mismatching number of positions", getXWeak(), 1); + } + + maKashidaPositions = aPositions; + } + geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds( ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); ENSURE_OR_THROW( mpFont, "TextLayout::queryTextBounds(): invalid font" ); @@ -156,22 +175,18 @@ namespace oglcanvas sal_Int8 SAL_CALL TextLayout::getMainTextDirection( ) { - ::osl::MutexGuard aGuard( m_aMutex ); - return mnTextDirection; } uno::Reference< rendering::XCanvasFont > SAL_CALL TextLayout::getFont( ) { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); - return mpFont.get(); + return mpFont; } rendering::StringContext SAL_CALL TextLayout::getText( ) { - ::osl::MutexGuard aGuard( m_aMutex ); - return maText; } diff --git a/canvas/source/opengl/ogl_textlayout.hxx b/canvas/source/opengl/ogl_textlayout.hxx index f2e6869c466d..d913ec3fb368 100644 --- a/canvas/source/opengl/ogl_textlayout.hxx +++ b/canvas/source/opengl/ogl_textlayout.hxx @@ -9,8 +9,7 @@ #pragma once -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> +#include <comphelper/compbase.hxx> #include <com/sun/star/rendering/XTextLayout.hpp> @@ -21,23 +20,22 @@ namespace oglcanvas { - typedef ::cppu::WeakComponentImplHelper< css::rendering::XTextLayout > TextLayoutBaseT; + typedef ::comphelper::WeakComponentImplHelper< css::rendering::XTextLayout > TextLayoutBaseT; - class TextLayout : public ::cppu::BaseMutex, - public TextLayoutBaseT + class TextLayout : public TextLayoutBaseT { public: - TextLayout( const css::rendering::StringContext& aText, - sal_Int8 nDirection, - sal_Int64 nRandomSeed, - const CanvasFont::ImplRef& rFont ); + TextLayout( css::rendering::StringContext aText, + sal_Int8 nDirection, + sal_Int64 nRandomSeed, + CanvasFont::ImplRef rFont ); /// make noncopyable TextLayout(const TextLayout&) = delete; const TextLayout& operator=(const TextLayout&) = delete; /// Dispose all internal references - virtual void SAL_CALL disposing() override; + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; // XTextLayout virtual css::uno::Sequence< css::uno::Reference< css::rendering::XPolyPolygon2D > > SAL_CALL queryTextShapes( ) override; @@ -45,6 +43,8 @@ namespace oglcanvas virtual css::uno::Sequence< css::geometry::RealRectangle2D > SAL_CALL queryMeasures( ) override; virtual css::uno::Sequence< double > SAL_CALL queryLogicalAdvancements( ) override; virtual void SAL_CALL applyLogicalAdvancements( const css::uno::Sequence< double >& aAdvancements ) override; + virtual css::uno::Sequence< sal_Bool > SAL_CALL queryKashidaPositions( ) override; + virtual void SAL_CALL applyKashidaPositions( const css::uno::Sequence< sal_Bool >& aPositions ) override; virtual css::geometry::RealRectangle2D SAL_CALL queryTextBounds( ) override; virtual double SAL_CALL justify( double nSize ) override; virtual double SAL_CALL combinedJustify( const css::uno::Sequence< css::uno::Reference< css::rendering::XTextLayout > >& aNextLayouts, double nSize ) override; @@ -61,6 +61,7 @@ namespace oglcanvas private: css::rendering::StringContext maText; css::uno::Sequence< double > maLogicalAdvancements; + css::uno::Sequence< sal_Bool > maKashidaPositions; CanvasFont::ImplRef mpFont; sal_Int8 mnTextDirection; }; diff --git a/canvas/source/simplecanvas/simplecanvasimpl.cxx b/canvas/source/simplecanvas/simplecanvasimpl.cxx index c9b87265d1d6..db1377e419b1 100644 --- a/canvas/source/simplecanvas/simplecanvasimpl.cxx +++ b/canvas/source/simplecanvas/simplecanvasimpl.cxx @@ -28,8 +28,7 @@ #include <com/sun/star/rendering/PanoseWeight.hpp> #include <com/sun/star/rendering/XSimpleCanvas.hpp> #include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> +#include <comphelper/compbase.hxx> #include <o3tl/lazy_update.hxx> #include <canvas/canvastools.hxx> @@ -45,29 +44,25 @@ namespace uno::Sequence< double > color2Sequence( sal_Int32 nColor ) { // TODO(F3): Color management - uno::Sequence< double > aRes( 4 ); - - aRes[0] = static_cast<sal_uInt8>( (nColor&0xFF000000U) >> 24U ) / 255.0; - aRes[1] = static_cast<sal_uInt8>( (nColor&0x00FF0000U) >> 16U ) / 255.0; - aRes[2] = static_cast<sal_uInt8>( (nColor&0x0000FF00U) >> 8U ) / 255.0; - aRes[3] = static_cast<sal_uInt8>( (nColor&0x000000FFU) ) / 255.0; - + uno::Sequence< double > aRes{ + static_cast<sal_uInt8>( (nColor&0xFF000000U) >> 24U ) / 255.0, + static_cast<sal_uInt8>( (nColor&0x00FF0000U) >> 16U ) / 255.0, + static_cast<sal_uInt8>( (nColor&0x0000FF00U) >> 8U ) / 255.0, + static_cast<sal_uInt8>( (nColor&0x000000FFU) ) / 255.0 + }; return aRes; } uno::Reference< rendering::XPolyPolygon2D > rect2Poly( uno::Reference<rendering::XGraphicDevice> const& xDevice, geometry::RealRectangle2D const& rRect ) { - uno::Sequence< geometry::RealPoint2D > rectSequence( 4 ); - geometry::RealPoint2D* pOutput = rectSequence.getArray(); - pOutput[0] = geometry::RealPoint2D( rRect.X1, rRect.Y1 ); - pOutput[1] = geometry::RealPoint2D( rRect.X2, rRect.Y1 ); - pOutput[2] = geometry::RealPoint2D( rRect.X2, rRect.Y2 ); - pOutput[3] = geometry::RealPoint2D( rRect.X1, rRect.Y2 ); - - uno::Sequence< uno::Sequence< geometry::RealPoint2D > > sequenceSequence( 1 ); - sequenceSequence[0] = rectSequence; - + uno::Sequence< geometry::RealPoint2D > rectSequence{ + geometry::RealPoint2D( rRect.X1, rRect.Y1 ), + geometry::RealPoint2D( rRect.X2, rRect.Y1 ), + geometry::RealPoint2D( rRect.X2, rRect.Y2 ), + geometry::RealPoint2D( rRect.X1, rRect.Y2 ) + }; + uno::Sequence< uno::Sequence< geometry::RealPoint2D > > sequenceSequence{ rectSequence }; uno::Reference< rendering::XPolyPolygon2D > xRes = xDevice->createCompatibleLinePolyPolygon( sequenceSequence ); if( xRes.is() ) @@ -91,19 +86,17 @@ namespace explicit SimpleRenderState( uno::Reference<rendering::XGraphicDevice> const& xDevice ) : m_aPenColor( &color2Sequence), m_aFillColor( &color2Sequence ), - m_aRectClip( [&xDevice](geometry::RealRectangle2D const& rRect) { return rect2Poly(xDevice, rRect); } ), - m_aTransformation() + m_aRectClip( [&xDevice](geometry::RealRectangle2D const& rRect) { return rect2Poly(xDevice, rRect); } ) { tools::setIdentityAffineMatrix2D( m_aTransformation ); } }; - typedef ::cppu::WeakComponentImplHelper< css::rendering::XSimpleCanvas, + typedef ::comphelper::WeakComponentImplHelper< css::rendering::XSimpleCanvas, css::lang::XServiceName > SimpleCanvasBase; - class SimpleCanvasImpl : private cppu::BaseMutex, - public SimpleCanvasBase + class SimpleCanvasImpl : public SimpleCanvasBase { private: bool isStrokingEnabled() const @@ -152,13 +145,11 @@ namespace public: SimpleCanvasImpl( const uno::Sequence< uno::Any >& aArguments, const uno::Reference< uno::XComponentContext >& ) : - SimpleCanvasBase( m_aMutex ), mxCanvas( grabCanvas(aArguments) ), maFont([this](rendering::FontRequest const& rFontRequest) { return mxCanvas->createFont(rFontRequest, uno::Sequence< beans::PropertyValue >(), geometry::Matrix2D()); } ), - maViewState(), maRenderState( mxCanvas->getDevice() ) { tools::initViewState(maViewState); @@ -178,7 +169,7 @@ namespace sal_Bool bold, sal_Bool italic ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); maFont->FontDescription.FamilyName = sFontName; maFont->CellSize = size; @@ -190,31 +181,31 @@ namespace virtual void SAL_CALL setPenColor( ::sal_Int32 nsRgbaColor ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); *(maRenderState.m_aPenColor) = nsRgbaColor; } virtual void SAL_CALL setFillColor( ::sal_Int32 nsRgbaColor ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); *(maRenderState.m_aFillColor) = nsRgbaColor; } virtual void SAL_CALL setRectClip( const geometry::RealRectangle2D& aRect ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); *(maRenderState.m_aRectClip) = aRect; } virtual void SAL_CALL setTransformation( const geometry::AffineMatrix2D& aTransform ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); maRenderState.m_aTransformation = aTransform; } virtual void SAL_CALL drawPixel( const geometry::RealPoint2D& aPoint ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); mxCanvas->drawPoint(aPoint, maViewState, createFillingRenderState()); @@ -223,7 +214,7 @@ namespace virtual void SAL_CALL drawLine( const geometry::RealPoint2D& aStartPoint, const geometry::RealPoint2D& aEndPoint ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); mxCanvas->drawLine(aStartPoint, aEndPoint, maViewState, @@ -232,7 +223,7 @@ namespace virtual void SAL_CALL drawRect( const geometry::RealRectangle2D& aRect ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); uno::Reference< rendering::XPolyPolygon2D > xPoly( rect2Poly( mxCanvas->getDevice(), aRect)); @@ -249,7 +240,7 @@ namespace virtual void SAL_CALL drawPolyPolygon( const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); if( isFillingEnabled() ) mxCanvas->drawPolyPolygon(xPolyPolygon, @@ -265,7 +256,7 @@ namespace const geometry::RealPoint2D& aOutPos, ::sal_Int8 nTextDirection ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); const basegfx::B2DHomMatrix offsetTransform(basegfx::utils::createTranslateB2DHomMatrix(aOutPos.X,aOutPos.Y)); rendering::RenderState aRenderState( createStrokingRenderState() ); tools::appendToRenderState(aRenderState, offsetTransform); @@ -280,7 +271,7 @@ namespace virtual void SAL_CALL drawBitmap( const uno::Reference< rendering::XBitmap >& xBitmap, const geometry::RealPoint2D& aLeftTop ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); const basegfx::B2DHomMatrix offsetTransform(basegfx::utils::createTranslateB2DHomMatrix(aLeftTop.X,aLeftTop.Y)); rendering::RenderState aRenderState( createStrokingRenderState() ); tools::appendToRenderState(aRenderState, offsetTransform); @@ -290,61 +281,61 @@ namespace virtual uno::Reference< rendering::XGraphicDevice > SAL_CALL getDevice( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return mxCanvas->getDevice(); } virtual uno::Reference< rendering::XCanvas > SAL_CALL getCanvas( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return mxCanvas; } virtual rendering::FontMetrics SAL_CALL getFontMetrics( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maFont.getOutValue()->getFontMetrics(); } virtual uno::Reference< rendering::XCanvasFont > SAL_CALL getCurrentFont( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maFont.getOutValue(); } virtual ::sal_Int32 SAL_CALL getCurrentPenColor( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maRenderState.m_aPenColor.getInValue(); } virtual ::sal_Int32 SAL_CALL getCurrentFillColor( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maRenderState.m_aFillColor.getInValue(); } virtual geometry::RealRectangle2D SAL_CALL getCurrentClipRect( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maRenderState.m_aRectClip.getInValue(); } virtual geometry::AffineMatrix2D SAL_CALL getCurrentTransformation( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maRenderState.m_aTransformation; } virtual rendering::ViewState SAL_CALL getCurrentViewState( ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return maViewState; } virtual rendering::RenderState SAL_CALL getCurrentRenderState( sal_Bool bUseFillColor ) override { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); if( bUseFillColor ) return createFillingRenderState(); else diff --git a/canvas/source/tools/cachedprimitivebase.cxx b/canvas/source/tools/cachedprimitivebase.cxx index 056796fcde98..73b09758dce2 100644 --- a/canvas/source/tools/cachedprimitivebase.cxx +++ b/canvas/source/tools/cachedprimitivebase.cxx @@ -25,17 +25,17 @@ #include <cppuhelper/supportsservice.hxx> #include <base/cachedprimitivebase.hxx> +#include <utility> using namespace ::com::sun::star; namespace canvas { - CachedPrimitiveBase::CachedPrimitiveBase( const rendering::ViewState& rUsedViewState, - const uno::Reference< rendering::XCanvas >& rTarget ) : - CachedPrimitiveBase_Base( m_aMutex ), - maUsedViewState( rUsedViewState ), - mxTarget( rTarget ) + CachedPrimitiveBase::CachedPrimitiveBase( rendering::ViewState aUsedViewState, + uno::Reference< rendering::XCanvas > xTarget ) : + maUsedViewState(std::move( aUsedViewState )), + mxTarget(std::move( xTarget )) { } @@ -43,10 +43,8 @@ namespace canvas { } - void SAL_CALL CachedPrimitiveBase::disposing() + void CachedPrimitiveBase::disposing(std::unique_lock<std::mutex>& /*rGuard*/) { - ::osl::MutexGuard aGuard( m_aMutex ); - maUsedViewState.Clip.clear(); mxTarget.clear(); } @@ -78,7 +76,7 @@ namespace canvas OUString SAL_CALL CachedPrimitiveBase::getImplementationName( ) { - return "canvas::CachedPrimitiveBase"; + return u"canvas::CachedPrimitiveBase"_ustr; } sal_Bool SAL_CALL CachedPrimitiveBase::supportsService( const OUString& ServiceName ) @@ -88,7 +86,7 @@ namespace canvas uno::Sequence< OUString > SAL_CALL CachedPrimitiveBase::getSupportedServiceNames( ) { - return { "com.sun.star.rendering.CachedBitmap" }; + return { u"com.sun.star.rendering.CachedBitmap"_ustr }; } } diff --git a/canvas/source/tools/canvascustomspritehelper.cxx b/canvas/source/tools/canvascustomspritehelper.cxx index 156936a05e53..975d62325d49 100644 --- a/canvas/source/tools/canvascustomspritehelper.cxx +++ b/canvas/source/tools/canvascustomspritehelper.cxx @@ -30,7 +30,7 @@ #include <basegfx/utils/canvastools.hxx> #include <basegfx/vector/b2dsize.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <base/canvascustomspritehelper.hxx> #include <canvas/canvastools.hxx> @@ -146,12 +146,6 @@ namespace canvas } CanvasCustomSpriteHelper::CanvasCustomSpriteHelper() : - mpSpriteCanvas(), - maCurrClipBounds(), - maPosition(), - maSize(), - maTransform(), - mxClipPoly(), mfPriority(0.0), mfAlpha(0.0), mbActive(false), @@ -197,16 +191,14 @@ namespace canvas if( xBitmap->hasAlpha() ) return; - const geometry::IntegerSize2D& rInputSize( - xBitmap->getSize() ); - const ::basegfx::B2DSize& rOurSize( - rSprite->getSizePixel() ); + const geometry::IntegerSize2D& rInputSize(xBitmap->getSize()); + basegfx::B2DSize rOurSize(rSprite->getSizePixel().getX(), rSprite->getSizePixel().getY()); ::basegfx::B2DHomMatrix aTransform; if( tools::isInside( ::basegfx::B2DRectangle( 0.0,0.0, - rOurSize.getX(), - rOurSize.getY() ), + rOurSize.getWidth(), + rOurSize.getHeight() ), ::basegfx::B2DRectangle( 0.0,0.0, rInputSize.Width, rInputSize.Height ), diff --git a/canvas/source/tools/canvastools.cxx b/canvas/source/tools/canvastools.cxx index 53ab7e71f0c5..1ff393005758 100644 --- a/canvas/source/tools/canvastools.cxx +++ b/canvas/source/tools/canvastools.cxx @@ -51,10 +51,9 @@ #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp> #include <com/sun/star/util/Endianness.hpp> #include <cppuhelper/implbase.hxx> -#include <rtl/instance.hxx> #include <sal/log.hxx> #include <toolkit/helper/vclunohelper.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/canvastools.hxx> #include <vcl/window.hxx> @@ -843,33 +842,18 @@ namespace canvas::tools } }; - struct StandardColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>, - StandardColorSpaceHolder> - { - uno::Reference<rendering::XIntegerBitmapColorSpace> operator()() - { - return new StandardColorSpace(); - } - }; - - struct StandardNoAlphaColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>, - StandardNoAlphaColorSpaceHolder> - { - uno::Reference<rendering::XIntegerBitmapColorSpace> operator()() - { - return new StandardNoAlphaColorSpace(); - } - }; } uno::Reference<rendering::XIntegerBitmapColorSpace> const & getStdColorSpace() { - return StandardColorSpaceHolder::get(); + static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new StandardColorSpace(); + return SPACE; } uno::Reference<rendering::XIntegerBitmapColorSpace> const & getStdColorSpaceWithoutAlpha() { - return StandardNoAlphaColorSpaceHolder::get(); + static uno::Reference<rendering::XIntegerBitmapColorSpace> SPACE = new StandardNoAlphaColorSpace(); + return SPACE; } rendering::IntegerBitmapLayout getStdMemoryLayout( const geometry::IntegerSize2D& rBmpSize ) @@ -895,7 +879,7 @@ namespace canvas::tools pCols[0] = rColor.GetRed(); pCols[1] = rColor.GetGreen(); pCols[2] = rColor.GetBlue(); - pCols[3] = 255-rColor.GetTransparency(); + pCols[3] = rColor.GetAlpha(); #else *reinterpret_cast<sal_Int32*>(pCols) = sal_Int32(rColor); #endif @@ -1096,27 +1080,25 @@ namespace canvas::tools { o_rxParams.realloc( 0 ); - if( i_rxCanvas.is() ) + if( !i_rxCanvas.is() ) + return o_rxParams; + + try { - try - { - uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(), - uno::UNO_SET_THROW ); + uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(), + uno::UNO_SET_THROW ); - uno::Reference< lang::XServiceInfo > xServiceInfo( xDevice, - uno::UNO_QUERY_THROW ); - uno::Reference< beans::XPropertySet > xPropSet( xDevice, + uno::Reference< lang::XServiceInfo > xServiceInfo( xDevice, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPropSet( xDevice, + uno::UNO_QUERY_THROW ); - o_rxParams.realloc( 2 ); - - o_rxParams[ 0 ] <<= xServiceInfo->getImplementationName(); - o_rxParams[ 1 ] = xPropSet->getPropertyValue( "DeviceHandle" ); - } - catch( const uno::Exception& ) - { - // ignore, but return empty sequence - } + o_rxParams = { uno::Any(xServiceInfo->getImplementationName()), + xPropSet->getPropertyValue( "DeviceHandle" ) }; + } + catch( const uno::Exception& ) + { + // ignore, but return empty sequence } return o_rxParams; diff --git a/canvas/source/tools/elapsedtime.cxx b/canvas/source/tools/elapsedtime.cxx index 84a6ed5c48bd..46167dd9a851 100644 --- a/canvas/source/tools/elapsedtime.cxx +++ b/canvas/source/tools/elapsedtime.cxx @@ -22,6 +22,7 @@ #include <canvas/elapsedtime.hxx> #include <tools/time.hxx> +#include <utility> namespace canvas::tools { @@ -41,8 +42,8 @@ ElapsedTime::ElapsedTime() } ElapsedTime::ElapsedTime( - std::shared_ptr<ElapsedTime> const & pTimeBase ) - : m_pTimeBase( pTimeBase ), + std::shared_ptr<ElapsedTime> pTimeBase ) + : m_pTimeBase(std::move( pTimeBase )), m_fLastQueriedTime( 0.0 ), m_fStartTime( getCurrentTime() ), m_fFrozenTime( 0.0 ), diff --git a/canvas/source/tools/page.cxx b/canvas/source/tools/page.cxx index 3537fa0b6873..32eedb71b29f 100644 --- a/canvas/source/tools/page.cxx +++ b/canvas/source/tools/page.cxx @@ -18,14 +18,14 @@ */ #include <sal/config.h> - +#include <basegfx/vector/b2ivector.hxx> #include "page.hxx" namespace canvas { Page::Page( const std::shared_ptr<IRenderModule> &rRenderModule ) : mpRenderModule(rRenderModule), - mpSurface(rRenderModule->createSurface(::basegfx::B2ISize())) + mpSurface(rRenderModule->createSurface(::basegfx::B2IVector())) { } @@ -76,10 +76,7 @@ namespace canvas // be relocated to some other page or it will // currently be deleted. in either case, simply // remove the reference from our internal storage. - FragmentContainer_t::iterator it( - std::remove( - mpFragments.begin(),mpFragments.end(),pFragment)); - mpFragments.erase(it,mpFragments.end()); + std::erase(mpFragments, pFragment); } bool Page::insert( SurfaceRect& r ) @@ -91,8 +88,8 @@ namespace canvas const sal_Int32 y = rect.maPos.getY(); // to avoid interpolation artifacts from other textures, // one pixel gap between them - const sal_Int32 w = rect.maSize.getX()+1; - const sal_Int32 h = rect.maSize.getY()+1; + const sal_Int32 w = rect.maSize.getWidth() + 1; + const sal_Int32 h = rect.maSize.getHeight() + 1; // probe location to the right r.maPos.setX(x+w); @@ -118,7 +115,8 @@ namespace canvas // the rectangle passed as argument has a valid // location if and only if there's no intersection // with existing areas. - SurfaceRect aBoundary(mpRenderModule->getPageSize()); + basegfx::B2ISize aSize(mpRenderModule->getPageSize().getX(), mpRenderModule->getPageSize().getY()); + SurfaceRect aBoundary(aSize); if( !r.inside(aBoundary) ) return false; diff --git a/canvas/source/tools/page.hxx b/canvas/source/tools/page.hxx index 14fa17c53ae0..6af4bf0f6be8 100644 --- a/canvas/source/tools/page.hxx +++ b/canvas/source/tools/page.hxx @@ -20,6 +20,7 @@ #pragma once #include <basegfx/vector/b2isize.hxx> +#include <basegfx/vector/b2ivector.hxx> #include <basegfx/range/b2irectangle.hxx> #include <rendering/icolorbuffer.hxx> #include <rendering/irendermodule.hxx> @@ -132,7 +133,7 @@ namespace canvas return pSurface->update( maRect.maPos, ::basegfx::B2IRectangle( maSourceOffset, - maSourceOffset + maRect.maSize ), + maSourceOffset + basegfx::B2IVector(maRect.maSize.getWidth(), maRect.maSize.getHeight())), *mpBuffer ); } diff --git a/canvas/source/tools/pagemanager.cxx b/canvas/source/tools/pagemanager.cxx index c1e874ca498a..4ee7df76ed7e 100644 --- a/canvas/source/tools/pagemanager.cxx +++ b/canvas/source/tools/pagemanager.cxx @@ -18,7 +18,7 @@ */ #include <sal/config.h> - +#include <basegfx/vector/b2ivector.hxx> #include "pagemanager.hxx" namespace canvas @@ -65,10 +65,7 @@ namespace canvas { // erase the reference to the given fragment from our // internal container. - FragmentContainer_t::iterator it( - std::remove( - maFragments.begin(),maFragments.end(),pFragment)); - maFragments.erase(it,maFragments.end()); + std::erase(maFragments, pFragment); // let the fragment itself know about it... // we need to pass 'this' as argument since the fragment @@ -98,7 +95,7 @@ namespace canvas if( *aCurr && !( ( *aCurr )->isNaked() ) ) { const ::basegfx::B2ISize& rSize( ( *aCurr )->getSize() ); - sal_uInt32 nArea( rSize.getX() * rSize.getY() ); + sal_uInt32 nArea( rSize.getWidth() * rSize.getHeight() ); if( nCurrMaxArea < nArea ) { @@ -145,7 +142,8 @@ namespace canvas ::basegfx::B2ISize PageManager::getPageSize() const { - return mpRenderModule->getPageSize(); + return { mpRenderModule->getPageSize().getX(), + mpRenderModule->getPageSize().getY() }; } } diff --git a/canvas/source/tools/pagemanager.hxx b/canvas/source/tools/pagemanager.hxx index a5d905ef726c..57de912a12ba 100644 --- a/canvas/source/tools/pagemanager.hxx +++ b/canvas/source/tools/pagemanager.hxx @@ -21,6 +21,7 @@ #include <basegfx/vector/b2isize.hxx> #include <rendering/irendermodule.hxx> +#include <utility> #include "page.hxx" @@ -30,8 +31,8 @@ namespace canvas class PageManager { public: - explicit PageManager(const std::shared_ptr<canvas::IRenderModule>& rRenderModule) - : mpRenderModule(rRenderModule) + explicit PageManager(std::shared_ptr<canvas::IRenderModule> xRenderModule) + : mpRenderModule(std::move(xRenderModule)) { } diff --git a/canvas/source/tools/parametricpolypolygon.cxx b/canvas/source/tools/parametricpolypolygon.cxx index bd62b1b5568a..ca42d7fe36f7 100644 --- a/canvas/source/tools/parametricpolypolygon.cxx +++ b/canvas/source/tools/parametricpolypolygon.cxx @@ -27,6 +27,7 @@ #include <com/sun/star/rendering/XGraphicDevice.hpp> #include <parametricpolypolygon.hxx> +#include <utility> using namespace ::com::sun::star; @@ -39,23 +40,19 @@ namespace canvas "RectangularGradient"}; } - ParametricPolyPolygon* ParametricPolyPolygon::create( + rtl::Reference<ParametricPolyPolygon> ParametricPolyPolygon::create( const uno::Reference< rendering::XGraphicDevice >& rDevice, std::u16string_view rServiceName, const uno::Sequence< uno::Any >& rArgs ) { - uno::Sequence< uno::Sequence< double > > colorSequence(2); - uno::Sequence< double > colorStops(2); double fAspectRatio=1.0; // defaults - uno::Sequence< rendering::RGBColor > rgbColors(1); - rgbColors[0] = rendering::RGBColor(0,0,0); - colorSequence[0] = rDevice->getDeviceColorSpace()->convertFromRGB(rgbColors); - rgbColors[0] = rendering::RGBColor(1,1,1); - colorSequence[1] = rDevice->getDeviceColorSpace()->convertFromRGB(rgbColors); - colorStops[0] = 0; - colorStops[1] = 1; + uno::Sequence< uno::Sequence< double > > colorSequence{ + rDevice->getDeviceColorSpace()->convertFromRGB({ rendering::RGBColor(0,0,0) }), + rDevice->getDeviceColorSpace()->convertFromRGB({ rendering::RGBColor(1,1,1) }) + }; + uno::Sequence< double > colorStops{ 0, 1 }; // extract args for( const uno::Any& rArg : rArgs ) @@ -110,7 +107,7 @@ namespace canvas return nullptr; } - ParametricPolyPolygon* ParametricPolyPolygon::createLinearHorizontalGradient( + rtl::Reference<ParametricPolyPolygon> ParametricPolyPolygon::createLinearHorizontalGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice, const uno::Sequence< uno::Sequence< double > >& colors, const uno::Sequence< double >& stops ) @@ -120,7 +117,7 @@ namespace canvas return new ParametricPolyPolygon( rDevice, GradientType::Linear, colors, stops ); } - ParametricPolyPolygon* ParametricPolyPolygon::createEllipticalGradient( + rtl::Reference<ParametricPolyPolygon> ParametricPolyPolygon::createEllipticalGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice, const uno::Sequence< uno::Sequence< double > >& colors, const uno::Sequence< double >& stops, @@ -136,7 +133,7 @@ namespace canvas colors, stops, fAspectRatio ); } - ParametricPolyPolygon* ParametricPolyPolygon::createRectangularGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice, + rtl::Reference<ParametricPolyPolygon> ParametricPolyPolygon::createRectangularGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice, const uno::Sequence< uno::Sequence< double > >& colors, const uno::Sequence< double >& stops, double fAspectRatio ) @@ -151,10 +148,8 @@ namespace canvas colors, stops, fAspectRatio ); } - void SAL_CALL ParametricPolyPolygon::disposing() + void ParametricPolyPolygon::disposing(std::unique_lock<std::mutex>&) { - ::osl::MutexGuard aGuard( m_aMutex ); - mxDevice.clear(); } @@ -178,7 +173,7 @@ namespace canvas uno::Reference< rendering::XColorSpace > SAL_CALL ParametricPolyPolygon::getColorSpace() { - ::osl::MutexGuard aGuard( m_aMutex ); + std::unique_lock aGuard( m_aMutex ); return mxDevice.is() ? mxDevice->getDeviceColorSpace() : uno::Reference< rendering::XColorSpace >(); } @@ -186,7 +181,7 @@ namespace canvas OUString SAL_CALL ParametricPolyPolygon::getImplementationName( ) { - return "Canvas::ParametricPolyPolygon"; + return u"Canvas::ParametricPolyPolygon"_ustr; } sal_Bool SAL_CALL ParametricPolyPolygon::supportsService( const OUString& ServiceName ) @@ -196,21 +191,20 @@ namespace canvas uno::Sequence< OUString > SAL_CALL ParametricPolyPolygon::getSupportedServiceNames( ) { - return { "com.sun.star.rendering.ParametricPolyPolygon" }; + return { u"com.sun.star.rendering.ParametricPolyPolygon"_ustr }; } ParametricPolyPolygon::~ParametricPolyPolygon() { } - ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& rDevice, + ParametricPolyPolygon::ParametricPolyPolygon( uno::Reference< rendering::XGraphicDevice > xDevice, const ::basegfx::B2DPolygon& rGradientPoly, GradientType eType, const uno::Sequence< uno::Sequence< double > >& rColors, const uno::Sequence< double >& rStops, double nAspectRatio ) : - ParametricPolyPolygon_Base( m_aMutex ), - mxDevice( rDevice ), + mxDevice(std::move( xDevice )), maValues( rGradientPoly, rColors, rStops, @@ -219,12 +213,11 @@ namespace canvas { } - ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& rDevice, + ParametricPolyPolygon::ParametricPolyPolygon( uno::Reference< rendering::XGraphicDevice > xDevice, GradientType eType, const uno::Sequence< uno::Sequence< double > >& rColors, const uno::Sequence< double >& rStops ) : - ParametricPolyPolygon_Base( m_aMutex ), - mxDevice( rDevice ), + mxDevice(std::move( xDevice )), maValues( ::basegfx::B2DPolygon(), rColors, rStops, @@ -235,8 +228,6 @@ namespace canvas ParametricPolyPolygon::Values ParametricPolyPolygon::getValues() const { - ::osl::MutexGuard aGuard( m_aMutex ); - return maValues; } diff --git a/canvas/source/tools/propertysethelper.cxx b/canvas/source/tools/propertysethelper.cxx index 92f2e3bd28e4..24a07cb7dc25 100644 --- a/canvas/source/tools/propertysethelper.cxx +++ b/canvas/source/tools/propertysethelper.cxx @@ -57,16 +57,14 @@ namespace canvas }; } - PropertySetHelper::PropertySetHelper() : - mpMap(), - maMapEntries() + PropertySetHelper::PropertySetHelper() { } - void PropertySetHelper::initProperties( const InputMap& rMap ) + void PropertySetHelper::initProperties( InputMap&& rMap ) { mpMap.reset(); - maMapEntries = rMap; + maMapEntries = std::move(rMap); std::sort( maMapEntries.begin(), maMapEntries.end(), @@ -85,7 +83,7 @@ namespace canvas rMap.begin(), rMap.end() ); - initProperties( aMerged ); + initProperties( std::move(aMerged) ); } bool PropertySetHelper::isPropertyName( const OUString& aPropertyName ) const diff --git a/canvas/source/tools/spriteredrawmanager.cxx b/canvas/source/tools/spriteredrawmanager.cxx index 443673093ff1..06eb6d1de594 100644 --- a/canvas/source/tools/spriteredrawmanager.cxx +++ b/canvas/source/tools/spriteredrawmanager.cxx @@ -23,11 +23,12 @@ #include <basegfx/range/b2drectangle.hxx> #include <basegfx/utils/canvastools.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <sal/log.hxx> #include <spriteredrawmanager.hxx> #include <boost/range/adaptor/reversed.hpp> +#include <utility> namespace canvas { @@ -43,10 +44,8 @@ namespace canvas class SpriteTracer { public: - explicit SpriteTracer( const Sprite::Reference& rAffectedSprite ) : - mpAffectedSprite(rAffectedSprite), - maMoveStartArea(), - maMoveEndArea(), + explicit SpriteTracer( Sprite::Reference rAffectedSprite ) : + mpAffectedSprite(std::move(rAffectedSprite)), mbIsMove( false ), mbIsGenericUpdate( false ) { @@ -425,9 +424,7 @@ namespace canvas { return cp.second.needsUpdate(); } ); } - SpriteRedrawManager::SpriteRedrawManager() : - maSprites(), - maChangeRecords() + SpriteRedrawManager::SpriteRedrawManager() { } @@ -458,7 +455,7 @@ namespace canvas void SpriteRedrawManager::hideSprite( const Sprite::Reference& rSprite ) { - maSprites.erase(std::remove(maSprites.begin(), maSprites.end(), rSprite), maSprites.end()); + std::erase(maSprites, rSprite); } void SpriteRedrawManager::moveSprite( const Sprite::Reference& rSprite, diff --git a/canvas/source/tools/surface.cxx b/canvas/source/tools/surface.cxx index 10c2d4655343..ff5dce985048 100644 --- a/canvas/source/tools/surface.cxx +++ b/canvas/source/tools/surface.cxx @@ -22,18 +22,18 @@ #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <basegfx/polygon/b2dpolygonclipper.hxx> #include <comphelper/scopeguard.hxx> +#include <utility> #include "surface.hxx" namespace canvas { - Surface::Surface( const PageManagerSharedPtr& rPageManager, - const std::shared_ptr<IColorBuffer>& rColorBuffer, + Surface::Surface( PageManagerSharedPtr rPageManager, + std::shared_ptr<IColorBuffer> xColorBuffer, const ::basegfx::B2IPoint& rPos, const ::basegfx::B2ISize& rSize ) : - mpColorBuffer(rColorBuffer), - mpPageManager(rPageManager), - mpFragment(), + mpColorBuffer(std::move(xColorBuffer)), + mpPageManager(std::move(rPageManager)), maSourceOffset(rPos), maSize(rSize), mbIsDirty(true) @@ -58,12 +58,12 @@ namespace canvas if( mpFragment ) aDestOffset = mpFragment->getPos(); - const double pw( aPageSize.getX() ); - const double ph( aPageSize.getY() ); + const double pw( aPageSize.getWidth() ); + const double ph( aPageSize.getHeight() ); const double ox( aDestOffset.getX() ); const double oy( aDestOffset.getY() ); - const double sx( maSize.getX() ); - const double sy( maSize.getY() ); + const double sx( maSize.getWidth() ); + const double sy( maSize.getHeight() ); return ::basegfx::B2DRectangle( ox/pw, oy/ph, @@ -76,12 +76,12 @@ namespace canvas { ::basegfx::B2ISize aPageSize(mpPageManager->getPageSize()); - const double pw( aPageSize.getX() ); - const double ph( aPageSize.getY() ); + const double pw( aPageSize.getWidth() ); + const double ph( aPageSize.getHeight() ); const double ox( rPos.getX() ); const double oy( rPos.getY() ); - const double sx( rSize.getX() ); - const double sy( rSize.getY() ); + const double sx( rSize.getWidth() ); + const double sy( rSize.getHeight() ); return ::basegfx::B2DRectangle( ox/pw, oy/ph, @@ -117,8 +117,7 @@ namespace canvas basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix( maSourceOffset.getX(), maSourceOffset.getY())); aTransform = aTransform * rTransform; - aTransform.translate(::basegfx::fround(rPos.getX()), - ::basegfx::fround(rPos.getY())); + aTransform.translate(rPos); /* ###################################### @@ -145,10 +144,10 @@ namespace canvas ###################################### */ - const ::basegfx::B2DPoint& p0(aTransform * ::basegfx::B2DPoint(maSize.getX(),maSize.getY())); - const ::basegfx::B2DPoint& p1(aTransform * ::basegfx::B2DPoint(0.0,maSize.getY())); + const ::basegfx::B2DPoint& p0(aTransform * ::basegfx::B2DPoint(maSize.getWidth(),maSize.getHeight())); + const ::basegfx::B2DPoint& p1(aTransform * ::basegfx::B2DPoint(0.0,maSize.getHeight())); const ::basegfx::B2DPoint& p2(aTransform * ::basegfx::B2DPoint(0.0,0.0)); - const ::basegfx::B2DPoint& p3(aTransform * ::basegfx::B2DPoint(maSize.getX(),0.0)); + const ::basegfx::B2DPoint& p3(aTransform * ::basegfx::B2DPoint(maSize.getWidth(),0.0)); canvas::Vertex vertex; vertex.r = 1.0f; @@ -208,10 +207,10 @@ namespace canvas ::basegfx::fround(rArea.getMaximum().getY()) ); // clip the positions to the area this surface covers - aPos1.setX(std::max(aPos1.getX(),maSourceOffset.getX())); - aPos1.setY(std::max(aPos1.getY(),maSourceOffset.getY())); - aPos2.setX(std::min(aPos2.getX(),maSourceOffset.getX()+maSize.getX())); - aPos2.setY(std::min(aPos2.getY(),maSourceOffset.getY()+maSize.getY())); + aPos1.setX(std::max(aPos1.getX(), maSourceOffset.getX())); + aPos1.setY(std::max(aPos1.getY(), maSourceOffset.getY())); + aPos2.setX(std::min(aPos2.getX(), maSourceOffset.getX() + maSize.getWidth())); + aPos2.setY(std::min(aPos2.getY(), maSourceOffset.getY() + maSize.getHeight())); // if the resulting area is empty, return immediately ::basegfx::B2IVector aSize(aPos2 - aPos1); @@ -225,7 +224,7 @@ namespace canvas // convert size to normalized device coordinates const ::basegfx::B2DRectangle& rUV( getUVCoords(aPos1 - maSourceOffset + aDestOffset, - aSize) ); + basegfx::B2ISize(aSize.getX(), aSize.getY())) ); const double u1(rUV.getMinX()); const double v1(rUV.getMinY()); const double u2(rUV.getMaxX()); @@ -237,8 +236,7 @@ namespace canvas // 3) translation to output position [rPos] basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix(aPos1.getX(), aPos1.getY())); aTransform = aTransform * rTransform; - aTransform.translate(::basegfx::fround(rPos.getX()), - ::basegfx::fround(rPos.getY())); + aTransform.translate(rPos); /* @@ -321,8 +319,8 @@ namespace canvas // the whole image, with non-zero maSourceOffset) const double x1(maSourceOffset.getX()); const double y1(maSourceOffset.getY()); - const double w(maSize.getX()); - const double h(maSize.getY()); + const double w(maSize.getWidth()); + const double h(maSize.getHeight()); const double x2(x1+w); const double y2(y1+h); const ::basegfx::B2DRectangle aSurfaceClipRect(x1,y1,x2,y2); @@ -333,8 +331,7 @@ namespace canvas // be calculated from the result, and this is why we need to use // integer coordinates here... basegfx::B2DHomMatrix aTransform = rTransform; - aTransform.translate(::basegfx::fround(rPos.getX()), - ::basegfx::fround(rPos.getY())); + aTransform.translate(rPos); /* ###################################### diff --git a/canvas/source/tools/surface.hxx b/canvas/source/tools/surface.hxx index 25b859ba416b..e78925292f27 100644 --- a/canvas/source/tools/surface.hxx +++ b/canvas/source/tools/surface.hxx @@ -41,8 +41,8 @@ namespace canvas { public: - Surface( const PageManagerSharedPtr& rPageManager, - const std::shared_ptr<IColorBuffer>& rColorBuffer, + Surface( PageManagerSharedPtr xPageManager, + std::shared_ptr<IColorBuffer> xColorBuffer, const ::basegfx::B2IPoint& rPos, const ::basegfx::B2ISize& rSize ); ~Surface(); diff --git a/canvas/source/tools/surfaceproxy.cxx b/canvas/source/tools/surfaceproxy.cxx index b5c2b52f95b6..af76b8b3c30a 100644 --- a/canvas/source/tools/surfaceproxy.cxx +++ b/canvas/source/tools/surfaceproxy.cxx @@ -23,23 +23,23 @@ #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/polygon/b2dpolygontriangulator.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <utility> #include "surfaceproxy.hxx" namespace canvas { - SurfaceProxy::SurfaceProxy( const std::shared_ptr<canvas::IColorBuffer>& pBuffer, - const PageManagerSharedPtr& pPageManager ) : - mpPageManager( pPageManager ), - maSurfaceList(), - mpBuffer( pBuffer ) + SurfaceProxy::SurfaceProxy( std::shared_ptr<canvas::IColorBuffer> xBuffer, + PageManagerSharedPtr xPageManager ) : + mpPageManager(std::move( xPageManager )), + mpBuffer(std::move( xBuffer )) { const ::basegfx::B2ISize aImageSize(mpBuffer->getWidth(),mpBuffer->getHeight()); const ::basegfx::B2ISize aPageSize(mpPageManager->getPageSize()); - const sal_Int32 aPageSizeX(aPageSize.getX()); - const sal_Int32 aPageSizeY(aPageSize.getY()); - const sal_Int32 aImageSizeX(aImageSize.getX()); - const sal_Int32 aImageSizeY(aImageSize.getY()); + const sal_Int32 aPageSizeX(aPageSize.getWidth()); + const sal_Int32 aPageSizeY(aPageSize.getHeight()); + const sal_Int32 aImageSizeX(aImageSize.getWidth()); + const sal_Int32 aImageSizeY(aImageSize.getHeight()); // see if the size of the colorbuffer is larger than the size // of a single page. if this is the case we divide the @@ -64,10 +64,10 @@ namespace canvas // the current surface is located at the position [x,y] // and has the size [min(restx,pagesizex),min(resty,pagesizey) ::basegfx::B2IPoint aOffset(x,y); - ::basegfx::B2ISize aSize( std::min( aImageSize.getX()-x, - aPageSize.getX() ), - std::min( aImageSize.getY()-y, - aPageSize.getY() ) ); + ::basegfx::B2ISize aSize( std::min( aImageSize.getWidth()-x, + aPageSize.getWidth() ), + std::min( aImageSize.getHeight()-y, + aPageSize.getHeight() ) ); maSurfaceList.push_back( std::make_shared<Surface>( diff --git a/canvas/source/tools/surfaceproxy.hxx b/canvas/source/tools/surfaceproxy.hxx index 5c620d3e3bc8..72841d754e0a 100644 --- a/canvas/source/tools/surfaceproxy.hxx +++ b/canvas/source/tools/surfaceproxy.hxx @@ -38,8 +38,8 @@ namespace canvas { public: - SurfaceProxy( const std::shared_ptr<canvas::IColorBuffer>& pBuffer, - const PageManagerSharedPtr &pPageManager ); + SurfaceProxy( std::shared_ptr<canvas::IColorBuffer> xBuffer, + PageManagerSharedPtr xPageManager ); // ISurfaceProxy interface virtual void setColorBufferDirty() override; diff --git a/canvas/source/tools/surfacerect.hxx b/canvas/source/tools/surfacerect.hxx index 808796d6d528..0925fa8e6f4b 100644 --- a/canvas/source/tools/surfacerect.hxx +++ b/canvas/source/tools/surfacerect.hxx @@ -49,8 +49,8 @@ namespace canvas { const sal_Int32 x1(maPos.getX()); const sal_Int32 y1(maPos.getY()); - const sal_Int32 x2(x1 + maSize.getX()); - const sal_Int32 y2(y1 + maSize.getY()); + const sal_Int32 x2(x1 + maSize.getWidth()); + const sal_Int32 y2(y1 + maSize.getHeight()); if(px < x1) return false; if(px >= x2) return false; if(py < y1) return false; @@ -63,13 +63,13 @@ namespace canvas { const sal_Int32 x1(maPos.getX()); const sal_Int32 y1(maPos.getY()); - const sal_Int32 x1w(x1 + maSize.getX() - 1); - const sal_Int32 y1h(y1 + maSize.getY() - 1); + const sal_Int32 x1w(x1 + maSize.getWidth() - 1); + const sal_Int32 y1h(y1 + maSize.getHeight() - 1); const sal_Int32 x2(r.maPos.getX()); const sal_Int32 y2(r.maPos.getY()); - const sal_Int32 x2w(x2 + r.maSize.getX() - 1); - const sal_Int32 y2h(y2 + r.maSize.getY() - 1); + const sal_Int32 x2w(x2 + r.maSize.getWidth() - 1); + const sal_Int32 y2h(y2 + r.maSize.getHeight() - 1); return !((x1w < x2) || (x2w < x1) || (y1h < y2) || (y2h < y1)); } @@ -78,8 +78,8 @@ namespace canvas { const sal_Int32 x1(maPos.getX()); const sal_Int32 y1(maPos.getY()); - const sal_Int32 x2(x1 + maSize.getX() - 1); - const sal_Int32 y2(y1 + maSize.getY() - 1); + const sal_Int32 x2(x1 + maSize.getWidth() - 1); + const sal_Int32 y2(y1 + maSize.getHeight() - 1); if(!(r.pointInside(x1,y1))) return false; if(!(r.pointInside(x2,y2))) return false; return true; diff --git a/canvas/source/vcl/backbuffer.cxx b/canvas/source/vcl/backbuffer.cxx index c2779cdf0489..aa45a56e7ab6 100644 --- a/canvas/source/vcl/backbuffer.cxx +++ b/canvas/source/vcl/backbuffer.cxx @@ -27,14 +27,9 @@ namespace vclcanvas { - BackBuffer::BackBuffer( const OutputDevice& rRefDevice, - bool bMonochromeBuffer ) : - maVDev( VclPtr<VirtualDevice>::Create( rRefDevice, - bMonochromeBuffer ? DeviceFormat::BITMASK : DeviceFormat::DEFAULT ) ) + BackBuffer::BackBuffer( const OutputDevice& rRefDevice ) : + maVDev( VclPtr<VirtualDevice>::Create( rRefDevice, DeviceFormat::WITHOUT_ALPHA ) ) { - if( bMonochromeBuffer ) - return; - tools::SetDefaultDeviceAntiAliasing( maVDev ); } diff --git a/canvas/source/vcl/backbuffer.hxx b/canvas/source/vcl/backbuffer.hxx index 6bbeb85ec54b..0e31111b6fcf 100644 --- a/canvas/source/vcl/backbuffer.hxx +++ b/canvas/source/vcl/backbuffer.hxx @@ -31,15 +31,8 @@ namespace vclcanvas class BackBuffer : public OutDevProvider { public: - /** Create a backbuffer for given reference device - - @param bMonochromeBuffer - When false, default depth of reference device is - chosen. When true, the buffer will be monochrome, i.e. one - bit deep. - */ - BackBuffer( const OutputDevice& rRefDevice, - bool bMonochromeBuffer=false ); + /** Create a backbuffer for given reference device */ + BackBuffer( const OutputDevice& rRefDevice ); virtual ~BackBuffer() override; virtual OutputDevice& getOutDev() override; diff --git a/canvas/source/vcl/bitmapbackbuffer.cxx b/canvas/source/vcl/bitmapbackbuffer.cxx index 337e0bae7c2e..3766276f3b53 100644 --- a/canvas/source/vcl/bitmapbackbuffer.cxx +++ b/canvas/source/vcl/bitmapbackbuffer.cxx @@ -111,8 +111,8 @@ namespace vclcanvas // VDev not yet created, do it now. Create an alpha-VDev, // if bitmap has transparency. - mpVDev = maBitmap->IsTransparent() ? - VclPtr<VirtualDevice>::Create( mrRefDevice, DeviceFormat::DEFAULT, DeviceFormat::DEFAULT ) : + mpVDev = maBitmap->IsAlpha() ? + VclPtr<VirtualDevice>::Create( mrRefDevice, DeviceFormat::WITH_ALPHA ) : VclPtr<VirtualDevice>::Create( mrRefDevice ); OSL_ENSURE( mpVDev, diff --git a/canvas/source/vcl/cachedbitmap.cxx b/canvas/source/vcl/cachedbitmap.cxx index 404b8888402c..a27bf6166f96 100644 --- a/canvas/source/vcl/cachedbitmap.cxx +++ b/canvas/source/vcl/cachedbitmap.cxx @@ -21,7 +21,8 @@ #include <com/sun/star/rendering/XCanvas.hpp> #include <com/sun/star/rendering/RepaintResult.hpp> -#include <tools/diagnose_ex.h> +#include <utility> +#include <comphelper/diagnose_ex.hxx> #include "cachedbitmap.hxx" #include "repainttarget.hxx" @@ -31,29 +32,27 @@ using namespace ::com::sun::star; namespace vclcanvas { - CachedBitmap::CachedBitmap( const GraphicObjectSharedPtr& rGraphicObject, + CachedBitmap::CachedBitmap( GraphicObjectSharedPtr xGraphicObject, const ::Point& rPoint, const ::Size& rSize, const GraphicAttr& rAttr, const rendering::ViewState& rUsedViewState, - const rendering::RenderState& rUsedRenderState, + rendering::RenderState aUsedRenderState, const uno::Reference< rendering::XCanvas >& rTarget ) : CachedPrimitiveBase( rUsedViewState, rTarget ), - mpGraphicObject( rGraphicObject ), - maRenderState(rUsedRenderState), + mpGraphicObject(std::move( xGraphicObject )), + maRenderState(std::move(aUsedRenderState)), maPoint( rPoint ), maSize( rSize ), maAttributes( rAttr ) { } - void SAL_CALL CachedBitmap::disposing() + void CachedBitmap::disposing(std::unique_lock<std::mutex>& rGuard) { - ::osl::MutexGuard aGuard( m_aMutex ); - mpGraphicObject.reset(); - CachedPrimitiveBase::disposing(); + CachedPrimitiveBase::disposing(rGuard); } ::sal_Int8 CachedBitmap::doRedraw( const rendering::ViewState& rNewState, diff --git a/canvas/source/vcl/cachedbitmap.hxx b/canvas/source/vcl/cachedbitmap.hxx index 1b3b396ebd5a..140b9c968f38 100644 --- a/canvas/source/vcl/cachedbitmap.hxx +++ b/canvas/source/vcl/cachedbitmap.hxx @@ -37,16 +37,16 @@ namespace vclcanvas /** Create an XCachedPrimitive for given GraphicObject */ - CachedBitmap( const GraphicObjectSharedPtr& rGraphicObject, + CachedBitmap( GraphicObjectSharedPtr xGraphicObject, const ::Point& rPoint, const ::Size& rSize, const GraphicAttr& rAttr, const css::rendering::ViewState& rUsedViewState, - const css::rendering::RenderState& rUsedRenderState, + css::rendering::RenderState aUsedRenderState, const css::uno::Reference< css::rendering::XCanvas >& rTarget ); /// Dispose all internal references - virtual void SAL_CALL disposing() override; + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; private: virtual ::sal_Int8 doRedraw( const css::rendering::ViewState& rNewState, diff --git a/canvas/source/vcl/canvas.cxx b/canvas/source/vcl/canvas.cxx index e8f6ffe0c62a..4a3b6f8d766b 100644 --- a/canvas/source/vcl/canvas.cxx +++ b/canvas/source/vcl/canvas.cxx @@ -19,40 +19,20 @@ #include <sal/config.h> +#include "canvas.hxx" + #include <com/sun/star/lang/NoSupportException.hpp> #include <sal/log.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> +#include <cppuhelper/supportsservice.hxx> #include <vcl/outdev.hxx> -#include "canvas.hxx" +#include "outdevholder.hxx" using namespace ::com::sun::star; namespace vclcanvas { - namespace - { - class OutDevHolder : public OutDevProvider - { - public: - OutDevHolder(const OutDevHolder&) = delete; - const OutDevHolder& operator=(const OutDevHolder&) = delete; - - explicit OutDevHolder( OutputDevice& rOutDev ) : - mrOutDev(rOutDev) - {} - - private: - virtual OutputDevice& getOutDev() override { return mrOutDev; } - virtual const OutputDevice& getOutDev() const override { return mrOutDev; } - - // TODO(Q2): Lifetime issue. This _only_ works reliably, - // if disposing the Canvas correctly disposes all - // entities which hold this pointer. - OutputDevice& mrOutDev; - }; - } - Canvas::Canvas( const uno::Sequence< uno::Any >& aArguments, const uno::Reference< uno::XComponentContext >& /*rxContext*/ ) : maArguments(aArguments) @@ -114,7 +94,19 @@ namespace vclcanvas OUString SAL_CALL Canvas::getServiceName( ) { - return "com.sun.star.rendering.Canvas.VCL"; + return u"com.sun.star.rendering.Canvas.VCL"_ustr; + } + + OUString Canvas::getImplementationName() { + return u"com.sun.star.comp.rendering.Canvas.VCL"_ustr; + } + + sal_Bool Canvas::supportsService(OUString const & ServiceName) { + return cppu::supportsService(this, ServiceName); + } + + css::uno::Sequence<OUString> Canvas::getSupportedServiceNames() { + return {getServiceName()}; } bool Canvas::repaint( const GraphicObjectSharedPtr& rGrf, @@ -134,10 +126,9 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* com_sun_star_comp_rendering_Canvas_VCL_get_implementation( css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) { - auto p = new vclcanvas::Canvas(args, context); - cppu::acquire(p); + rtl::Reference<vclcanvas::Canvas> p = new vclcanvas::Canvas(args, context); p->initialize(); - return static_cast<cppu::OWeakObject*>(p); + return cppu::acquire(p.get()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/vcl/canvas.hxx b/canvas/source/vcl/canvas.hxx index be7d7858e3ad..8bcbc1f49894 100644 --- a/canvas/source/vcl/canvas.hxx +++ b/canvas/source/vcl/canvas.hxx @@ -21,6 +21,7 @@ #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XServiceName.hpp> #include <com/sun/star/util/XUpdatable.hpp> #include <com/sun/star/rendering/XBitmapCanvas.hpp> @@ -48,7 +49,8 @@ namespace vclcanvas css::lang::XMultiServiceFactory, css::util::XUpdatable, css::beans::XPropertySet, - css::lang::XServiceName > GraphicDeviceBase_Base; + css::lang::XServiceName, + css::lang::XServiceInfo > GraphicDeviceBase_Base; typedef ::canvas::GraphicDeviceBase< ::canvas::BaseMutexHelper< GraphicDeviceBase_Base >, DeviceHelper, tools::LocalGuard, @@ -96,6 +98,10 @@ namespace vclcanvas // XServiceName virtual OUString SAL_CALL getServiceName( ) override; + OUString SAL_CALL getImplementationName() override; + sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override; + css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + // RepaintTarget virtual bool repaint( const GraphicObjectSharedPtr& rGrf, const css::rendering::ViewState& viewState, diff --git a/canvas/source/vcl/canvasbitmap.cxx b/canvas/source/vcl/canvasbitmap.cxx index 1de5800fa653..193afd62c6b2 100644 --- a/canvas/source/vcl/canvasbitmap.cxx +++ b/canvas/source/vcl/canvasbitmap.cxx @@ -39,10 +39,7 @@ namespace vclcanvas { // create bitmap for given reference device // ======================================== - const sal_uInt16 nBitCount( sal_uInt16(24U) ); - const BitmapPalette* pPalette = nullptr; - - Bitmap aBitmap( rSize, nBitCount, pPalette ); + Bitmap aBitmap(rSize, vcl::PixelFormat::N24_BPP); // only create alpha channel bitmap, if factory requested // that. Providing alpha-channeled bitmaps by default has, @@ -74,7 +71,7 @@ namespace vclcanvas OUString SAL_CALL CanvasBitmap::getImplementationName( ) { - return "VCLCanvas.CanvasBitmap"; + return u"VCLCanvas.CanvasBitmap"_ustr; } sal_Bool SAL_CALL CanvasBitmap::supportsService( const OUString& ServiceName ) @@ -84,7 +81,7 @@ namespace vclcanvas uno::Sequence< OUString > SAL_CALL CanvasBitmap::getSupportedServiceNames( ) { - return { "com.sun.star.rendering.CanvasBitmap" }; + return { u"com.sun.star.rendering.CanvasBitmap"_ustr }; } BitmapEx CanvasBitmap::getBitmap() const diff --git a/canvas/source/vcl/canvasbitmaphelper.cxx b/canvas/source/vcl/canvasbitmaphelper.cxx index dd1898486e8a..99b9831cabf6 100644 --- a/canvas/source/vcl/canvasbitmaphelper.cxx +++ b/canvas/source/vcl/canvasbitmaphelper.cxx @@ -21,7 +21,7 @@ #include <sal/log.hxx> #include <canvas/canvastools.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/bitmapex.hxx> #include <vcl/BitmapTools.hxx> #include <vcl/canvastools.hxx> @@ -34,9 +34,7 @@ using namespace ::com::sun::star; namespace vclcanvas { - CanvasBitmapHelper::CanvasBitmapHelper() : - mpBackBuffer(), - mpOutDevReference() + CanvasBitmapHelper::CanvasBitmapHelper() { } @@ -53,7 +51,7 @@ namespace vclcanvas CanvasHelper::init( rDevice, mpBackBuffer, false, - rBitmap.IsTransparent() ); + rBitmap.IsAlpha() ); } void CanvasBitmapHelper::disposing() @@ -148,7 +146,7 @@ namespace vclcanvas pRes[ 0 ] = aColor.GetRed(); pRes[ 1 ] = aColor.GetGreen(); pRes[ 2 ] = aColor.GetBlue(); - pRes[ 3 ] = 255 - aColor.GetAlpha(); + pRes[ 3 ] = aColor.GetAlpha(); return aRes; } diff --git a/canvas/source/vcl/canvascustomsprite.cxx b/canvas/source/vcl/canvascustomsprite.cxx index 9d1f83a74ef7..316176f6ac24 100644 --- a/canvas/source/vcl/canvascustomsprite.cxx +++ b/canvas/source/vcl/canvascustomsprite.cxx @@ -22,7 +22,7 @@ #include <basegfx/point/b2dpoint.hxx> #include <cppuhelper/supportsservice.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/outdev.hxx> #include "canvascustomsprite.hxx" @@ -58,9 +58,8 @@ namespace vclcanvas BackBufferSharedPtr pBackBuffer = std::make_shared<BackBuffer>( rOutDevProvider->getOutDev() ); pBackBuffer->setSize( aSize ); - // create mask backbuffer, with one bit color depth - BackBufferSharedPtr pBackBufferMask = std::make_shared<BackBuffer>( rOutDevProvider->getOutDev(), - true ); + // create mask backbuffer + BackBufferSharedPtr pBackBufferMask = std::make_shared<BackBuffer>( rOutDevProvider->getOutDev() ); pBackBufferMask->setSize( aSize ); // TODO(F1): Implement alpha vdev (could prolly enable @@ -104,7 +103,7 @@ namespace vclcanvas OUString SAL_CALL CanvasCustomSprite::getImplementationName() { - return "VCLCanvas.CanvasCustomSprite"; + return u"VCLCanvas.CanvasCustomSprite"_ustr; } sal_Bool SAL_CALL CanvasCustomSprite::supportsService( const OUString& ServiceName ) @@ -114,7 +113,7 @@ namespace vclcanvas uno::Sequence< OUString > SAL_CALL CanvasCustomSprite::getSupportedServiceNames() { - return { "com.sun.star.rendering.CanvasCustomSprite" }; + return { u"com.sun.star.rendering.CanvasCustomSprite"_ustr }; } // Sprite diff --git a/canvas/source/vcl/canvasfont.cxx b/canvas/source/vcl/canvasfont.cxx index e7fab0492549..235f72fbb514 100644 --- a/canvas/source/vcl/canvasfont.cxx +++ b/canvas/source/vcl/canvasfont.cxx @@ -41,13 +41,13 @@ namespace vclcanvas const geometry::Matrix2D& rFontMatrix, rendering::XGraphicDevice& rDevice, const OutDevProviderSharedPtr& rOutDevProvider ) : - CanvasFont_Base( m_aMutex ), maFont( vcl::Font( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize) ) ) ), + Size( 0, ::basegfx::fround<::tools::Long>(rFontRequest.CellSize) ) ) ), maFontRequest( rFontRequest ), mpRefDevice( &rDevice ), - mpOutDevProvider( rOutDevProvider ) + mpOutDevProvider( rOutDevProvider ), + maFontMatrix( rFontMatrix ) { maFont->SetAlignment( ALIGN_BASELINE ); maFont->SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==css::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); @@ -63,27 +63,7 @@ namespace vclcanvas maFont->SetLanguage( LanguageTag::convertToLanguageType( rFontRequest.Locale, false)); // adjust to stretched/shrunk font - if( !::rtl::math::approxEqual( rFontMatrix.m00, rFontMatrix.m11) ) - { - OutputDevice& rOutDev( rOutDevProvider->getOutDev() ); - - const bool bOldMapState( rOutDev.IsMapModeEnabled() ); - rOutDev.EnableMapMode(false); - - const Size aSize = rOutDev.GetFontMetric( *maFont ).GetFontSize(); - - const double fDividend( rFontMatrix.m10 + rFontMatrix.m11 ); - double fStretch = rFontMatrix.m00 + rFontMatrix.m01; - - if( !::basegfx::fTools::equalZero( fDividend) ) - fStretch /= fDividend; - - const ::tools::Long nNewWidth = ::basegfx::fround( aSize.Width() * fStretch ); - - maFont->SetAverageFontWidth( nNewWidth ); - - rOutDev.EnableMapMode(bOldMapState); - } + tools::setupFontWidth(rFontMatrix, maFont.get(), rOutDevProvider->getOutDev()); sal_uInt32 nEmphasisMark = 0; @@ -93,12 +73,16 @@ namespace vclcanvas maFont->SetEmphasisMark(FontEmphasisMark(nEmphasisMark)); } - void SAL_CALL CanvasFont::disposing() + void CanvasFont::disposing(std::unique_lock<std::mutex>& rGuard) { - SolarMutexGuard aGuard; + rGuard.unlock(); + { + SolarMutexGuard aGuard; - mpOutDevProvider.reset(); - mpRefDevice.clear(); + mpOutDevProvider.reset(); + mpRefDevice.clear(); + } + rGuard.lock(); } uno::Reference< rendering::XTextLayout > SAL_CALL CanvasFont::createTextLayout( const rendering::StringContext& aText, sal_Int8 nDirection, sal_Int64 ) @@ -117,8 +101,6 @@ namespace vclcanvas rendering::FontRequest SAL_CALL CanvasFont::getFontRequest( ) { - SolarMutexGuard aGuard; - return maFontRequest; } @@ -155,7 +137,7 @@ namespace vclcanvas OUString SAL_CALL CanvasFont::getImplementationName() { - return "VCLCanvas::CanvasFont"; + return u"VCLCanvas::CanvasFont"_ustr; } sal_Bool SAL_CALL CanvasFont::supportsService( const OUString& ServiceName ) @@ -165,13 +147,18 @@ namespace vclcanvas uno::Sequence< OUString > SAL_CALL CanvasFont::getSupportedServiceNames() { - return { "com.sun.star.rendering.CanvasFont" }; + return { u"com.sun.star.rendering.CanvasFont"_ustr }; } vcl::Font const & CanvasFont::getVCLFont() const { return *maFont; } + + const css::geometry::Matrix2D& CanvasFont::getFontMatrix() const + { + return maFontMatrix; + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/vcl/canvasfont.hxx b/canvas/source/vcl/canvasfont.hxx index fdfa870f5ed3..3e64d3d9f60d 100644 --- a/canvas/source/vcl/canvasfont.hxx +++ b/canvas/source/vcl/canvasfont.hxx @@ -19,8 +19,7 @@ #pragma once -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> +#include <comphelper/compbase.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/geometry/Matrix2D.hpp> @@ -39,11 +38,10 @@ namespace vclcanvas { - typedef ::cppu::WeakComponentImplHelper< css::rendering::XCanvasFont, + typedef ::comphelper::WeakComponentImplHelper< css::rendering::XCanvasFont, css::lang::XServiceInfo > CanvasFont_Base; - class CanvasFont : public ::cppu::BaseMutex, - public CanvasFont_Base + class CanvasFont : public CanvasFont_Base { public: typedef rtl::Reference<CanvasFont> Reference; @@ -59,7 +57,7 @@ namespace vclcanvas const OutDevProviderSharedPtr& rOutDevProvider ); /// Dispose all internal references - virtual void SAL_CALL disposing() override; + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; // XCanvasFont virtual css::uno::Reference< css::rendering::XTextLayout > SAL_CALL createTextLayout( const css::rendering::StringContext& aText, sal_Int8 nDirection, sal_Int64 nRandomSeed ) override; @@ -75,11 +73,14 @@ namespace vclcanvas vcl::Font const & getVCLFont() const; + const css::geometry::Matrix2D& getFontMatrix() const; + private: ::canvas::vcltools::VCLObject<vcl::Font> maFont; css::rendering::FontRequest maFontRequest; css::uno::Reference< css::rendering::XGraphicDevice> mpRefDevice; OutDevProviderSharedPtr mpOutDevProvider; + css::geometry::Matrix2D maFontMatrix; }; } diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx index 501741301d8e..861f74402134 100644 --- a/canvas/source/vcl/canvashelper.cxx +++ b/canvas/source/vcl/canvashelper.cxx @@ -35,12 +35,13 @@ #include <com/sun/star/rendering/TextDirection.hpp> #include <comphelper/sequence.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <tools/poly.hxx> #include <vcl/bitmapex.hxx> #include <vcl/BitmapReadAccess.hxx> #include <vcl/canvastools.hxx> #include <vcl/BitmapAlphaClampFilter.hxx> +#include <vcl/skia/SkiaHelper.hxx> #include <canvas/canvastools.hxx> @@ -104,9 +105,6 @@ namespace vclcanvas CanvasHelper::CanvasHelper() : mpDevice(), - mpProtectedOutDevProvider(), - mpOutDevProvider(), - mp2ndOutDevProvider(), mbHaveAlpha( false ) { } @@ -378,7 +376,7 @@ namespace vclcanvas double fMiterMinimumAngle; if (strokeAttributes.MiterLimit <= 1.0) { - fMiterMinimumAngle = F_PI2; + fMiterMinimumAngle = M_PI_2; } else { @@ -568,21 +566,21 @@ namespace vclcanvas return uno::Reference< rendering::XCachedPrimitive >(nullptr); // no output necessary // change text direction and layout mode - ComplexTextLayoutFlags nLayoutMode(ComplexTextLayoutFlags::Default); + vcl::text::ComplexTextLayoutFlags nLayoutMode(vcl::text::ComplexTextLayoutFlags::Default); switch( textDirection ) { case rendering::TextDirection::WEAK_LEFT_TO_RIGHT: case rendering::TextDirection::STRONG_LEFT_TO_RIGHT: - nLayoutMode |= ComplexTextLayoutFlags::BiDiStrong; - nLayoutMode |= ComplexTextLayoutFlags::TextOriginLeft; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::TextOriginLeft; break; case rendering::TextDirection::WEAK_RIGHT_TO_LEFT: - nLayoutMode |= ComplexTextLayoutFlags::BiDiRtl; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiRtl; [[fallthrough]]; case rendering::TextDirection::STRONG_RIGHT_TO_LEFT: - nLayoutMode |= ComplexTextLayoutFlags::BiDiRtl | ComplexTextLayoutFlags::BiDiStrong; - nLayoutMode |= ComplexTextLayoutFlags::TextOriginRight; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiRtl | vcl::text::ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode |= vcl::text::ComplexTextLayoutFlags::TextOriginRight; break; } @@ -710,7 +708,7 @@ namespace vclcanvas // actually what mp2ndOutDev is... well, here we do & // assume a 1bpp target - everything beyond 97% // transparency is fully transparent - if( aBmpEx.IsAlpha() ) + if( aBmpEx.IsAlpha() && !SkiaHelper::isVCLSkiaEnabled()) { BitmapFilter::Filter(aBmpEx, BitmapAlphaClampFilter(253)); } @@ -723,6 +721,41 @@ namespace vclcanvas // itself serves this purpose return uno::Reference< rendering::XCachedPrimitive >(nullptr); } + else if( mpOutDevProvider->getOutDev().HasFastDrawTransformedBitmap()) + { + ::basegfx::B2DHomMatrix aSizeTransform; + aSizeTransform.scale( aBmpEx.GetSizePixel().Width(), aBmpEx.GetSizePixel().Height() ); + aMatrix = aMatrix * aSizeTransform; + const double fAlpha = bModulateColors ? renderState.DeviceColor[3] : 1.0; + + mpOutDevProvider->getOutDev().DrawTransformedBitmapEx( aMatrix, aBmpEx, fAlpha ); + if( mp2ndOutDevProvider ) + { + if( aBmpEx.IsAlpha() ) + { + // tdf#157790 invert alpha mask + // Due to commit 81994cb2b8b32453a92bcb011830fcb884f22ff3, + // the alpha mask needs to be inverted. Note: when + // testing tdf#157790, this code only gets executed + // when Skia is enabled. + AlphaMask aAlpha( aBmpEx.GetAlphaMask() ); + aAlpha.Invert(); + aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aAlpha ); + + // HACK. Normally, CanvasHelper does not care about + // actually what mp2ndOutDev is... well, here we do & + // assume a 1bpp target - everything beyond 97% + // transparency is fully transparent + if( !SkiaHelper::isVCLSkiaEnabled()) + { + BitmapFilter::Filter(aBmpEx, BitmapAlphaClampFilter(253)); + } + } + + mp2ndOutDevProvider->getOutDev().DrawTransformedBitmapEx( aMatrix, aBmpEx ); + } + return uno::Reference< rendering::XCachedPrimitive >(nullptr); + } else { // Matrix contains non-trivial transformation (or @@ -771,7 +804,7 @@ namespace vclcanvas // degrees with the orientation reversed: [0,2Pi) -> // (3600,0]. Note that the original angle may have // values outside the [0,2Pi) interval. - const double nAngleInTenthOfDegrees (3600.0 - nRotate * 3600.0 / (2*M_PI)); + const double nAngleInTenthOfDegrees (3600.0 - basegfx::rad2deg<10>(nRotate)); aGrfAttr.SetRotation( Degree10(::basegfx::fround(nAngleInTenthOfDegrees)) ); pGrfObj = std::make_shared<GraphicObject>( aBmpEx ); @@ -809,19 +842,35 @@ namespace vclcanvas // output GraphicObject const ::Point aPt( vcl::unotools::pointFromB2DPoint( aOutputPos ) ); - const ::Size aSz( ::basegfx::fround( aScale.getX() * aBmpSize.Width() ), - ::basegfx::fround( aScale.getY() * aBmpSize.Height() ) ); + const ::Size aSz( ::basegfx::fround<::tools::Long>( aScale.getX() * aBmpSize.Width() ), + ::basegfx::fround<::tools::Long>( aScale.getY() * aBmpSize.Height() ) ); - pGrfObj->Draw( &mpOutDevProvider->getOutDev(), - aPt, - aSz, - &aGrfAttr ); + pGrfObj->Draw(mpOutDevProvider->getOutDev(), + aPt, + aSz, + &aGrfAttr); if( mp2ndOutDevProvider ) - pGrfObj->Draw( &mp2ndOutDevProvider->getOutDev(), - aPt, - aSz, - &aGrfAttr ); + { + GraphicObjectSharedPtr p2ndGrfObj = pGrfObj; + if( aBmpEx.IsAlpha() ) + { + // tdf#157790 invert alpha mask + // Due to commit 81994cb2b8b32453a92bcb011830fcb884f22ff3, + // the alpha mask needs to be inverted. Note: when + // testing tdf#157790, this code only gets executed + // when Skia is disabled. + AlphaMask aAlpha( aBmpEx.GetAlphaMask() ); + aAlpha.Invert(); + BitmapEx a2ndBmpEx( aBmpEx.GetBitmap(), aAlpha ); + p2ndGrfObj = std::make_shared<GraphicObject>( a2ndBmpEx ); + } + + p2ndGrfObj->Draw(mp2ndOutDevProvider->getOutDev(), + aPt, + aSz, + &aGrfAttr); + } // created GraphicObject, which possibly cached // display bitmap - return cache object, to retain @@ -922,7 +971,7 @@ namespace vclcanvas Bitmap aBitmap( rOutDev.GetBitmapEx(aRect.TopLeft(), aRect.GetSize()).GetBitmap() ); - Bitmap::ScopedReadAccess pReadAccess( aBitmap ); + BitmapScopedReadAccess pReadAccess( aBitmap ); ENSURE_OR_THROW( pReadAccess.get() != nullptr, "Could not acquire read access to OutDev bitmap" ); @@ -1138,12 +1187,12 @@ namespace vclcanvas tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDevProvider ); setupOutDevState( viewState, renderState, IGNORE_COLOR ); - if( !rGrf->Draw( &mpOutDevProvider->getOutDev(), rPt, rSz, &rAttr ) ) + if (!rGrf->Draw(mpOutDevProvider->getOutDev(), rPt, rSz, &rAttr)) return false; // #i80779# Redraw also into mask outdev - if( mp2ndOutDevProvider ) - return rGrf->Draw( &mp2ndOutDevProvider->getOutDev(), rPt, rSz, &rAttr ); + if (mp2ndOutDevProvider) + return rGrf->Draw(mp2ndOutDevProvider->getOutDev(), rPt, rSz, &rAttr); return true; } diff --git a/canvas/source/vcl/canvashelper_texturefill.cxx b/canvas/source/vcl/canvashelper_texturefill.cxx index c0ef516d4c0a..6972066b47a5 100644 --- a/canvas/source/vcl/canvashelper_texturefill.cxx +++ b/canvas/source/vcl/canvashelper_texturefill.cxx @@ -34,7 +34,7 @@ #include <basegfx/utils/tools.hxx> #include <com/sun/star/rendering/TexturingMode.hpp> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <tools/poly.hxx> #include <vcl/bitmapex.hxx> #include <vcl/canvastools.hxx> @@ -55,7 +55,7 @@ namespace vclcanvas namespace { bool textureFill( OutputDevice& rOutDev, - GraphicObject& rGraphic, + const GraphicObject& rGraphic, const ::Point& rPosPixel, const ::Size& rNextTileX, const ::Size& rNextTileY, @@ -77,10 +77,10 @@ namespace vclcanvas { // update return value. This method should return true, if // at least one of the looped Draws succeeded. - bRet |= rGraphic.Draw( &rOutDev, - aCurrPos, - rTileSize, - &rAttr ); + bRet |= rGraphic.Draw(rOutDev, + aCurrPos, + rTileSize, + &rAttr); aCurrPos.AdjustX(rNextTileX.Width() ); aCurrPos.AdjustY(rNextTileX.Height() ); @@ -154,18 +154,17 @@ namespace vclcanvas // 2 colors and 2 stops (at 0 and 1) is a linear gradient: if( rColors.size() == 2 && rValues.maStops.size() == 2 && rValues.maStops[0] == 0 && rValues.maStops[1] == 1) { - Gradient vclGradient( GradientStyle::Linear, rColors[ 0 ], rColors[ 1 ] ); - ::tools::Polygon aTempPoly( static_cast<sal_uInt16>(5) ); - aTempPoly[0] = ::Point( ::basegfx::fround( aLeftTop.getX() ), - ::basegfx::fround( aLeftTop.getY() ) ); - aTempPoly[1] = ::Point( ::basegfx::fround( aRightTop.getX() ), - ::basegfx::fround( aRightTop.getY() ) ); - aTempPoly[2] = ::Point( ::basegfx::fround( aRightBottom.getX() ), - ::basegfx::fround( aRightBottom.getY() ) ); - aTempPoly[3] = ::Point( ::basegfx::fround( aLeftBottom.getX() ), - ::basegfx::fround( aLeftBottom.getY() ) ); - aTempPoly[4] = aTempPoly[0]; - rOutDev.DrawGradient( aTempPoly, vclGradient ); + // tdf#144073 and tdf#147645: use bounds and angle for gradient + // Passing an expanded, rotated polygon noticeably modifies the + // drawing of the gradient in a slideshow due to moving of the + // starting and ending colors far off the edges of the drawing + // surface. So try another way and set the angle of the + // gradient and draw only the unadjusted bounds. + Gradient vclGradient( css::awt::GradientStyle_LINEAR, rColors[ 0 ], rColors[ 1 ] ); + double fRotate = atan2( aDirection.getY(), aDirection.getX() ); + const double nAngleInTenthOfDegrees = 3600.0 - basegfx::rad2deg<10>( fRotate ) + 900.0; + vclGradient.SetAngle( Degree10( ::basegfx::fround( nAngleInTenthOfDegrees ) ) ); + rOutDev.DrawGradient( rBounds, vclGradient ); return; } // 3 colors with first and last being equal and 3 stops (at 0, 0.5 and 1) is an axial gradient: @@ -173,18 +172,17 @@ namespace vclcanvas && rValues.maStops.size() == 3 && rValues.maStops[0] == 0 && rValues.maStops[1] == 0.5 && rValues.maStops[2] == 1) { - Gradient vclGradient( GradientStyle::Axial, rColors[ 1 ], rColors[ 0 ] ); - ::tools::Polygon aTempPoly( static_cast<sal_uInt16>(5) ); - aTempPoly[0] = ::Point( ::basegfx::fround( aLeftTop.getX() ), - ::basegfx::fround( aLeftTop.getY() ) ); - aTempPoly[1] = ::Point( ::basegfx::fround( aRightTop.getX() ), - ::basegfx::fround( aRightTop.getY() ) ); - aTempPoly[2] = ::Point( ::basegfx::fround( aRightBottom.getX() ), - ::basegfx::fround( aRightBottom.getY() ) ); - aTempPoly[3] = ::Point( ::basegfx::fround( aLeftBottom.getX() ), - ::basegfx::fround( aLeftBottom.getY() ) ); - aTempPoly[4] = aTempPoly[0]; - rOutDev.DrawGradient( aTempPoly, vclGradient ); + // tdf#144073 and tdf#147645: use bounds and angle for gradient + // Passing an expanded, rotated polygon noticeably modifies the + // drawing of the gradient in a slideshow due to moving of the + // starting and ending colors far off the edges of the drawing + // surface. So try another way and set the angle of the + // gradient and draw only the unadjusted bounds. + Gradient vclGradient( css::awt::GradientStyle_AXIAL, rColors[ 1 ], rColors[ 0 ] ); + double fRotate = atan2( aDirection.getY(), aDirection.getX() ); + const double nAngleInTenthOfDegrees = 3600.0 - basegfx::rad2deg<10>( fRotate ) + 900.0; + vclGradient.SetAngle( Degree10( ::basegfx::fround( nAngleInTenthOfDegrees ) ) ); + rOutDev.DrawGradient( rBounds, vclGradient ); return; } @@ -213,12 +211,12 @@ namespace vclcanvas // loop below, we set the _right_ edge here, which will be // readily copied into the left edge in the loop below const ::basegfx::B2DPoint& rPoint1( aLeftTop - 2.0*nDiagonalLength*aDirection ); - aTempPoly[1] = ::Point( ::basegfx::fround( rPoint1.getX() ), - ::basegfx::fround( rPoint1.getY() ) ); + aTempPoly[1] = ::Point( ::basegfx::fround<::tools::Long>( rPoint1.getX() ), + ::basegfx::fround<::tools::Long>( rPoint1.getY() ) ); const ::basegfx::B2DPoint& rPoint2( aLeftBottom - 2.0*nDiagonalLength*aDirection ); - aTempPoly[2] = ::Point( ::basegfx::fround( rPoint2.getX() ), - ::basegfx::fround( rPoint2.getY() ) ); + aTempPoly[2] = ::Point( ::basegfx::fround<::tools::Long>( rPoint2.getX() ), + ::basegfx::fround<::tools::Long>( rPoint2.getY() ) ); // iteratively render all other strips @@ -260,14 +258,14 @@ namespace vclcanvas const ::basegfx::B2DPoint& rPoint3( (nStepCount - i-1)/double(nStepCount)*aLeftTop + (i+1)/double(nStepCount)*aRightTop ); - aTempPoly[1] = ::Point( ::basegfx::fround( rPoint3.getX() ), - ::basegfx::fround( rPoint3.getY() ) ); + aTempPoly[1] = ::Point( ::basegfx::fround<::tools::Long>( rPoint3.getX() ), + ::basegfx::fround<::tools::Long>( rPoint3.getY() ) ); const ::basegfx::B2DPoint& rPoint4( (nStepCount - i-1)/double(nStepCount)*aLeftBottom + (i+1)/double(nStepCount)*aRightBottom ); - aTempPoly[2] = ::Point( ::basegfx::fround( rPoint4.getX() ), - ::basegfx::fround( rPoint4.getY() ) ); + aTempPoly[2] = ::Point( ::basegfx::fround<::tools::Long>( rPoint4.getX() ), + ::basegfx::fround<::tools::Long>( rPoint4.getY() ) ); rOutDev.DrawPolygon( aTempPoly ); } @@ -285,12 +283,12 @@ namespace vclcanvas // gradient rect two times the bound rect's diagonal to // the 'right'. const ::basegfx::B2DPoint& rPoint3( aRightTop + 2.0*nDiagonalLength*aDirection ); - aTempPoly[0] = aTempPoly[4] = ::Point( ::basegfx::fround( rPoint3.getX() ), - ::basegfx::fround( rPoint3.getY() ) ); + aTempPoly[0] = aTempPoly[4] = ::Point( ::basegfx::fround<::tools::Long>( rPoint3.getX() ), + ::basegfx::fround<::tools::Long>( rPoint3.getY() ) ); const ::basegfx::B2DPoint& rPoint4( aRightBottom + 2.0*nDiagonalLength*aDirection ); - aTempPoly[3] = ::Point( ::basegfx::fround( rPoint4.getX() ), - ::basegfx::fround( rPoint4.getY() ) ); + aTempPoly[3] = ::Point( ::basegfx::fround<::tools::Long>( rPoint4.getX() ), + ::basegfx::fround<::tools::Long>( rPoint4.getY() ) ); rOutDev.SetFillColor( rColors.back() ); @@ -420,8 +418,8 @@ namespace vclcanvas const ::basegfx::B2DPoint& rInnerPoint( aInnerPoly.getB2DPoint(p) ); aTempPoly[static_cast<sal_uInt16>(p)] = ::Point( - basegfx::fround( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ), - basegfx::fround( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) ); + basegfx::fround<::tools::Long>( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ), + basegfx::fround<::tools::Long>( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) ); } // close polygon explicitly @@ -526,7 +524,7 @@ namespace vclcanvas // poly-polygons, and don't have to output the gradient // twice for XOR - rOutDev.Push( PushFlags::CLIPREGION ); + rOutDev.Push( vcl::PushFlags::CLIPREGION ); rOutDev.IntersectClipRegion( aPolygonDeviceRectOrig ); doGradientFill( rOutDev, rValues, @@ -550,7 +548,7 @@ namespace vclcanvas { const vcl::Region aPolyClipRegion( rPoly ); - rOutDev.Push( PushFlags::CLIPREGION ); + rOutDev.Push( vcl::PushFlags::CLIPREGION ); rOutDev.IntersectClipRegion( aPolyClipRegion ); doGradientFill( rOutDev, @@ -798,7 +796,7 @@ namespace vclcanvas // degrees with the orientation reversed: [0,2Pi) -> // (3600,0]. Note that the original angle may have // values outside the [0,2Pi) interval. - const double nAngleInTenthOfDegrees (3600.0 - nRotate * 3600.0 / (2*M_PI)); + const double nAngleInTenthOfDegrees (3600.0 - basegfx::rad2deg<10>(nRotate)); aGrfAttr.SetRotation( Degree10(::basegfx::fround(nAngleInTenthOfDegrees)) ); pGrfObj = std::make_shared<GraphicObject>( aBmpEx ); @@ -900,15 +898,15 @@ namespace vclcanvas const ::Point aPtRepeat( vcl::unotools::pointFromB2DPoint( aSingleDeviceTextureRect.getMinimum() ) ); - const ::Size aSz( ::basegfx::fround( aScale.getX() * aBmpSize.Width ), - ::basegfx::fround( aScale.getY() * aBmpSize.Height ) ); + const ::Size aSz( ::basegfx::fround<::tools::Long>( aScale.getX() * aBmpSize.Width ), + ::basegfx::fround<::tools::Long>( aScale.getY() * aBmpSize.Height ) ); const ::Size aIntegerNextTileX( vcl::unotools::sizeFromB2DSize(aNextTileX) ); const ::Size aIntegerNextTileY( vcl::unotools::sizeFromB2DSize(aNextTileY) ); const ::Point aPt( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? - ::basegfx::fround( aOutputPos.getX() ) : aPtRepeat.X(), + ::basegfx::fround<::tools::Long>( aOutputPos.getX() ) : aPtRepeat.X(), textures[0].RepeatModeY == rendering::TexturingMode::NONE ? - ::basegfx::fround( aOutputPos.getY() ) : aPtRepeat.Y() ); + ::basegfx::fround<::tools::Long>( aOutputPos.getY() ) : aPtRepeat.Y() ); const sal_Int32 nTilesX( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? 1 : nX2 - nX1 ); const sal_Int32 nTilesY( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? @@ -1030,7 +1028,7 @@ namespace vclcanvas { const vcl::Region aPolyClipRegion( aPolyPoly ); - rOutDev.Push( PushFlags::CLIPREGION ); + rOutDev.Push( vcl::PushFlags::CLIPREGION ); rOutDev.IntersectClipRegion( aPolyClipRegion ); textureFill( rOutDev, @@ -1047,7 +1045,7 @@ namespace vclcanvas if( mp2ndOutDevProvider ) { OutputDevice& r2ndOutDev( mp2ndOutDevProvider->getOutDev() ); - r2ndOutDev.Push( PushFlags::CLIPREGION ); + r2ndOutDev.Push( vcl::PushFlags::CLIPREGION ); r2ndOutDev.IntersectClipRegion( aPolyClipRegion ); textureFill( r2ndOutDev, diff --git a/canvas/source/vcl/devicehelper.cxx b/canvas/source/vcl/devicehelper.cxx index b9d4138aade1..40d2575f8883 100644 --- a/canvas/source/vcl/devicehelper.cxx +++ b/canvas/source/vcl/devicehelper.cxx @@ -22,7 +22,6 @@ #include <basegfx/utils/canvastools.hxx> #include <basegfx/utils/unopolypolygon.hxx> #include <canvas/canvastools.hxx> -#include <rtl/instance.hxx> #include <tools/stream.hxx> #include <vcl/canvastools.hxx> #include <vcl/dibtools.hxx> @@ -34,8 +33,7 @@ using namespace ::com::sun::star; namespace vclcanvas { - DeviceHelper::DeviceHelper() : - mpOutDev() + DeviceHelper::DeviceHelper() {} void DeviceHelper::init( const OutDevProviderSharedPtr& rOutDev ) @@ -174,22 +172,23 @@ namespace vclcanvas namespace { - struct DeviceColorSpace: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, - DeviceColorSpace> + uno::Reference<rendering::XColorSpace>& GetDeviceColorSpace() { - uno::Reference<rendering::XColorSpace> operator()() + static uno::Reference<rendering::XColorSpace> xColorSpace = + []() { - uno::Reference< rendering::XColorSpace > xColorSpace = canvas::tools::getStdColorSpace(); - assert( xColorSpace.is() ); - return xColorSpace; - } + auto xTmp = canvas::tools::getStdColorSpace(); + assert( xTmp.is() ); + return xTmp; + }(); + return xColorSpace; }; } uno::Reference<rendering::XColorSpace> const & DeviceHelper::getColorSpace() const { // always the same - return DeviceColorSpace::get(); + return GetDeviceColorSpace(); } void DeviceHelper::dumpScreenContent() const diff --git a/canvas/source/vcl/impltools.cxx b/canvas/source/vcl/impltools.cxx index 800ad3128342..cafc59a9b83f 100644 --- a/canvas/source/vcl/impltools.cxx +++ b/canvas/source/vcl/impltools.cxx @@ -27,7 +27,7 @@ #include <basegfx/utils/canvastools.hxx> #include <basegfx/tuple/b2dtuple.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <sal/log.hxx> #include <vcl/bitmapex.hxx> #include <vcl/canvastools.hxx> @@ -73,7 +73,7 @@ namespace vclcanvas::tools xBitmap, uno::UNO_QUERY_THROW ); ::BitmapEx aBmpEx = vcl::unotools::bitmapExFromXBitmap( xIntBmp ); - if( !!aBmpEx ) + if( !aBmpEx.IsEmpty() ) return aBmpEx; // TODO(F1): extract pixel from XBitmap interface @@ -123,18 +123,45 @@ namespace vclcanvas::tools if( !::rtl::math::approxEqual(aScale.getY(), 1.0) ) { const sal_Int32 nFontHeight( io_rVCLFont.GetFontHeight() ); - io_rVCLFont.SetFontHeight( ::basegfx::fround(nFontHeight * aScale.getY()) ); + io_rVCLFont.SetFontHeight( ::basegfx::fround<::tools::Long>(nFontHeight * aScale.getY()) ); } - io_rVCLFont.SetOrientation( Degree10( ::basegfx::fround(-fmod(nRotate, 2*M_PI)*(1800.0/M_PI)) ) ); + io_rVCLFont.SetOrientation( Degree10( ::basegfx::fround(-basegfx::rad2deg<10>(fmod(nRotate, 2*M_PI))) ) ); // TODO(F2): Missing functionality in VCL: shearing - o_rPoint.setX( ::basegfx::fround(aTranslate.getX()) ); - o_rPoint.setY( ::basegfx::fround(aTranslate.getY()) ); + o_rPoint.setX( ::basegfx::fround<::tools::Long>(aTranslate.getX()) ); + o_rPoint.setY( ::basegfx::fround<::tools::Long>(aTranslate.getY()) ); return true; } + void setupFontWidth(const css::geometry::Matrix2D& rFontMatrix, + vcl::Font& rFont, + OutputDevice& rOutDev) + { + rFont.SetFontSize(Size(0, rFont.GetFontHeight())); + + if (!::rtl::math::approxEqual(rFontMatrix.m00, rFontMatrix.m11)) + { + const bool bOldMapState(rOutDev.IsMapModeEnabled()); + rOutDev.EnableMapMode(false); + + const Size aSize = rOutDev.GetFontMetric(rFont).GetFontSize(); + + const double fDividend(rFontMatrix.m10 + rFontMatrix.m11); + double fStretch = rFontMatrix.m00 + rFontMatrix.m01; + + if (!::basegfx::fTools::equalZero(fDividend)) + fStretch /= fDividend; + + const ::tools::Long nNewWidth = ::basegfx::fround<::tools::Long>(aSize.Width() * fStretch); + + rFont.SetAverageFontWidth(nNewWidth); + + rOutDev.EnableMapMode(bOldMapState); + } + } + bool isRectangle( const ::tools::PolyPolygon& rPolyPoly ) { // exclude some cheap cases first diff --git a/canvas/source/vcl/impltools.hxx b/canvas/source/vcl/impltools.hxx index f8a9db075227..030d5341b5b9 100644 --- a/canvas/source/vcl/impltools.hxx +++ b/canvas/source/vcl/impltools.hxx @@ -60,6 +60,7 @@ namespace com::sun::star::geometry struct RealPoint2D; struct RealSize2D; struct RealRectangle2D; + struct Matrix2D; } namespace com::sun::star::rendering @@ -88,6 +89,10 @@ namespace vclcanvas const css::rendering::RenderState& renderState, ::OutputDevice const & rOutDev ); + void setupFontWidth(const css::geometry::Matrix2D& rFontMatrix, + vcl::Font& rFont, + OutputDevice& rOutDev); + /** Predicate, to determine whether polygon is actually an axis-aligned rectangle @return true, if the polygon is a rectangle. diff --git a/canvas/source/vcl/outdevholder.hxx b/canvas/source/vcl/outdevholder.hxx new file mode 100644 index 000000000000..9679687c4329 --- /dev/null +++ b/canvas/source/vcl/outdevholder.hxx @@ -0,0 +1,50 @@ +/* -*- 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 <vcl/outdev.hxx> + +#include "outdevprovider.hxx" + +namespace vclcanvas +{ +class OutDevHolder : public OutDevProvider +{ +public: + OutDevHolder(const OutDevHolder&) = delete; + const OutDevHolder& operator=(const OutDevHolder&) = delete; + + explicit OutDevHolder(OutputDevice& rOutDev) + : mrOutDev(rOutDev) + { + } + +private: + virtual OutputDevice& getOutDev() override { return mrOutDev; } + virtual const OutputDevice& getOutDev() const override { return mrOutDev; } + + // TODO(Q2): Lifetime issue. This _only_ works reliably, + // if disposing the Canvas correctly disposes all + // entities which hold this pointer. + OutputDevice& mrOutDev; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/vcl/repainttarget.hxx b/canvas/source/vcl/repainttarget.hxx index b7b4058e9e9d..b8bac4ab9210 100644 --- a/canvas/source/vcl/repainttarget.hxx +++ b/canvas/source/vcl/repainttarget.hxx @@ -34,7 +34,7 @@ namespace vclcanvas This interface must be implemented on all canvas implementations that hand out XCachedPrimitives */ - class RepaintTarget + class SAL_LOPLUGIN_ANNOTATE("crosscast") RepaintTarget { public: virtual ~RepaintTarget() {} diff --git a/canvas/source/vcl/spritecanvas.cxx b/canvas/source/vcl/spritecanvas.cxx index bc3b2d9f290a..cbe0fa8dc791 100644 --- a/canvas/source/vcl/spritecanvas.cxx +++ b/canvas/source/vcl/spritecanvas.cxx @@ -21,10 +21,12 @@ #include <sal/log.hxx> #include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/lang/NoSupportException.hpp> #include <cppuhelper/supportsservice.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include "spritecanvas.hxx" +#include "outdevholder.hxx" #include "windowoutdevholder.hxx" @@ -75,14 +77,27 @@ namespace vclcanvas maArguments[3].getValueTypeClass() == uno::TypeClass_INTERFACE, "VCLSpriteCanvas::initialize: wrong number of arguments, or wrong types" ); + sal_Int64 nPtr = 0; + maArguments[0] >>= nPtr; + + OutputDevice* pOutDev = reinterpret_cast<OutputDevice*>(nPtr); + if( !pOutDev ) + throw lang::NoSupportException("Passed OutDev invalid!", nullptr); + uno::Reference< awt::XWindow > xParentWindow; maArguments[3] >>= xParentWindow; - OutDevProviderSharedPtr pOutDev = std::make_shared<WindowOutDevHolder>(xParentWindow); + OutDevProviderSharedPtr pOutDevProvider; + if( xParentWindow.is()) + pOutDevProvider = std::make_shared<WindowOutDevHolder>(xParentWindow); + else + pOutDevProvider = std::make_shared<OutDevHolder>(*pOutDev); // setup helper - maDeviceHelper.init( pOutDev ); - setWindow(uno::Reference<awt::XWindow2>(xParentWindow, uno::UNO_QUERY_THROW)); + maDeviceHelper.init( pOutDevProvider ); + setWindow( xParentWindow.is() + ? uno::Reference<awt::XWindow2>(xParentWindow, uno::UNO_QUERY_THROW) + : uno::Reference<awt::XWindow2>()); maCanvasHelper.init( maDeviceHelper.getBackBuffer(), *this, maRedrawManager, @@ -163,10 +178,9 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* com_sun_star_comp_rendering_SpriteCanvas_VCL_get_implementation( css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) { - auto p = new vclcanvas::SpriteCanvas(args, context); - cppu::acquire(p); + rtl::Reference<vclcanvas::SpriteCanvas> p = new vclcanvas::SpriteCanvas(args, context); p->initialize(); - return static_cast<cppu::OWeakObject*>(p); + return cppu::acquire(p.get()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/vcl/spritecanvashelper.cxx b/canvas/source/vcl/spritecanvashelper.cxx index 0c1a454c3260..37f70a364267 100644 --- a/canvas/source/vcl/spritecanvashelper.cxx +++ b/canvas/source/vcl/spritecanvashelper.cxx @@ -24,7 +24,7 @@ #include <basegfx/range/b2drectangle.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/canvastools.hxx> #include <vcl/outdev.hxx> #include <vcl/window.hxx> @@ -60,7 +60,7 @@ namespace vclcanvas double calcNumPixel( const ::canvas::Sprite::Reference& rSprite ) { - const ::basegfx::B2DSize& rSize( + const ::basegfx::B2DVector& rSize( ::boost::polymorphic_downcast< Sprite* >(rSprite.get())->getSizePixel() ); return rSize.getX() * rSize.getY(); @@ -120,7 +120,6 @@ namespace vclcanvas mpRedrawManager( nullptr ), mpOwningSpriteCanvas( nullptr ), maVDev(VclPtr<VirtualDevice>::Create()), - maLastUpdate(), mbShowFrameInfo( false ), mbShowSpriteBounds( false ), mbIsUnsafeScrolling( false ) @@ -220,7 +219,7 @@ namespace vclcanvas vcl::Window* pTargetWindow = nullptr; if( rOutDev.GetOutDevType() == OUTDEV_WINDOW ) { - pTargetWindow = &static_cast<vcl::Window&>(rOutDev); // TODO(Q3): Evil downcast. + pTargetWindow = rOutDev.GetOwnerWindow(); // TODO(Q3): Evil downcast. // we're double-buffered, thus no need for paint area-limiting // clips. besides that, will interfere with animations (as for @@ -309,7 +308,7 @@ namespace vclcanvas if( pTargetWindow ) { // commit to screen - pTargetWindow->Flush(); + pTargetWindow->GetOutDev()->Flush(); } return true; @@ -407,7 +406,7 @@ namespace vclcanvas // repaint uncovered areas from sprite. Need to actually // clip here, since we're only repainting _parts_ of the // sprite - rOutDev.Push( PushFlags::CLIPREGION ); + rOutDev.Push( vcl::PushFlags::CLIPREGION ); for( const auto& rArea : aUnscrollableAreas ) opaqueUpdateSpriteArea( aFirst->second.getSprite(), diff --git a/canvas/source/vcl/spritedevicehelper.cxx b/canvas/source/vcl/spritedevicehelper.cxx index 150e3fcb42af..99f8b19145ce 100644 --- a/canvas/source/vcl/spritedevicehelper.cxx +++ b/canvas/source/vcl/spritedevicehelper.cxx @@ -31,8 +31,7 @@ using namespace ::com::sun::star; namespace vclcanvas { - SpriteDeviceHelper::SpriteDeviceHelper() : - mpBackBuffer() + SpriteDeviceHelper::SpriteDeviceHelper() { } diff --git a/canvas/source/vcl/spritehelper.cxx b/canvas/source/vcl/spritehelper.cxx index 53116fa9d53d..7b3384c934e7 100644 --- a/canvas/source/vcl/spritehelper.cxx +++ b/canvas/source/vcl/spritehelper.cxx @@ -26,18 +26,14 @@ #include <basegfx/range/b2drectangle.hxx> #include <basegfx/utils/canvastools.hxx> #include <rtl/math.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <vcl/alpha.hxx> #include <vcl/bitmapex.hxx> #include <vcl/canvastools.hxx> #include <vcl/outdev.hxx> -#include <vcl/BitmapMonochromeFilter.hxx> -#include <vcl/skia/SkiaHelper.hxx> #include <canvas/canvastools.hxx> -#include <config_features.h> -#include "impltools.hxx" #include "spritehelper.hxx" using namespace ::com::sun::star; @@ -46,9 +42,6 @@ using namespace ::com::sun::star; namespace vclcanvas { SpriteHelper::SpriteHelper() : - mpBackBuffer(), - mpBackBufferMask(), - maContent(), mbShowSpriteBounds(false) { } @@ -81,10 +74,8 @@ namespace vclcanvas void SpriteHelper::redraw( OutputDevice& rTargetSurface, const ::basegfx::B2DPoint& rPos, bool& io_bSurfacesDirty, - bool bBufferedUpdate ) const + bool /*bBufferedUpdate*/ ) const { - (void)bBufferedUpdate; // not used on every platform - if( !mpBackBuffer || !mpBackBufferMask ) { @@ -143,100 +134,20 @@ namespace vclcanvas // sprite content might contain alpha, create // BmpEx, then. BitmapEx aMask( mpBackBufferMask->getOutDev().GetBitmapEx( aEmptyPoint, - aOutputSize ) ); - - // bitmasks are much faster than alphamasks on some platforms - // so convert to bitmask if useful - bool convertTo1Bpp = aMask.GetBitCount() != 1; -#ifdef MACOSX - convertTo1Bpp = false; -#endif - if( SkiaHelper::isVCLSkiaEnabled()) - convertTo1Bpp = false; - - if( convertTo1Bpp ) - { - OSL_FAIL("CanvasCustomSprite::redraw(): Mask bitmap is not " - "monochrome (performance!)"); - BitmapEx aMaskEx(aMask); - BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(255)); - aMask = aMaskEx.GetBitmap(); - } + aOutputSize ) ); + AlphaMask aAlpha( aMask.GetBitmap() ); + aAlpha.Invert(); // Note: since we retrieved aBmp and aMask // directly from an OutDev, it's already a // 'display bitmap' on windows. - if( aMask.GetBitCount() == 1 ) - maContent = BitmapEx( aBmp.GetBitmap(), aMask.GetBitmap() ); - else - maContent = BitmapEx( aBmp.GetBitmap(), AlphaMask( aMask.GetBitmap()) ); + maContent = BitmapEx( aBmp.GetBitmap(), aAlpha ); } } ::basegfx::B2DHomMatrix aTransform( getTransformation() ); - // check whether matrix is "easy" to handle - pure - // translations or scales are handled by OutputDevice - // alone - const bool bIdentityTransform( aTransform.isIdentity() ); - - // make transformation absolute (put sprite to final - // output position). Need to happen here, as we also have - // to translate the clip polygon - aTransform.translate( aOutPos.X(), - aOutPos.Y() ); - - if( !bIdentityTransform ) - { - if (!::basegfx::fTools::equalZero( aTransform.get(0,1) ) || - !::basegfx::fTools::equalZero( aTransform.get(1,0) )) - { - // "complex" transformation, employ affine - // transformator - - // modify output position, to account for the fact - // that transformBitmap() always normalizes its output - // bitmap into the smallest enclosing box. - ::basegfx::B2DRectangle aDestRect; - ::canvas::tools::calcTransformedRectBounds( aDestRect, - ::basegfx::B2DRectangle(0, - 0, - rOrigOutputSize.getX(), - rOrigOutputSize.getY()), - aTransform ); - - aOutPos.setX( ::basegfx::fround( aDestRect.getMinX() ) ); - aOutPos.setY( ::basegfx::fround( aDestRect.getMinY() ) ); - - // TODO(P3): Use optimized bitmap transformation here. - - // actually re-create the bitmap ONLY if necessary - if( bNeedBitmapUpdate ) - maContent = tools::transformBitmap( *maContent, - aTransform ); - - aOutputSize = maContent->GetSizePixel(); - } - else - { - // relatively 'simplistic' transformation - - // retrieve scale and translational offset - aOutputSize.setWidth ( - ::basegfx::fround( rOrigOutputSize.getX() * aTransform.get(0,0) ) ); - aOutputSize.setHeight( - ::basegfx::fround( rOrigOutputSize.getY() * aTransform.get(1,1) ) ); - - aOutPos.setX( ::basegfx::fround( aTransform.get(0,2) ) ); - aOutPos.setY( ::basegfx::fround( aTransform.get(1,2) ) ); - } - } - - // transformBitmap() might return empty bitmaps, for tiny - // scales. - if( !(*maContent) ) - return; - - rTargetSurface.Push( PushFlags::CLIPREGION ); + rTargetSurface.Push( vcl::PushFlags::CLIPREGION ); // apply clip (if any) if( getClip().is() ) @@ -247,15 +158,15 @@ namespace vclcanvas if( aClipPoly.count() ) { - // aTransform already contains the - // translational component, moving the clip to - // the final sprite output position. - aClipPoly.transform( aTransform ); + // Move the clip to the final sprite output position. + ::basegfx::B2DHomMatrix aClipTransform( aTransform ); + aClipTransform.translate( aOutPos.X(), aOutPos.Y() ); + aClipPoly.transform( aClipTransform ); if( mbShowSpriteBounds ) { // Paint green sprite clip area - rTargetSurface.SetLineColor( Color( 0,255,0 ) ); + rTargetSurface.SetLineColor( COL_LIGHTGREEN ); rTargetSurface.SetFillColor(); rTargetSurface.DrawPolyPolygon(::tools::PolyPolygon(aClipPoly)); // #i76339# @@ -266,33 +177,12 @@ namespace vclcanvas } } - if( ::rtl::math::approxEqual(fAlpha, 1.0) ) - { - // no alpha modulation -> just copy to output - if( maContent->IsTransparent() ) - rTargetSurface.DrawBitmapEx( aOutPos, aOutputSize, *maContent ); - else - rTargetSurface.DrawBitmap( aOutPos, aOutputSize, maContent->GetBitmap() ); - } - else - { - // TODO(P3): Switch to OutputDevice::DrawTransparent() - // here - - // draw semi-transparent - sal_uInt8 nColor( static_cast<sal_uInt8>( ::basegfx::fround( 255.0*(1.0 - fAlpha) + .5) ) ); - AlphaMask aAlpha( maContent->GetSizePixel(), - &nColor ); - - // mask out fully transparent areas - if( maContent->IsTransparent() ) - aAlpha.Replace( maContent->GetMask(), 255 ); - - // alpha-blend to output - rTargetSurface.DrawBitmapEx( aOutPos, aOutputSize, - BitmapEx( maContent->GetBitmap(), - aAlpha ) ); - } + ::basegfx::B2DHomMatrix aSizeTransform, aMoveTransform; + aSizeTransform.scale( aOutputSize.Width(), aOutputSize.Height() ); + aMoveTransform.translate( aOutPos.X(), aOutPos.Y() ); + aTransform = aMoveTransform * aTransform * aSizeTransform; + + rTargetSurface.DrawTransformedBitmapEx( aTransform, *maContent, fAlpha ); rTargetSurface.Pop(); diff --git a/canvas/source/vcl/textlayout.cxx b/canvas/source/vcl/textlayout.cxx index 2a0e1fec1a70..23c450e66149 100644 --- a/canvas/source/vcl/textlayout.cxx +++ b/canvas/source/vcl/textlayout.cxx @@ -20,8 +20,7 @@ #include <sal/config.h> -#include <tools/diagnose_ex.h> -#include <tools/long.hxx> +#include <comphelper/diagnose_ex.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/numeric/ftools.hxx> #include <basegfx/utils/canvastools.hxx> @@ -31,6 +30,8 @@ #include <com/sun/star/rendering/ViewState.hpp> #include <comphelper/sequence.hxx> #include <cppuhelper/supportsservice.hxx> +#include <utility> +#include <vcl/kernarray.hxx> #include <vcl/metric.hxx> #include <vcl/virdev.hxx> @@ -50,19 +51,19 @@ namespace vclcanvas sal_Int8 nTextDirection ) { // TODO(P3): avoid if already correctly set - ComplexTextLayoutFlags nLayoutMode = ComplexTextLayoutFlags::Default; + vcl::text::ComplexTextLayoutFlags nLayoutMode = vcl::text::ComplexTextLayoutFlags::Default; switch( nTextDirection ) { case rendering::TextDirection::WEAK_LEFT_TO_RIGHT: break; case rendering::TextDirection::STRONG_LEFT_TO_RIGHT: - nLayoutMode = ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode = vcl::text::ComplexTextLayoutFlags::BiDiStrong; break; case rendering::TextDirection::WEAK_RIGHT_TO_LEFT: - nLayoutMode = ComplexTextLayoutFlags::BiDiRtl; + nLayoutMode = vcl::text::ComplexTextLayoutFlags::BiDiRtl; break; case rendering::TextDirection::STRONG_RIGHT_TO_LEFT: - nLayoutMode = ComplexTextLayoutFlags::BiDiRtl | ComplexTextLayoutFlags::BiDiStrong; + nLayoutMode = vcl::text::ComplexTextLayoutFlags::BiDiRtl | vcl::text::ComplexTextLayoutFlags::BiDiStrong; break; default: break; @@ -70,31 +71,32 @@ namespace vclcanvas // set calculated layout mode. Origin is always the left edge, // as required at the API spec - rOutDev.SetLayoutMode( nLayoutMode | ComplexTextLayoutFlags::TextOriginLeft ); + rOutDev.SetLayoutMode( nLayoutMode | vcl::text::ComplexTextLayoutFlags::TextOriginLeft ); } } - TextLayout::TextLayout( const rendering::StringContext& aText, - sal_Int8 nDirection, - const CanvasFont::Reference& rFont, - const uno::Reference<rendering::XGraphicDevice>& xDevice, - const OutDevProviderSharedPtr& rOutDev ) : - TextLayout_Base( m_aMutex ), - maText( aText ), - maLogicalAdvancements(), - mpFont( rFont ), - mxDevice( xDevice ), - mpOutDevProvider( rOutDev ), + TextLayout::TextLayout( rendering::StringContext aText, + sal_Int8 nDirection, + CanvasFont::Reference rFont, + uno::Reference<rendering::XGraphicDevice> xDevice, + OutDevProviderSharedPtr xOutDev ) : + maText(std::move( aText )), + mpFont(std::move( rFont )), + mxDevice(std::move( xDevice )), + mpOutDevProvider(std::move( xOutDev )), mnTextDirection( nDirection ) {} - void SAL_CALL TextLayout::disposing() + void TextLayout::disposing(std::unique_lock<std::mutex>& rGuard) { - SolarMutexGuard aGuard; - - mpOutDevProvider.reset(); - mxDevice.clear(); - mpFont.clear(); + rGuard.unlock(); + { + SolarMutexGuard aGuard; + mpOutDevProvider.reset(); + mxDevice.clear(); + mpFont.clear(); + } + rGuard.lock(); } // XTextLayout @@ -118,8 +120,8 @@ namespace vclcanvas uno::Sequence<double>(4), rendering::CompositeOperation::SOURCE); - std::unique_ptr< ::tools::Long []> aOffsets(new ::tools::Long[maLogicalAdvancements.getLength()]); - setupTextOffsets(aOffsets.get(), maLogicalAdvancements, aViewState, aRenderState); + KernArray aOffsets(setupTextOffsets(maLogicalAdvancements, aViewState, aRenderState)); + std::span<const sal_Bool> aKashidaArray(maKashidaPositions.getArray(), maKashidaPositions.getLength()); std::vector< uno::Reference< rendering::XPolyPolygon2D> > aOutlineSequence; ::basegfx::B2DPolyPolygonVector aOutlines; @@ -130,7 +132,8 @@ namespace vclcanvas maText.StartPosition, maText.Length, 0, - aOffsets.get())) + aOffsets, + aKashidaArray)) { aOutlineSequence.reserve(aOutlines.size()); sal_Int32 nIndex (0); @@ -166,10 +169,9 @@ namespace vclcanvas uno::Sequence<double>(4), rendering::CompositeOperation::SOURCE); - std::unique_ptr< ::tools::Long []> aOffsets(new ::tools::Long[maLogicalAdvancements.getLength()]); - setupTextOffsets(aOffsets.get(), maLogicalAdvancements, aViewState, aRenderState); + KernArray aOffsets(setupTextOffsets(maLogicalAdvancements, aViewState, aRenderState)); - MetricVector aMetricVector; + std::vector< ::tools::Rectangle > aMetricVector; uno::Sequence<geometry::RealRectangle2D> aBoundingBoxes; if (pVDev->GetGlyphBoundRects( Point(0,0), @@ -179,14 +181,15 @@ namespace vclcanvas aMetricVector)) { aBoundingBoxes.realloc(aMetricVector.size()); + auto pBoundingBoxes = aBoundingBoxes.getArray(); sal_Int32 nIndex (0); for (auto const& metric : aMetricVector) { - aBoundingBoxes[nIndex++] = geometry::RealRectangle2D( - metric.getX(), - metric.getY(), - metric.getX() + metric.getWidth(), - metric.getY() + metric.getHeight()); + pBoundingBoxes[nIndex++] = geometry::RealRectangle2D( + metric.Left(), + metric.Top(), + metric.Right(), + metric.Bottom()); } } return aBoundingBoxes; @@ -215,6 +218,23 @@ namespace vclcanvas maLogicalAdvancements = aAdvancements; } + uno::Sequence< sal_Bool > SAL_CALL TextLayout::queryKashidaPositions( ) + { + SolarMutexGuard aGuard; + + return maKashidaPositions; + } + + void SAL_CALL TextLayout::applyKashidaPositions( const uno::Sequence< sal_Bool >& aPositions ) + { + SolarMutexGuard aGuard; + + ENSURE_ARG_OR_THROW( !aPositions.hasElements() || aPositions.getLength() == maText.Length, + "TextLayout::applyKashidaPositions(): mismatching number of positions" ); + + maKashidaPositions = aPositions; + } + geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds( ) { SolarMutexGuard aGuard; @@ -304,8 +324,6 @@ namespace vclcanvas sal_Int8 SAL_CALL TextLayout::getMainTextDirection( ) { - SolarMutexGuard aGuard; - return mnTextDirection; } @@ -313,13 +331,11 @@ namespace vclcanvas { SolarMutexGuard aGuard; - return mpFont.get(); + return mpFont; } rendering::StringContext SAL_CALL TextLayout::getText( ) { - SolarMutexGuard aGuard; - return maText; } @@ -330,20 +346,29 @@ namespace vclcanvas { SolarMutexGuard aGuard; +#ifdef _WIN32 + // tdf#147999 + // On Windows we get the wrong font width for fallback fonts unless we setup again here. + vcl::Font aFont(rOutDev.GetFont()); + tools::setupFontWidth(mpFont->getFontMatrix(), aFont, rOutDev); + rOutDev.SetFont(aFont); +#endif + setupLayoutMode( rOutDev, mnTextDirection ); if( maLogicalAdvancements.hasElements() ) { // TODO(P2): cache that - std::unique_ptr< ::tools::Long []> aOffsets(new ::tools::Long[maLogicalAdvancements.getLength()]); - setupTextOffsets( aOffsets.get(), maLogicalAdvancements, viewState, renderState ); + KernArray aOffsets(setupTextOffsets(maLogicalAdvancements, viewState, renderState)); + std::span<const sal_Bool> aKashidaArray(maKashidaPositions.getConstArray(), maKashidaPositions.getLength()); // TODO(F3): ensure correct length and termination for DX // array (last entry _must_ contain the overall width) rOutDev.DrawTextArray( rOutpos, maText.Text, - aOffsets.get(), + aOffsets, + aKashidaArray, ::canvas::tools::numeric_cast<sal_uInt16>(maText.StartPosition), ::canvas::tools::numeric_cast<sal_uInt16>(maText.Length) ); } @@ -361,8 +386,8 @@ namespace vclcanvas class OffsetTransformer { public: - explicit OffsetTransformer( const ::basegfx::B2DHomMatrix& rMat ) : - maMatrix( rMat ) + explicit OffsetTransformer( ::basegfx::B2DHomMatrix aMat ) : + maMatrix(std::move( aMat )) { } @@ -388,14 +413,11 @@ namespace vclcanvas }; } - void TextLayout::setupTextOffsets( ::tools::Long* outputOffsets, + KernArray TextLayout::setupTextOffsets( const uno::Sequence< double >& inputOffsets, const rendering::ViewState& viewState, const rendering::RenderState& renderState ) const { - ENSURE_OR_THROW( outputOffsets!=nullptr, - "TextLayout::setupTextOffsets offsets NULL" ); - ::basegfx::B2DHomMatrix aMatrix; ::canvas::tools::mergeViewAndRenderTransform(aMatrix, @@ -403,15 +425,16 @@ namespace vclcanvas renderState); // fill integer offsets - std::transform( inputOffsets.begin(), - inputOffsets.end(), - outputOffsets, - OffsetTransformer( aMatrix ) ); + KernArray outputOffsets; + OffsetTransformer aTransform(aMatrix); + std::for_each(inputOffsets.begin(), inputOffsets.end(), + [&outputOffsets, &aTransform](double n) {outputOffsets.push_back(aTransform(n)); } ); + return outputOffsets; } OUString SAL_CALL TextLayout::getImplementationName() { - return "VCLCanvas::TextLayout"; + return u"VCLCanvas::TextLayout"_ustr; } sal_Bool SAL_CALL TextLayout::supportsService( const OUString& ServiceName ) @@ -421,7 +444,7 @@ namespace vclcanvas uno::Sequence< OUString > SAL_CALL TextLayout::getSupportedServiceNames() { - return { "com.sun.star.rendering.TextLayout" }; + return { u"com.sun.star.rendering.TextLayout"_ustr }; } } diff --git a/canvas/source/vcl/textlayout.hxx b/canvas/source/vcl/textlayout.hxx index 43853740588b..998383cb029b 100644 --- a/canvas/source/vcl/textlayout.hxx +++ b/canvas/source/vcl/textlayout.hxx @@ -19,8 +19,7 @@ #pragma once -#include <cppuhelper/compbase.hxx> -#include <cppuhelper/basemutex.hxx> +#include <comphelper/compbase.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/rendering/StringContext.hpp> @@ -29,31 +28,29 @@ #include "canvasfont.hxx" #include "impltools.hxx" - /* Definition of TextLayout class */ namespace vclcanvas { - typedef ::cppu::WeakComponentImplHelper< css::rendering::XTextLayout, + typedef ::comphelper::WeakComponentImplHelper< css::rendering::XTextLayout, css::lang::XServiceInfo > TextLayout_Base; - class TextLayout : public ::cppu::BaseMutex, - public TextLayout_Base + class TextLayout : public TextLayout_Base { public: /// make noncopyable TextLayout(const TextLayout&) = delete; const TextLayout& operator=(const TextLayout&) = delete; - TextLayout( const css::rendering::StringContext& aText, - sal_Int8 nDirection, - const CanvasFont::Reference& rFont, - const css::uno::Reference< - css::rendering::XGraphicDevice>& xDevice, - const OutDevProviderSharedPtr& rOutDev ); + TextLayout( css::rendering::StringContext aText, + sal_Int8 nDirection, + CanvasFont::Reference rFont, + css::uno::Reference< + css::rendering::XGraphicDevice> xDevice, + OutDevProviderSharedPtr xOutDev ); /// Dispose all internal references - virtual void SAL_CALL disposing() override; + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; // XTextLayout virtual css::uno::Sequence< css::uno::Reference< css::rendering::XPolyPolygon2D > > SAL_CALL queryTextShapes( ) override; @@ -61,6 +58,8 @@ namespace vclcanvas virtual css::uno::Sequence< css::geometry::RealRectangle2D > SAL_CALL queryMeasures( ) override; virtual css::uno::Sequence< double > SAL_CALL queryLogicalAdvancements( ) override; virtual void SAL_CALL applyLogicalAdvancements( const css::uno::Sequence< double >& aAdvancements ) override; + virtual css::uno::Sequence< sal_Bool > SAL_CALL queryKashidaPositions( ) override; + virtual void SAL_CALL applyKashidaPositions( const css::uno::Sequence< sal_Bool >& aPositions ) override; virtual css::geometry::RealRectangle2D SAL_CALL queryTextBounds( ) override; virtual double SAL_CALL justify( double nSize ) override; virtual double SAL_CALL combinedJustify( const css::uno::Sequence< css::uno::Reference< css::rendering::XTextLayout > >& aNextLayouts, double nSize ) override; @@ -85,13 +84,14 @@ namespace vclcanvas const css::rendering::RenderState& renderState ) const; private: - void setupTextOffsets( ::tools::Long* outputOffsets, + KernArray setupTextOffsets( const css::uno::Sequence< double >& inputOffsets, const css::rendering::ViewState& viewState, const css::rendering::RenderState& renderState ) const; css::rendering::StringContext maText; css::uno::Sequence< double > maLogicalAdvancements; + css::uno::Sequence< sal_Bool > maKashidaPositions; CanvasFont::Reference mpFont; css::uno::Reference< css::rendering::XGraphicDevice> mxDevice; OutDevProviderSharedPtr mpOutDevProvider; diff --git a/canvas/source/vcl/windowoutdevholder.hxx b/canvas/source/vcl/windowoutdevholder.hxx index d9d69e9a37c9..87138a8a9106 100644 --- a/canvas/source/vcl/windowoutdevholder.hxx +++ b/canvas/source/vcl/windowoutdevholder.hxx @@ -36,8 +36,8 @@ namespace vclcanvas explicit WindowOutDevHolder( const css::uno::Reference< css::awt::XWindow>& xWin ); private: - virtual OutputDevice& getOutDev() override { return mrOutputWindow; } - virtual const OutputDevice& getOutDev() const override { return mrOutputWindow; } + virtual OutputDevice& getOutDev() override { return *mrOutputWindow.GetOutDev(); } + virtual const OutputDevice& getOutDev() const override { return *mrOutputWindow.GetOutDev(); } // TODO(Q2): Lifetime issue. Though WindowGraphicDeviceBase // now listens to the window component, I still consider |