summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2022-04-11 23:31:50 +0900
committerTomaž Vajngerl <quikee@gmail.com>2022-04-13 01:20:31 +0200
commita98971ac975e19efa2336b608506eefa85ce2485 (patch)
tree49e0e8b1e578685cb55a5e0e53fbadd91e1e7ff8
parent07745a031da255991c2d4c1533e916bb604d66c2 (diff)
vcl: move X11 drawing that uses cairo into X11CairoSalGraphicsImpl
If cairo is available we override drawPolyPolygon and drawPolyLine with an implementation that uses cairo to draw instead of X11. This override was previously done in X11SalGraphics, but as we want to have all the drawing in backends (SalGraphicsImpl children) this also needs to be moved to one. In this case we can just derive X11SalGraphicsImpl and implement specifics there. As there is some common stuff now betwee X11SalGraphics and X11SalGraphicsImpl, also add X11Common, which includes those. Change-Id: Id1e0c5227506e03d3dd0f937e4ef50d69b17bb22 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132827 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--vcl/Library_vclplug_gen.mk1
-rw-r--r--vcl/inc/unx/salgdi.h97
-rw-r--r--vcl/skia/x11/salvd.cxx2
-rw-r--r--vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx185
-rw-r--r--vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx97
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.cxx32
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.hxx2
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx339
-rw-r--r--vcl/unx/generic/gdi/salvd.cxx6
9 files changed, 394 insertions, 367 deletions
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 73f5464d7362..2cefd3f76856 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -98,6 +98,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
vcl/unx/generic/dtrans/X11_transferable \
vcl/unx/generic/gdi/cairo_xlib_cairo \
vcl/unx/generic/gdi/x11cairotextrender \
+ vcl/unx/generic/gdi/X11CairoSalGraphicsImpl \
vcl/unx/generic/gdi/gdiimpl \
vcl/unx/generic/gdi/salbmp \
vcl/unx/generic/gdi/salgdi2 \
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 2d0e00800886..045a3848e20f 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -62,6 +62,29 @@ namespace basegfx {
class B2DTrapezoid;
}
+class X11Common
+{
+public:
+ Drawable m_hDrawable;
+ const SalColormap* m_pColormap;
+ cairo_surface_t* m_pExternalSurface;
+
+ X11Common();
+
+ cairo_t* getCairoContext();
+
+ static void releaseCairoContext(cairo_t* cr);
+
+ bool SupportsCairo() const;
+
+ const SalColormap& GetColormap() const { return *m_pColormap; }
+ const SalDisplay* GetDisplay() const { return GetColormap().GetDisplay(); }
+ const SalVisual& GetVisual() const { return GetColormap().GetVisual(); }
+ Display* GetXDisplay() const { return GetColormap().GetXDisplay(); }
+ Pixel GetPixel(Color nColor) const { return GetColormap().GetPixel(nColor); }
+ Drawable GetDrawable() const { return m_hDrawable; }
+};
+
class X11SalGraphics final : public SalGraphicsAutoDelegateToImpl
{
friend class X11SalGraphicsImpl;
@@ -78,18 +101,10 @@ public:
void DeInit();
virtual SalGraphicsImpl* GetImpl() const override;
- inline const SalDisplay* GetDisplay() const;
- inline Display* GetXDisplay() const;
- inline const SalVisual& GetVisual() const;
SalGeometryProvider* GetGeometryProvider() const;
- Drawable GetDrawable() const { return hDrawable_; }
void SetDrawable(Drawable d, cairo_surface_t* surface, SalX11Screen nXScreen);
XRenderPictFormat* GetXRenderFormat() const;
void SetXRenderFormat( XRenderPictFormat* pXRenderFormat ) { m_pXRenderFormat = pXRenderFormat; }
- const SalColormap& GetColormap() const { return *m_pColormap; }
-
- using SalGraphics::GetPixel;
- inline Pixel GetPixel( Color nColor ) const;
const SalX11Screen& GetScreenNumber() const { return m_nXScreen; }
@@ -98,15 +113,6 @@ public:
// override all pure virtual methods
virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) override;
- virtual void ResetClipRegion() override;
- virtual bool setClipRegion( const vcl::Region& ) override;
-
- virtual void SetLineColor() override;
- virtual void SetLineColor( Color nColor ) override;
- virtual void SetFillColor() override;
-
- virtual void SetFillColor( Color nColor ) override;
-
virtual void SetTextColor( Color nColor ) override;
virtual void SetFont(LogicalFontInstance*, int nFallbackLevel) override;
virtual void GetFontMetric( ImplFontMetricDataRef&, int nFallbackLevel ) override;
@@ -138,23 +144,6 @@ public:
GetTextLayout(int nFallbackLevel) override;
virtual void DrawTextLayout( const GenericSalLayout& ) override;
-
- virtual bool drawPolyPolygon(
- const basegfx::B2DHomMatrix& rObjectToDevice,
- const basegfx::B2DPolyPolygon&,
- double fTransparency) override;
-
- virtual bool drawPolyLine(
- const basegfx::B2DHomMatrix& rObjectToDevice,
- const basegfx::B2DPolygon&,
- double fTransparency,
- double fLineWidth,
- const std::vector< double >* pStroke, // MM01
- basegfx::B2DLineJoin,
- css::drawing::LineCap,
- double fMiterMinimumAngle,
- bool bPixelSnapHairline) override;
-
virtual SystemGraphicsData GetGraphicsData() const override;
#if ENABLE_CAIRO_CANVAS
@@ -181,57 +170,39 @@ public:
private:
- using SalGraphicsAutoDelegateToImpl::drawPolyPolygon;
- using SalGraphicsAutoDelegateToImpl::drawPolyLine;
-
- using SalGraphics::SetClipRegion;
+ using SalGraphics::GetPixel;
void SetClipRegion( GC pGC, Region pXReg = nullptr ) const;
bool GetDitherPixmap ( Color nColor );
- using SalGraphics::DrawBitmap;
-
void freeResources();
SalFrame* m_pFrame; // the SalFrame which created this Graphics or NULL
SalVirtualDevice* m_pVDev; // the SalVirtualDevice which created this Graphics or NULL
- const SalColormap* m_pColormap;
+
std::unique_ptr<SalColormap> m_pDeleteColormap;
- Drawable hDrawable_; // use
- cairo_surface_t* m_pExternalSurface;
+
SalX11Screen m_nXScreen;
mutable XRenderPictFormat* m_pXRenderFormat;
XID m_aXRenderPicture;
Region mpClipRegion;
-#if ENABLE_CAIRO_CANVAS
- vcl::Region maClipRegion;
- Color mnPenColor;
- Color mnFillColor;
-#endif // ENABLE_CAIRO_CANVAS
-
Pixmap hBrush_; // Dither
bool bWindow_ : 1; // is Window
bool bVirDev_ : 1; // is VirDev
- bool m_bSkia : 1;
-private:
std::unique_ptr<SalGraphicsImpl> mxImpl;
std::unique_ptr<TextRenderImpl> mxTextRenderImpl;
+ X11Common maX11Common;
+public:
+ Drawable GetDrawable() const { return maX11Common.GetDrawable(); }
+ const SalColormap& GetColormap() const { return maX11Common.GetColormap(); }
+ const SalDisplay* GetDisplay() const { return maX11Common.GetDisplay(); }
+ const SalVisual& GetVisual() const { return maX11Common.GetVisual(); }
+ Display* GetXDisplay() const { return maX11Common.GetXDisplay(); }
+ Pixel GetPixel(Color nColor) const { return maX11Common.GetPixel(nColor); }
};
-inline const SalDisplay *X11SalGraphics::GetDisplay() const
-{ return GetColormap().GetDisplay(); }
-
-inline const SalVisual& X11SalGraphics::GetVisual() const
-{ return GetColormap().GetVisual(); }
-
-inline Display *X11SalGraphics::GetXDisplay() const
-{ return GetColormap().GetXDisplay(); }
-
-inline Pixel X11SalGraphics::GetPixel( Color nColor ) const
-{ return GetColormap().GetPixel( nColor ); }
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/x11/salvd.cxx b/vcl/skia/x11/salvd.cxx
index bb007962f11c..73488b8a10bc 100644
--- a/vcl/skia/x11/salvd.cxx
+++ b/vcl/skia/x11/salvd.cxx
@@ -21,7 +21,7 @@ void X11SalGraphics::Init(X11SkiaSalVirtualDevice* pDevice)
SalDisplay* pDisplay = pDevice->GetDisplay();
m_nXScreen = pDevice->GetXScreenNumber();
- m_pColormap = &pDisplay->GetColormap(m_nXScreen);
+ maX11Common.m_pColormap = &pDisplay->GetColormap(m_nXScreen);
m_pVDev = pDevice;
m_pFrame = nullptr;
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;