diff options
Diffstat (limited to 'vcl/unx')
-rw-r--r-- | vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx | 185 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx | 97 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.cxx | 32 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.hxx | 2 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi.cxx | 339 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salvd.cxx | 6 |
6 files changed, 358 insertions, 303 deletions
diff --git a/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx new file mode 100644 index 000000000000..2109e19b9660 --- /dev/null +++ b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx @@ -0,0 +1,185 @@ +/* -*- 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 . + */ + +#include "X11CairoSalGraphicsImpl.hxx" + +#if ENABLE_CAIRO_CANVAS + +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/curve/b2dcubicbezier.hxx> + +X11CairoSalGraphicsImpl::X11CairoSalGraphicsImpl(X11SalGraphics& rParent, X11Common& rX11Common) + : X11SalGraphicsImpl(rParent) + , mrX11Common(rX11Common) + , mnPenColor(SALCOLOR_NONE) + , mnFillColor(SALCOLOR_NONE) +{ +} + +bool X11CairoSalGraphicsImpl::drawPolyPolygon(const basegfx::B2DHomMatrix& rObjectToDevice, + const basegfx::B2DPolyPolygon& rPolyPolygon, + double fTransparency) +{ + if (fTransparency >= 1.0) + { + return true; + } + + if (rPolyPolygon.count() == 0) + { + return true; + } + + // Fallback: Transform to DeviceCoordinates + basegfx::B2DPolyPolygon aPolyPolygon(rPolyPolygon); + aPolyPolygon.transform(rObjectToDevice); + + if (SALCOLOR_NONE == mnFillColor && SALCOLOR_NONE == mnPenColor) + { + return true; + } + + // enable by setting to something + static const char* pUseCairoForPolygons(getenv("SAL_ENABLE_USE_CAIRO_FOR_POLYGONS")); + + if (nullptr != pUseCairoForPolygons && mrX11Common.SupportsCairo()) + { + // snap to raster if requested + const bool bSnapPoints(!getAntiAlias()); + + if (bSnapPoints) + { + aPolyPolygon = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aPolyPolygon); + } + + cairo_t* cr = mrX11Common.getCairoContext(); + clipRegion(cr); + + for (auto const& rPolygon : std::as_const(aPolyPolygon)) + { + const sal_uInt32 nPointCount(rPolygon.count()); + + if (nPointCount) + { + const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nPointCount : nPointCount - 1); + + if (nEdgeCount) + { + basegfx::B2DCubicBezier aEdge; + + for (sal_uInt32 b = 0; b < nEdgeCount; ++b) + { + rPolygon.getBezierSegment(b, aEdge); + + if (!b) + { + const basegfx::B2DPoint aStart(aEdge.getStartPoint()); + cairo_move_to(cr, aStart.getX(), aStart.getY()); + } + + const basegfx::B2DPoint aEnd(aEdge.getEndPoint()); + + if (aEdge.isBezier()) + { + const basegfx::B2DPoint aCP1(aEdge.getControlPointA()); + const basegfx::B2DPoint aCP2(aEdge.getControlPointB()); + cairo_curve_to(cr, aCP1.getX(), aCP1.getY(), aCP2.getX(), aCP2.getY(), + aEnd.getX(), aEnd.getY()); + } + else + { + cairo_line_to(cr, aEnd.getX(), aEnd.getY()); + } + } + + cairo_close_path(cr); + } + } + } + + if (SALCOLOR_NONE != mnFillColor) + { + cairo_set_source_rgba(cr, mnFillColor.GetRed() / 255.0, mnFillColor.GetGreen() / 255.0, + mnFillColor.GetBlue() / 255.0, 1.0 - fTransparency); + cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_fill_preserve(cr); + } + + if (SALCOLOR_NONE != mnPenColor) + { + cairo_set_source_rgba(cr, mnPenColor.GetRed() / 255.0, mnPenColor.GetGreen() / 255.0, + mnPenColor.GetBlue() / 255.0, 1.0 - fTransparency); + cairo_stroke_preserve(cr); + } + + X11Common::releaseCairoContext(cr); + return true; + } + + return X11SalGraphicsImpl::drawPolyPolygon(rObjectToDevice, rPolyPolygon, fTransparency); +} + +bool X11CairoSalGraphicsImpl::drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDevice, + const basegfx::B2DPolygon& rPolygon, + double fTransparency, double fLineWidth, + const std::vector<double>* pStroke, + basegfx::B2DLineJoin eLineJoin, + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle, bool bPixelSnapHairline) +{ + if (0 == rPolygon.count()) + { + return true; + } + + if (fTransparency >= 1.0) + { + return true; + } + + // disable by setting to something + static const char* pUseCairoForFatLines(getenv("SAL_DISABLE_USE_CAIRO_FOR_FATLINES")); + + if (nullptr == pUseCairoForFatLines && mrX11Common.SupportsCairo()) + { + cairo_t* cr = mrX11Common.getCairoContext(); + clipRegion(cr); + + // Use the now available static drawPolyLine from the Cairo-Headless-Fallback + // that will take care of all needed stuff + const bool bRetval(CairoCommon::drawPolyLine( + cr, nullptr, mnPenColor, getAntiAlias(), rObjectToDevice, rPolygon, fTransparency, + fLineWidth, pStroke, eLineJoin, eLineCap, fMiterMinimumAngle, bPixelSnapHairline)); + + X11Common::releaseCairoContext(cr); + + if (bRetval) + { + return true; + } + } + + return X11SalGraphicsImpl::drawPolyLine(rObjectToDevice, rPolygon, fTransparency, fLineWidth, + pStroke, eLineJoin, eLineCap, fMiterMinimumAngle, + bPixelSnapHairline); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx new file mode 100644 index 000000000000..beb07e3ffc30 --- /dev/null +++ b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx @@ -0,0 +1,97 @@ +/* -*- 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 . + */ + +#include <config_features.h> +#include <config_cairo_canvas.h> + +#if ENABLE_CAIRO_CANVAS + +#include <cairo-xlib.h> +#include <unx/salgdi.h> +#include "gdiimpl.hxx" +#include "cairo_xlib_cairo.hxx" + +#include <headless/CairoCommon.hxx> + +class X11CairoSalGraphicsImpl : public X11SalGraphicsImpl +{ +private: + X11Common& mrX11Common; + vcl::Region maClipRegion; + Color mnPenColor; + Color mnFillColor; + + using X11SalGraphicsImpl::drawPolyPolygon; + using X11SalGraphicsImpl::drawPolyLine; + +public: + X11CairoSalGraphicsImpl(X11SalGraphics& rParent, X11Common& rX11Common); + + void ResetClipRegion() override + { + maClipRegion.SetNull(); + X11SalGraphicsImpl::ResetClipRegion(); + } + + bool setClipRegion(const vcl::Region& i_rClip) override + { + maClipRegion = i_rClip; + return X11SalGraphicsImpl::setClipRegion(i_rClip); + } + + void SetLineColor() override + { + mnPenColor = SALCOLOR_NONE; + X11SalGraphicsImpl::SetLineColor(); + } + + void SetLineColor(Color nColor) override + { + mnPenColor = nColor; + X11SalGraphicsImpl::SetLineColor(nColor); + } + + void SetFillColor() override + { + mnFillColor = SALCOLOR_NONE; + X11SalGraphicsImpl::SetFillColor(); + } + + void SetFillColor(Color nColor) override + { + mnFillColor = nColor; + X11SalGraphicsImpl::SetFillColor(nColor); + } + + void clipRegion(cairo_t* cr) { CairoCommon::clipRegion(cr, maClipRegion); } + + bool drawPolyPolygon(const basegfx::B2DHomMatrix& rObjectToDevice, + const basegfx::B2DPolyPolygon& rPolyPolygon, + double fTransparency) override; + + bool drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDevice, + const basegfx::B2DPolygon& rPolygon, double fTransparency, double fLineWidth, + const std::vector<double>* pStroke, basegfx::B2DLineJoin eLineJoin, + css::drawing::LineCap eLineCap, double fMiterMinimumAngle, + bool bPixelSnapHairline) override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index 53226821b4a1..d5fc4d6c1dc7 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -167,7 +167,7 @@ XID X11SalGraphicsImpl::GetXRenderPicture() if( !pXRenderFormat ) return 0; // get the matching xrender target for drawable - mrParent.m_aXRenderPicture = rRenderPeer.CreatePicture( mrParent.hDrawable_, pXRenderFormat, 0, nullptr ); + mrParent.m_aXRenderPicture = rRenderPeer.CreatePicture( mrParent.GetDrawable(), pXRenderFormat, 0, nullptr ); } { @@ -211,8 +211,8 @@ GC X11SalGraphicsImpl::CreateGC( Drawable hDrawable, unsigned long nMask ) XGCValues values; values.graphics_exposures = False; - values.foreground = mrParent.m_pColormap->GetBlackPixel() - ^ mrParent.m_pColormap->GetWhitePixel(); + values.foreground = mrParent.GetColormap().GetBlackPixel() + ^ mrParent.GetColormap().GetWhitePixel(); values.function = GXxor; values.line_width = 1; values.fill_style = FillStippled; @@ -244,8 +244,8 @@ GC X11SalGraphicsImpl::GetTrackingGC() XGCValues values; values.graphics_exposures = False; - values.foreground = mrParent.m_pColormap->GetBlackPixel() - ^ mrParent.m_pColormap->GetWhitePixel(); + values.foreground = mrParent.GetColormap().GetBlackPixel() + ^ mrParent.GetColormap().GetWhitePixel(); values.function = GXxor; values.line_width = 1; values.line_style = LineOnOffDash; @@ -291,8 +291,8 @@ GC X11SalGraphicsImpl::GetInvert50GC() XGCValues values; values.graphics_exposures = False; - values.foreground = mrParent.m_pColormap->GetWhitePixel(); - values.background = mrParent.m_pColormap->GetBlackPixel(); + values.foreground = mrParent.GetColormap().GetWhitePixel(); + values.background = mrParent.GetColormap().GetBlackPixel(); values.function = GXinvert; values.line_width = 1; values.line_style = LineSolid; @@ -353,7 +353,7 @@ GC X11SalGraphicsImpl::SelectBrush() values.fill_rule = EvenOddRule; // Pict import/ Gradient values.graphics_exposures = False; - mpBrushGC = XCreateGC( pDisplay, mrParent.hDrawable_, + mpBrushGC = XCreateGC( pDisplay, mrParent.GetDrawable(), GCSubwindowMode | GCFillRule | GCGraphicsExposures, &values ); } @@ -390,7 +390,7 @@ GC X11SalGraphicsImpl::SelectPen() values.fill_rule = EvenOddRule; // Pict import/ Gradient values.graphics_exposures = False; - mpPenGC = XCreateGC( pDisplay, mrParent.hDrawable_, + mpPenGC = XCreateGC( pDisplay, mrParent.GetDrawable(), GCSubwindowMode | GCFillRule | GCGraphicsExposures, &values ); } @@ -742,7 +742,7 @@ bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR, // create source Picture int nDepth = mrParent.m_pVDev ? static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() : rSalVis.GetDepth(); const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap ); - ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( mrParent.hDrawable_, mrParent.m_nXScreen, nDepth, rTR ); + ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( mrParent.GetDrawable(), mrParent.m_nXScreen, nDepth, rTR ); if( !pSrcDDB ) return false; @@ -804,7 +804,7 @@ bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR, pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight, pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize ); - Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_, + Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, mrParent.GetDrawable(), rTR.mnDestWidth, rTR.mnDestHeight, 8 ); XGCValues aAlphaGCV; @@ -1184,10 +1184,10 @@ void X11SalGraphicsImpl::drawRect( tools::Long nX, tools::Long nY, tools::Long n void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const Point *pPtAry ) { - drawPolyLine( nPoints, pPtAry, false ); + internalDrawPolyLine( nPoints, pPtAry, false ); } -void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const Point *pPtAry, bool bClose ) +void X11SalGraphicsImpl::internalDrawPolyLine( sal_uInt32 nPoints, const Point *pPtAry, bool bClose ) { if( mnPenColor != SALCOLOR_NONE ) { @@ -1307,7 +1307,7 @@ void X11SalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, if( mnPenColor != SALCOLOR_NONE ) for( sal_uInt32 i = 0; i < nPoly; i++ ) - drawPolyLine( pPoints[i], pPtAry[i], true ); + internalDrawPolyLine( pPoints[i], pPtAry[i], true ); } bool X11SalGraphicsImpl::drawPolyLineBezier( sal_uInt32, const Point*, const PolyFlags* ) @@ -1486,7 +1486,7 @@ bool X11SalGraphicsImpl::drawFilledTrapezoids( const basegfx::B2DTrapezoid* pB2D { Display* pXDisplay = mrParent.GetXDisplay(); - rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_, 1, 1, 32 ); + rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, mrParent.GetDrawable(), 1, 1, 32 ); XRenderPictureAttributes aAttr; aAttr.repeat = int(true); @@ -1558,7 +1558,7 @@ bool X11SalGraphicsImpl::drawFilledTriangles( { Display* pXDisplay = mrParent.GetXDisplay(); - rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_, 1, 1, 32 ); + rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, mrParent.GetDrawable(), 1, 1, 32 ); XRenderPictureAttributes aAttr; aAttr.repeat = int(true); diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index 6257b47d613d..48211b13d472 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -101,7 +101,7 @@ private: const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - void drawPolyLine( sal_uInt32 nPoints, const Point* pPtAry, bool bClose ); + void internalDrawPolyLine( sal_uInt32 nPoints, const Point* pPtAry, bool bClose ); public: diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index e311ae4652f9..d6eecfecb1e8 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -58,30 +58,61 @@ #include <cairo-xlib.h> #if ENABLE_CAIRO_CANVAS -#include <headless/CairoCommon.hxx> +#include "X11CairoSalGraphicsImpl.hxx" #endif + +// X11Common + +X11Common::X11Common() + : m_hDrawable(None) + , m_pColormap(nullptr) + , m_pExternalSurface(nullptr) +{} + +cairo_t* X11Common::getCairoContext() +{ + if (m_pExternalSurface) + return cairo_create(m_pExternalSurface); + + cairo_surface_t* surface = cairo_xlib_surface_create(GetXDisplay(), m_hDrawable, GetVisual().visual, SAL_MAX_INT16, SAL_MAX_INT16); + + cairo_t *cr = cairo_create(surface); + cairo_surface_destroy(surface); + + return cr; +} + +void X11Common::releaseCairoContext(cairo_t* cr) +{ + cairo_destroy(cr); +} + +bool X11Common::SupportsCairo() const +{ + static bool bSupportsCairo = [this] { + Display *pDisplay = GetXDisplay(); + int nDummy; + return XQueryExtension(pDisplay, "RENDER", &nDummy, &nDummy, &nDummy); + }(); + return bSupportsCairo; +} + +// X11SalGraphics + X11SalGraphics::X11SalGraphics(): m_pFrame(nullptr), m_pVDev(nullptr), - m_pColormap(nullptr), - hDrawable_(None), - m_pExternalSurface(nullptr), m_nXScreen( 0 ), m_pXRenderFormat(nullptr), m_aXRenderPicture(0), mpClipRegion(nullptr), -#if ENABLE_CAIRO_CANVAS - mnPenColor(SALCOLOR_NONE), - mnFillColor(SALCOLOR_NONE), -#endif // ENABLE_CAIRO_CANVAS hBrush_(None), bWindow_(false), - bVirDev_(false), - m_bSkia(SkiaHelper::isVCLSkiaEnabled()) + bVirDev_(false) { #if HAVE_FEATURE_SKIA - if (m_bSkia) + if (SkiaHelper::isVCLSkiaEnabled()) { mxImpl.reset(new X11SkiaSalGraphicsImpl(*this)); mxTextRenderImpl.reset(new SkiaTextRender); @@ -90,9 +121,12 @@ X11SalGraphics::X11SalGraphics(): #endif { mxTextRenderImpl.reset(new X11CairoTextRender(*this)); +#if ENABLE_CAIRO_CANVAS + mxImpl.reset(new X11CairoSalGraphicsImpl(*this, maX11Common)); +#else mxImpl.reset(new X11SalGraphicsImpl(*this)); +#endif } - } X11SalGraphics::~X11SalGraphics() COVERITY_NOEXCEPT_FALSE @@ -122,7 +156,7 @@ void X11SalGraphics::freeResources() if( m_pDeleteColormap ) { m_pDeleteColormap.reset(); - m_pColormap = nullptr; + maX11Common.m_pColormap = nullptr; } if( m_aXRenderPicture ) { @@ -138,21 +172,21 @@ SalGraphicsImpl* X11SalGraphics::GetImpl() const void X11SalGraphics::SetDrawable(Drawable aDrawable, cairo_surface_t* pExternalSurface, SalX11Screen nXScreen) { - m_pExternalSurface = pExternalSurface; + maX11Common.m_pExternalSurface = pExternalSurface; // shortcut if nothing changed - if( hDrawable_ == aDrawable ) + if( maX11Common.m_hDrawable == aDrawable ) return; // free screen specific resources if needed if( nXScreen != m_nXScreen ) { freeResources(); - m_pColormap = &vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetColormap( nXScreen ); + maX11Common.m_pColormap = &vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetColormap( nXScreen ); m_nXScreen = nXScreen; } - hDrawable_ = aDrawable; + maX11Common.m_hDrawable = aDrawable; SetXRenderFormat( nullptr ); if( m_aXRenderPicture ) { @@ -164,7 +198,7 @@ void X11SalGraphics::SetDrawable(Drawable aDrawable, cairo_surface_t* pExternalS void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, SalX11Screen nXScreen ) { - m_pColormap = &vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetColormap(nXScreen); + maX11Common.m_pColormap = &vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetColormap(nXScreen); m_nXScreen = nXScreen; m_pFrame = pFrame; @@ -328,58 +362,6 @@ void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // cons rDPIX = rDPIY; // y-resolution is more trustworthy } -void X11SalGraphics::ResetClipRegion() -{ -#if ENABLE_CAIRO_CANVAS - maClipRegion.SetNull(); -#endif - SalGraphicsAutoDelegateToImpl::ResetClipRegion(); -} - -bool X11SalGraphics::setClipRegion( const vcl::Region& i_rClip ) -{ -#if ENABLE_CAIRO_CANVAS - maClipRegion = i_rClip; -#endif - return SalGraphicsAutoDelegateToImpl::setClipRegion( i_rClip ); -} - -void X11SalGraphics::SetLineColor() -{ -#if ENABLE_CAIRO_CANVAS - mnPenColor = SALCOLOR_NONE; -#endif // ENABLE_CAIRO_CANVAS - - SalGraphicsAutoDelegateToImpl::SetLineColor(); -} - -void X11SalGraphics::SetLineColor( Color nColor ) -{ -#if ENABLE_CAIRO_CANVAS - mnPenColor = nColor; -#endif // ENABLE_CAIRO_CANVAS - - SalGraphicsAutoDelegateToImpl::SetLineColor( nColor ); -} - -void X11SalGraphics::SetFillColor() -{ -#if ENABLE_CAIRO_CANVAS - mnFillColor = SALCOLOR_NONE; -#endif // ENABLE_CAIRO_CANVAS - - SalGraphicsAutoDelegateToImpl::SetFillColor(); -} - -void X11SalGraphics::SetFillColor( Color nColor ) -{ -#if ENABLE_CAIRO_CANVAS - mnFillColor = nColor; -#endif // ENABLE_CAIRO_CANVAS - - SalGraphicsAutoDelegateToImpl::SetFillColor( nColor ); -} - XRenderPictFormat* X11SalGraphics::GetXRenderFormat() const { if( m_pXRenderFormat == nullptr ) @@ -393,7 +375,7 @@ SystemGraphicsData X11SalGraphics::GetGraphicsData() const aRes.nSize = sizeof(aRes); aRes.pDisplay = GetXDisplay(); - aRes.hDrawable = hDrawable_; + aRes.hDrawable = maX11Common.m_hDrawable; aRes.pVisual = GetVisual().visual; aRes.nScreen = m_nXScreen.getXScreen(); aRes.pXRenderFormat = m_pXRenderFormat; @@ -410,12 +392,7 @@ void X11SalGraphics::Flush() bool X11SalGraphics::SupportsCairo() const { - static bool bSupportsCairo = [this] { - Display *pDisplay = GetXDisplay(); - int nDummy; - return XQueryExtension(pDisplay, "RENDER", &nDummy, &nDummy, &nDummy); - }(); - return bSupportsCairo; + return maX11Common.SupportsCairo(); } cairo::SurfaceSharedPtr X11SalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const @@ -484,201 +461,6 @@ css::uno::Any X11SalGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rS #endif // ENABLE_CAIRO_CANVAS -// draw a poly-polygon -bool X11SalGraphics::drawPolyPolygon( - const basegfx::B2DHomMatrix& rObjectToDevice, - const basegfx::B2DPolyPolygon& rPolyPolygon, - double fTransparency) -{ -#if ENABLE_CAIRO_CANVAS - if(fTransparency >= 1.0) - { - return true; - } - - if(rPolyPolygon.count() == 0) - { - return true; - } - - // Fallback: Transform to DeviceCoordinates - basegfx::B2DPolyPolygon aPolyPolygon(rPolyPolygon); - aPolyPolygon.transform(rObjectToDevice); - - if(SALCOLOR_NONE == mnFillColor && SALCOLOR_NONE == mnPenColor) - { - return true; - } - - // enable by setting to something - static const char* pUseCairoForPolygons(getenv("SAL_ENABLE_USE_CAIRO_FOR_POLYGONS")); - - if (!m_bSkia && nullptr != pUseCairoForPolygons && SupportsCairo()) - { - // snap to raster if requested - const bool bSnapPoints(!getAntiAlias()); - - if(bSnapPoints) - { - aPolyPolygon = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aPolyPolygon); - } - - cairo_t* cr = getCairoContext(); - clipRegion(cr); - - for(auto const& rPolygon : std::as_const(aPolyPolygon)) - { - const sal_uInt32 nPointCount(rPolygon.count()); - - if(nPointCount) - { - const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nPointCount : nPointCount - 1); - - if(nEdgeCount) - { - basegfx::B2DCubicBezier aEdge; - - for(sal_uInt32 b = 0; b < nEdgeCount; ++b) - { - rPolygon.getBezierSegment(b, aEdge); - - if(!b) - { - const basegfx::B2DPoint aStart(aEdge.getStartPoint()); - cairo_move_to(cr, aStart.getX(), aStart.getY()); - } - - const basegfx::B2DPoint aEnd(aEdge.getEndPoint()); - - if(aEdge.isBezier()) - { - const basegfx::B2DPoint aCP1(aEdge.getControlPointA()); - const basegfx::B2DPoint aCP2(aEdge.getControlPointB()); - cairo_curve_to(cr, - aCP1.getX(), aCP1.getY(), - aCP2.getX(), aCP2.getY(), - aEnd.getX(), aEnd.getY()); - } - else - { - cairo_line_to(cr, aEnd.getX(), aEnd.getY()); - } - } - - cairo_close_path(cr); - } - } - } - - if(SALCOLOR_NONE != mnFillColor) - { - cairo_set_source_rgba(cr, - mnFillColor.GetRed()/255.0, - mnFillColor.GetGreen()/255.0, - mnFillColor.GetBlue()/255.0, - 1.0 - fTransparency); - cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); - cairo_fill_preserve(cr); - } - - if(SALCOLOR_NONE != mnPenColor) - { - cairo_set_source_rgba(cr, - mnPenColor.GetRed()/255.0, - mnPenColor.GetGreen()/255.0, - mnPenColor.GetBlue()/255.0, - 1.0 - fTransparency); - cairo_stroke_preserve(cr); - } - - releaseCairoContext(cr); - return true; - } -#endif // ENABLE_CAIRO_CANVAS - - return SalGraphicsAutoDelegateToImpl::drawPolyPolygon( - rObjectToDevice, - rPolyPolygon, - fTransparency); -} - -#if ENABLE_CAIRO_CANVAS -void X11SalGraphics::clipRegion(cairo_t* cr) -{ - CairoCommon::clipRegion(cr, maClipRegion); -} -#endif // ENABLE_CAIRO_CANVAS - -bool X11SalGraphics::drawPolyLine( - const basegfx::B2DHomMatrix& rObjectToDevice, - const basegfx::B2DPolygon& rPolygon, - double fTransparency, - double fLineWidth, - const std::vector< double >* pStroke, // MM01 - basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap, - double fMiterMinimumAngle, - bool bPixelSnapHairline) -{ -#if ENABLE_CAIRO_CANVAS - if(0 == rPolygon.count()) - { - return true; - } - - if(fTransparency >= 1.0) - { - return true; - } - - - // disable by setting to something - static const char* pUseCairoForFatLines(getenv("SAL_DISABLE_USE_CAIRO_FOR_FATLINES")); - - if (!m_bSkia && nullptr == pUseCairoForFatLines && SupportsCairo()) - { - cairo_t* cr = getCairoContext(); - clipRegion(cr); - - // Use the now available static drawPolyLine from the Cairo-Headless-Fallback - // that will take care of all needed stuff - const bool bRetval( - CairoCommon::drawPolyLine( - cr, - nullptr, - mnPenColor, - getAntiAlias(), - rObjectToDevice, - rPolygon, - fTransparency, - fLineWidth, - pStroke, // MM01 - eLineJoin, - eLineCap, - fMiterMinimumAngle, - bPixelSnapHairline)); - - releaseCairoContext(cr); - - if(bRetval) - { - return true; - } - } -#endif // ENABLE_CAIRO_CANVAS - - return SalGraphicsAutoDelegateToImpl::drawPolyLine( - rObjectToDevice, - rPolygon, - fTransparency, - fLineWidth, - pStroke, // MM01 - eLineJoin, - eLineCap, - fMiterMinimumAngle, - bPixelSnapHairline); -} - SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const { if (m_pFrame) @@ -689,21 +471,12 @@ SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const cairo_t* X11SalGraphics::getCairoContext() { - if (m_pExternalSurface) - return cairo_create(m_pExternalSurface); - - cairo_surface_t* surface = cairo_xlib_surface_create(GetXDisplay(), hDrawable_, - GetVisual().visual, SAL_MAX_INT16, SAL_MAX_INT16); - - cairo_t *cr = cairo_create(surface); - cairo_surface_destroy(surface); - - return cr; + return maX11Common.getCairoContext(); } void X11SalGraphics::releaseCairoContext(cairo_t* cr) { - cairo_destroy(cr); + X11Common::releaseCairoContext(cr); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/salvd.cxx b/vcl/unx/generic/gdi/salvd.cxx index dcb3a5e897b8..f5e4449c625d 100644 --- a/vcl/unx/generic/gdi/salvd.cxx +++ b/vcl/unx/generic/gdi/salvd.cxx @@ -64,16 +64,16 @@ void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, cairo_surface_t* pPreEx if( pColormap ) { - m_pColormap = pColormap; + maX11Common.m_pColormap = pColormap; if( bDeleteColormap ) m_pDeleteColormap.reset(pColormap); } else if( nDeviceDepth == nVisualDepth ) - m_pColormap = &pDisplay->GetColormap( m_nXScreen ); + maX11Common.m_pColormap = &pDisplay->GetColormap( m_nXScreen ); else if( nDeviceDepth == 1 ) { m_pDeleteColormap.reset(new SalColormap()); - m_pColormap = m_pDeleteColormap.get(); + maX11Common.m_pColormap = m_pDeleteColormap.get(); } m_pVDev = pDevice; |