From 2aa39b2a344f07110bb6d6b44414ba58009ecde3 Mon Sep 17 00:00:00 2001 From: Takamitsu Endo Date: Fri, 9 Sep 2022 16:13:02 +0900 Subject: [PATCH] Update Ubuntu CI script --- ci/ci_ubuntu.sh | 11 +- ci/linux_patch/cairocontext.cpp | 566 ++++++++++++++++ ci/linux_patch/cairocontext.cpp.diff | 921 --------------------------- ci/linux_patch/x11frame.cpp.diff | 12 - 4 files changed, 569 insertions(+), 941 deletions(-) create mode 100644 ci/linux_patch/cairocontext.cpp delete mode 100644 ci/linux_patch/cairocontext.cpp.diff delete mode 100644 ci/linux_patch/x11frame.cpp.diff diff --git a/ci/ci_ubuntu.sh b/ci/ci_ubuntu.sh index edbd98c5..ae44fe8c 100755 --- a/ci/ci_ubuntu.sh +++ b/ci/ci_ubuntu.sh @@ -15,14 +15,9 @@ cd vst3sdk || exit # Patch vst3sdk. # - https://github.com/ryukau/VSTPlugins/issues/3 -patch \ - vstgui4/vstgui/lib/platform/linux/cairocontext.cpp \ - "$GITHUB_WORKSPACE"/ci/linux_patch/cairocontext.cpp.diff - -# - https://github.com/steinbergmedia/vstgui/issues/249 -patch \ - vstgui4/vstgui/lib/platform/linux/x11frame.cpp \ - "$GITHUB_WORKSPACE"/ci/linux_patch/x11frame.cpp.diff +cp \ + "$GITHUB_WORKSPACE"/ci/linux_patch/cairocontext.cpp \ + vstgui4/vstgui/lib/platform/linux/ mkdir build cd build || exit diff --git a/ci/linux_patch/cairocontext.cpp b/ci/linux_patch/cairocontext.cpp new file mode 100644 index 00000000..3fa8a7d0 --- /dev/null +++ b/ci/linux_patch/cairocontext.cpp @@ -0,0 +1,566 @@ +// This file is part of VSTGUI. It is subject to the license terms +// in the LICENSE file found in the top-level directory of this +// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE + +#include "cairocontext.h" +#include "../../cbitmap.h" +#include "../../cgradient.h" +#include "cairobitmap.h" +#include "cairogradient.h" +#include "cairopath.h" + +//------------------------------------------------------------------------ +namespace VSTGUI { +namespace Cairo { + +//------------------------------------------------------------------------ +namespace { + +struct SaveCairoState +{ + SaveCairoState (ContextHandle& h) : h (h) { cairo_save (h); } + ~SaveCairoState () { cairo_restore (h); } + +private: + ContextHandle& h; +}; + +//------------------------------------------------------------------------ +void checkCairoStatus (const ContextHandle& handle) +{ +#if DEBUG + auto status = cairo_status (handle); + if (status != CAIRO_STATUS_SUCCESS) + { + auto msg = cairo_status_to_string (status); + DebugPrint ("%s\n", msg); + } +#endif +} + +//------------------------------------------------------------------------ +cairo_matrix_t convert (CGraphicsTransform& ct) +{ + return {ct.m11, ct.m21, ct.m12, ct.m22, ct.dx, ct.dy}; +} + +//----------------------------------------------------------------------------- +inline bool needPixelAlignment (CDrawMode mode) +{ + return (mode.integralMode () && mode.modeIgnoringIntegralMode () == kAntiAliasing); +} + +//------------------------------------------------------------------------ +} // anonymous + +//------------------------------------------------------------------------ +DrawBlock::DrawBlock (Context& context) : context (context) +{ + auto ct = context.getCurrentTransform (); + CRect clip = context.getCurrentStateClipRect (); + if (clip.isEmpty ()) + { + clipIsEmpty = true; + } + else + { + cairo_save (context.getCairo ()); + cairo_rectangle (context.getCairo (), clip.left, clip.top, clip.getWidth (), + clip.getHeight ()); + cairo_clip (context.getCairo ()); + auto matrix = convert (ct); + cairo_set_matrix (context.getCairo (), &matrix); + auto antialiasMode = context.getDrawMode ().modeIgnoringIntegralMode () == kAntiAliasing + ? CAIRO_ANTIALIAS_BEST + : CAIRO_ANTIALIAS_NONE; + cairo_set_antialias (context.getCairo (), antialiasMode); + } +} + +//------------------------------------------------------------------------ +DrawBlock::~DrawBlock () +{ + if (!clipIsEmpty) + { + cairo_restore (context.getCairo ()); + } +} + +//------------------------------------------------------------------------ +DrawBlock DrawBlock::begin (Context& context) +{ + return DrawBlock (context); +} + +//----------------------------------------------------------------------------- +Context::Context (const CRect& rect, const SurfaceHandle& surface) : super (rect), surface (surface) +{ + init (); +} + +//----------------------------------------------------------------------------- +Context::Context (Bitmap* bitmap) : super (new CBitmap (bitmap)), surface (bitmap->getSurface ()) +{ + init (); +} + +//----------------------------------------------------------------------------- +Context::Context (CRect r, cairo_t* context) : super (r) +{ + cr = ContextHandle {cairo_reference (context)}; + init (); +} + +//----------------------------------------------------------------------------- +Context::~Context () {} + +//----------------------------------------------------------------------------- +void Context::init () +{ + if (surface) + cr.assign (cairo_create (surface)); + super::init (); +} + +//----------------------------------------------------------------------------- +CRect Context::getCurrentStateClipRect () const +{ + return getCurrentState ().clipRect; +} + +//----------------------------------------------------------------------------- +void Context::beginDraw () +{ + super::beginDraw (); + cairo_save (cr); + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +void Context::endDraw () +{ + cairo_restore (cr); + if (surface) + cairo_surface_flush (surface); + checkCairoStatus (cr); + super::endDraw (); +} + +//----------------------------------------------------------------------------- +void Context::saveGlobalState () +{ + super::saveGlobalState (); +} + +//----------------------------------------------------------------------------- +void Context::restoreGlobalState () +{ + super::restoreGlobalState (); +} + +//----------------------------------------------------------------------------- +void Context::setSourceColor (CColor color) +{ + auto alpha = color.normAlpha (); + alpha *= getGlobalAlpha (); + cairo_set_source_rgba (cr, color.normRed (), color.normGreen (), + color.normBlue (), alpha); + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +void Context::setupCurrentStroke () +{ + auto lineWidth = getLineWidth (); + cairo_set_line_width (cr, lineWidth); + const auto& style = getLineStyle (); + if (!style.getDashLengths ().empty ()) + { + auto lengths = style.getDashLengths (); + for (auto& l : lengths) + l *= lineWidth; + cairo_set_dash (cr, lengths.data (), lengths.size (), style.getDashPhase ()); + } + cairo_line_cap_t lineCap; + switch (style.getLineCap ()) + { + case CLineStyle::kLineCapButt: + { + lineCap = CAIRO_LINE_CAP_BUTT; + break; + } + case CLineStyle::kLineCapRound: + { + lineCap = CAIRO_LINE_CAP_ROUND; + break; + } + case CLineStyle::kLineCapSquare: + { + lineCap = CAIRO_LINE_CAP_SQUARE; + break; + } + } + cairo_set_line_cap (cr, lineCap); + cairo_line_join_t lineJoin; + switch (style.getLineJoin ()) + { + case CLineStyle::kLineJoinBevel: + { + lineJoin = CAIRO_LINE_JOIN_BEVEL; + break; + } + case CLineStyle::kLineJoinMiter: + { + lineJoin = CAIRO_LINE_JOIN_MITER; + break; + } + case CLineStyle::kLineJoinRound: + { + lineJoin = CAIRO_LINE_JOIN_ROUND; + break; + } + } + + cairo_set_line_join (cr, lineJoin); +} + +//----------------------------------------------------------------------------- +void Context::draw (CDrawStyle drawStyle) +{ + switch (drawStyle) + { + case kDrawStroked: + { + setupCurrentStroke (); + setSourceColor (getFrameColor ()); + cairo_stroke (cr); + break; + } + case kDrawFilled: + { + setSourceColor (getFillColor ()); + cairo_fill (cr); + break; + } + case kDrawFilledAndStroked: + { + setSourceColor (getFillColor ()); + cairo_fill_preserve (cr); + setupCurrentStroke (); + setSourceColor (getFrameColor ()); + cairo_stroke (cr); + break; + } + } + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +void Context::drawLine (const CDrawContext::LinePair& line) +{ + if (auto cd = DrawBlock::begin (*this)) + { + setupCurrentStroke (); + setSourceColor (getFrameColor ()); + if (getDrawMode ().integralMode ()) + { + CPoint start = pixelAlign (getCurrentTransform (), line.first); + CPoint end = pixelAlign (getCurrentTransform (), line.second); + cairo_move_to (cr, start.x, start.y); + cairo_line_to (cr, end.x, end.y); + } + else + { + cairo_move_to (cr, line.first.x, line.first.y); + cairo_line_to (cr, line.second.x, line.second.y); + } + cairo_stroke (cr); + } + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +void Context::drawLines (const CDrawContext::LineList& lines) +{ + if (auto cd = DrawBlock::begin (*this)) + { + setupCurrentStroke (); + setSourceColor (getFrameColor ()); + if (getDrawMode ().integralMode ()) + { + for (auto& line : lines) + { + CPoint start = pixelAlign (getCurrentTransform (), line.first); + CPoint end = pixelAlign (getCurrentTransform (), line.second); + cairo_move_to (cr, start.x, start.y); + cairo_line_to (cr, end.x, end.y); + cairo_stroke (cr); + } + } + else + { + for (auto& line : lines) + { + cairo_move_to (cr, line.first.x, line.first.y); + cairo_line_to (cr, line.second.x, line.second.y); + cairo_stroke (cr); + } + } + } +} + +//----------------------------------------------------------------------------- +void Context::drawPolygon (const CDrawContext::PointList& polygonPointList, + const CDrawStyle drawStyle) +{ + if (polygonPointList.size () < 2) + return; + + if (auto cd = DrawBlock::begin (*this)) + { + auto& first = polygonPointList.front (); + cairo_move_to (cr, first.x, first.y); + for (auto it = polygonPointList.begin () + 1; it != polygonPointList.end (); ++it) + cairo_line_to (cr, (*it).x, (*it).y); + + draw (drawStyle); + } +} + +//----------------------------------------------------------------------------- +void Context::drawRect (const CRect& rect, const CDrawStyle drawStyle) +{ + if (auto cd = DrawBlock::begin (*this)) + { + CRect r (rect); + if (needPixelAlignment (getDrawMode ())) + { + r = pixelAlign (getCurrentTransform (), r); + cairo_rectangle (cr, r.left, r.top, r.getWidth (), r.getHeight ()); + } + else + cairo_rectangle (cr, r.left + 0.5, r.top + 0.5, r.getWidth () - 0.5, + r.getHeight () - 0.5); + draw (drawStyle); + } +} + +//----------------------------------------------------------------------------- +void Context::drawArc (const CRect& rect, const float startAngle1, const float endAngle2, + const CDrawStyle drawStyle) +{ + if (auto cd = DrawBlock::begin (*this)) + { + cairo_save (cr); + CPoint center = rect.getCenter (); + cairo_translate (cr, center.x, center.y); + cairo_scale (cr, rect.getWidth () / 2.0, rect.getHeight () / 2.0); + cairo_arc (cr, 0, 0, 1, startAngle1 / 180.0 * M_PI, endAngle2 / 180.0 * M_PI); + cairo_restore (cr); + draw (drawStyle); + } +} + +//----------------------------------------------------------------------------- +void Context::drawEllipse (const CRect& rect, const CDrawStyle drawStyle) +{ + if (auto cd = DrawBlock::begin (*this)) + { + cairo_save (cr); + CPoint center = rect.getCenter (); + cairo_translate (cr, center.x, center.y); + cairo_scale (cr, rect.getWidth () / 2.0, rect.getHeight () / 2.0); + cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); + cairo_restore (cr); + draw (drawStyle); + } +} + +//----------------------------------------------------------------------------- +void Context::drawPoint (const CPoint& point, const CColor& color) +{ + if (auto cd = DrawBlock::begin (*this)) + { + setSourceColor (color); + cairo_rectangle (cr, point.x + 0.5, point.y + 0.5, 1, 1); + cairo_fill (cr); + } + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +void Context::drawBitmap (CBitmap* bitmap, const CRect& dest, const CPoint& offset, float alpha) +{ + if (auto cd = DrawBlock::begin (*this)) + { + double transformedScaleFactor = getScaleFactor (); + CGraphicsTransform t = getCurrentTransform (); + if (t.m11 == t.m22 && t.m12 == 0 && t.m21 == 0) + transformedScaleFactor *= t.m11; + auto cairoBitmap = + bitmap->getBestPlatformBitmapForScaleFactor (transformedScaleFactor).cast (); + if (cairoBitmap) + { + cairo_translate (cr, dest.left, dest.top); + cairo_rectangle (cr, 0, 0, dest.getWidth (), dest.getHeight ()); + cairo_clip (cr); + + // Setup a pattern for scaling bitmaps and take it as source afterwards. + auto pattern = cairo_pattern_create_for_surface (cairoBitmap->getSurface ()); + cairo_matrix_t matrix; + cairo_pattern_get_matrix (pattern, &matrix); + cairo_matrix_init_scale (&matrix, cairoBitmap->getScaleFactor (), + cairoBitmap->getScaleFactor ()); + cairo_matrix_translate (&matrix, offset.x, offset.y); + cairo_pattern_set_matrix (pattern, &matrix); + cairo_set_source (cr, pattern); + + cairo_rectangle (cr, -offset.x, -offset.y, dest.getWidth () + offset.x, + dest.getHeight () + offset.y); + alpha *= getGlobalAlpha (); + if (alpha != 1.f) + { + cairo_paint_with_alpha (cr, alpha); + } + else + { + cairo_fill (cr); + } + + cairo_pattern_destroy (pattern); + } + } + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +void Context::clearRect (const CRect& rect) +{ + if (auto cd = DrawBlock::begin (*this)) + { + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_rectangle (cr, rect.left, rect.top, rect.getWidth (), rect.getHeight ()); + cairo_fill (cr); + } + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +CGraphicsPath* Context::createGraphicsPath () +{ + if (!graphicsPathFactory) + graphicsPathFactory = std::make_shared (cr); + return new CGraphicsPath (graphicsPathFactory); +} + +//----------------------------------------------------------------------------- +CGraphicsPath* Context::createTextPath (const CFontRef font, UTF8StringPtr text) +{ +#warning TODO: Implementation + return nullptr; +} + +//----------------------------------------------------------------------------- +void Context::drawGraphicsPath (CGraphicsPath* path, CDrawContext::PathDrawMode mode, + CGraphicsTransform* transformation) +{ + if (path) + { + auto graphicsPath = dynamic_cast ( + path->getPlatformPath (PlatformGraphicsPathFillMode::Ignored).get ()); + if (!graphicsPath) + return; + if (auto cd = DrawBlock::begin (*this)) + { + std::unique_ptr alignedPath; + if (needPixelAlignment (getDrawMode ())) + alignedPath = graphicsPath->copyPixelAlign (getCurrentTransform ()); + auto p = alignedPath ? alignedPath->getCairoPath () : graphicsPath->getCairoPath (); + if (transformation) + { + cairo_matrix_t currentMatrix; + cairo_matrix_t resultMatrix; + auto matrix = convert (*transformation); + cairo_get_matrix (cr, ¤tMatrix); + cairo_matrix_multiply (&resultMatrix, &matrix, ¤tMatrix); + cairo_set_matrix (cr, &resultMatrix); + } + cairo_append_path (cr, p); + switch (mode) + { + case PathDrawMode::kPathFilled: + { + setSourceColor (getFillColor ()); + cairo_fill (cr); + break; + } + case PathDrawMode::kPathFilledEvenOdd: + { + setSourceColor (getFillColor ()); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_fill (cr); + break; + } + case PathDrawMode::kPathStroked: + { + setupCurrentStroke (); + setSourceColor (getFrameColor ()); + cairo_stroke (cr); + break; + } + } + } + } + checkCairoStatus (cr); +} + +//----------------------------------------------------------------------------- +void Context::fillLinearGradient (CGraphicsPath* path, const CGradient& gradient, + const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, + CGraphicsTransform* transformation) +{ + if (path) + { + auto graphicsPath = dynamic_cast ( + path->getPlatformPath (PlatformGraphicsPathFillMode::Ignored).get ()); + if (!graphicsPath) + return; + std::unique_ptr alignedPath; + if (needPixelAlignment (getDrawMode ())) + alignedPath = graphicsPath->copyPixelAlign (getCurrentTransform ()); + if (auto cairoGradient = dynamic_cast (gradient.getPlatformGradient ().get ())) + { + if (auto cd = DrawBlock::begin (*this)) + { + auto p = alignedPath ? alignedPath->getCairoPath () : graphicsPath->getCairoPath (); + cairo_append_path (cr, p); + cairo_set_source (cr, cairoGradient->getLinearGradient (startPoint, endPoint)); + if (evenOdd) + { + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_fill (cr); + } + else + { + cairo_fill (cr); + } + } + } + } +} + +//----------------------------------------------------------------------------- +void Context::fillRadialGradient (CGraphicsPath* path, const CGradient& gradient, + const CPoint& center, CCoord radius, const CPoint& originOffset, + bool evenOdd, CGraphicsTransform* transformation) +{ +#warning TODO: Implementation + auto cd = DrawBlock::begin (*this); + if (cd) + { + } +} + +//----------------------------------------------------------------------------- +} // Cairo +} // VSTGUI diff --git a/ci/linux_patch/cairocontext.cpp.diff b/ci/linux_patch/cairocontext.cpp.diff deleted file mode 100644 index ac3f5726..00000000 --- a/ci/linux_patch/cairocontext.cpp.diff +++ /dev/null @@ -1,921 +0,0 @@ -diff --git a/vstgui/lib/platform/linux/cairocontext.cpp b/vstgui/lib/platform/linux/cairocontext.cpp -index c2d07eb3..7762518f 100644 ---- a/vstgui/lib/platform/linux/cairocontext.cpp -+++ b/vstgui/lib/platform/linux/cairocontext.cpp -@@ -16,547 +16,496 @@ namespace Cairo { - //------------------------------------------------------------------------ - namespace { - --struct SaveCairoState --{ -- SaveCairoState (ContextHandle& h) : h (h) { cairo_save (h); } -- ~SaveCairoState () { cairo_restore (h); } -+struct SaveCairoState { -+ SaveCairoState(ContextHandle &h) : h(h) { cairo_save(h); } -+ ~SaveCairoState() { cairo_restore(h); } - - private: -- ContextHandle& h; -+ ContextHandle &h; - }; - - //------------------------------------------------------------------------ --void checkCairoStatus (const ContextHandle& handle) -+void checkCairoStatus(const ContextHandle &handle) - { - #if DEBUG -- auto status = cairo_status (handle); -- if (status != CAIRO_STATUS_SUCCESS) -- { -- auto msg = cairo_status_to_string (status); -- DebugPrint ("%s\n", msg); -- } -+ auto status = cairo_status(handle); -+ if (status != CAIRO_STATUS_SUCCESS) { -+ auto msg = cairo_status_to_string(status); -+ DebugPrint("%s\n", msg); -+ } - #endif - } - - //------------------------------------------------------------------------ --cairo_matrix_t convert (CGraphicsTransform& ct) -+cairo_matrix_t convert(CGraphicsTransform &ct) - { -- return {ct.m11, ct.m21, ct.m12, ct.m22, ct.dx, ct.dy}; -+ return {ct.m11, ct.m21, ct.m12, ct.m22, ct.dx, ct.dy}; - } - - //----------------------------------------------------------------------------- --inline bool needPixelAlignment (CDrawMode mode) -+inline bool needPixelAlignment(CDrawMode mode) - { -- return (mode.integralMode () && mode.modeIgnoringIntegralMode () == kAntiAliasing); -+ return (mode.integralMode() && mode.modeIgnoringIntegralMode() == kAntiAliasing); - } - - //------------------------------------------------------------------------ --} // anonymous -+} // namespace - - //------------------------------------------------------------------------ --DrawBlock::DrawBlock (Context& context) : context (context) --{ -- auto ct = context.getCurrentTransform (); -- CRect clip = context.getCurrentStateClipRect (); -- if (clip.isEmpty ()) -- { -- clipIsEmpty = true; -- } -- else -- { -- cairo_save (context.getCairo ()); -- cairo_rectangle (context.getCairo (), clip.left, clip.top, clip.getWidth (), -- clip.getHeight ()); -- cairo_clip (context.getCairo ()); -- auto matrix = convert (ct); -- cairo_set_matrix (context.getCairo (), &matrix); -- auto antialiasMode = context.getDrawMode ().modeIgnoringIntegralMode () == kAntiAliasing -- ? CAIRO_ANTIALIAS_BEST -- : CAIRO_ANTIALIAS_NONE; -- cairo_set_antialias (context.getCairo (), antialiasMode); -- } -+DrawBlock::DrawBlock(Context &context) : context(context) -+{ -+ auto ct = context.getCurrentTransform(); -+ CRect clip = context.getCurrentStateClipRect(); -+ if (clip.isEmpty()) { -+ clipIsEmpty = true; -+ } else { -+ cairo_save(context.getCairo()); -+ cairo_rectangle( -+ context.getCairo(), clip.left, clip.top, clip.getWidth(), clip.getHeight()); -+ cairo_clip(context.getCairo()); -+ auto matrix = convert(ct); -+ cairo_set_matrix(context.getCairo(), &matrix); -+ auto antialiasMode = context.getDrawMode().modeIgnoringIntegralMode() == kAntiAliasing -+ ? CAIRO_ANTIALIAS_BEST -+ : CAIRO_ANTIALIAS_NONE; -+ cairo_set_antialias(context.getCairo(), antialiasMode); -+ } - } - - //------------------------------------------------------------------------ --DrawBlock::~DrawBlock () -+DrawBlock::~DrawBlock() - { -- if (!clipIsEmpty) -- { -- cairo_restore (context.getCairo ()); -- } -+ if (!clipIsEmpty) { -+ cairo_restore(context.getCairo()); -+ } - } - - //------------------------------------------------------------------------ --DrawBlock DrawBlock::begin (Context& context) --{ -- return DrawBlock (context); --} -+DrawBlock DrawBlock::begin(Context &context) { return DrawBlock(context); } - - //----------------------------------------------------------------------------- --Context::Context (const CRect& rect, const SurfaceHandle& surface) : super (rect), surface (surface) -+Context::Context(const CRect &rect, const SurfaceHandle &surface) -+ : super(rect), surface(surface) - { -- init (); -+ init(); - } - - //----------------------------------------------------------------------------- --Context::Context (Bitmap* bitmap) : super (new CBitmap (bitmap)), surface (bitmap->getSurface ()) -+Context::Context(Bitmap *bitmap) -+ : super(new CBitmap(bitmap)), surface(bitmap->getSurface()) - { -- init (); -+ init(); - } - - //----------------------------------------------------------------------------- --Context::Context (CRect r, cairo_t* context) : super (r) -+Context::Context(CRect r, cairo_t *context) : super(r) - { -- cr = ContextHandle {cairo_reference (context)}; -- init (); -+ cr = ContextHandle{cairo_reference(context)}; -+ init(); - } - - //----------------------------------------------------------------------------- --Context::~Context () {} -+Context::~Context() {} - - //----------------------------------------------------------------------------- --void Context::init () -+void Context::init() - { -- if (surface) -- cr.assign (cairo_create (surface)); -- super::init (); -+ if (surface) cr.assign(cairo_create(surface)); -+ super::init(); - } - - //----------------------------------------------------------------------------- --CRect Context::getCurrentStateClipRect () const --{ -- return getCurrentState ().clipRect; --} -+CRect Context::getCurrentStateClipRect() const { return getCurrentState().clipRect; } - - //----------------------------------------------------------------------------- --void Context::beginDraw () -+void Context::beginDraw() - { -- super::beginDraw (); -- cairo_save (cr); -- checkCairoStatus (cr); -+ super::beginDraw(); -+ cairo_save(cr); -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --void Context::endDraw () -+void Context::endDraw() - { -- cairo_restore (cr); -- if (surface) -- cairo_surface_flush (surface); -- checkCairoStatus (cr); -- super::endDraw (); -+ cairo_restore(cr); -+ if (surface) cairo_surface_flush(surface); -+ checkCairoStatus(cr); -+ super::endDraw(); - } - - //----------------------------------------------------------------------------- --void Context::saveGlobalState () --{ -- super::saveGlobalState (); --} -+void Context::saveGlobalState() { super::saveGlobalState(); } - - //----------------------------------------------------------------------------- --void Context::restoreGlobalState () --{ -- super::restoreGlobalState (); --} -+void Context::restoreGlobalState() { super::restoreGlobalState(); } - - //----------------------------------------------------------------------------- --void Context::setSourceColor (CColor color) -+void Context::setSourceColor(CColor color) - { -- auto alpha = color.normAlpha (); -- alpha *= getGlobalAlpha (); -- cairo_set_source_rgba (cr, color.normRed (), color.normGreen (), -- color.normBlue (), alpha); -- checkCairoStatus (cr); -+ auto alpha = color.normAlpha(); -+ alpha *= getGlobalAlpha(); -+ cairo_set_source_rgba( -+ cr, color.normRed(), color.normGreen(), color.normBlue(), -+ alpha); -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --void Context::setupCurrentStroke () --{ -- auto lineWidth = getLineWidth (); -- cairo_set_line_width (cr, lineWidth); -- const auto& style = getLineStyle (); -- if (!style.getDashLengths ().empty ()) -- { -- auto lengths = style.getDashLengths (); -- for (auto& l : lengths) -- l *= lineWidth; -- cairo_set_dash (cr, lengths.data (), lengths.size (), style.getDashPhase ()); -- } -- cairo_line_cap_t lineCap; -- switch (style.getLineCap ()) -- { -- case CLineStyle::kLineCapButt: -- { -- lineCap = CAIRO_LINE_CAP_BUTT; -- break; -- } -- case CLineStyle::kLineCapRound: -- { -- lineCap = CAIRO_LINE_CAP_ROUND; -- break; -- } -- case CLineStyle::kLineCapSquare: -- { -- lineCap = CAIRO_LINE_CAP_SQUARE; -- break; -- } -- } -- cairo_set_line_cap (cr, lineCap); -- cairo_line_join_t lineJoin; -- switch (style.getLineJoin ()) -- { -- case CLineStyle::kLineJoinBevel: -- { -- lineJoin = CAIRO_LINE_JOIN_BEVEL; -- break; -- } -- case CLineStyle::kLineJoinMiter: -- { -- lineJoin = CAIRO_LINE_JOIN_MITER; -- break; -- } -- case CLineStyle::kLineJoinRound: -- { -- lineJoin = CAIRO_LINE_JOIN_ROUND; -- break; -- } -- } -- -- cairo_set_line_join (cr, lineJoin); -+void Context::setupCurrentStroke() -+{ -+ auto lineWidth = getLineWidth(); -+ cairo_set_line_width(cr, lineWidth); -+ const auto &style = getLineStyle(); -+ if (!style.getDashLengths().empty()) { -+ auto lengths = style.getDashLengths(); -+ for (auto &l : lengths) l *= lineWidth; -+ cairo_set_dash(cr, lengths.data(), lengths.size(), style.getDashPhase()); -+ } -+ cairo_line_cap_t lineCap; -+ switch (style.getLineCap()) { -+ case CLineStyle::kLineCapButt: { -+ lineCap = CAIRO_LINE_CAP_BUTT; -+ break; -+ } -+ case CLineStyle::kLineCapRound: { -+ lineCap = CAIRO_LINE_CAP_ROUND; -+ break; -+ } -+ case CLineStyle::kLineCapSquare: { -+ lineCap = CAIRO_LINE_CAP_SQUARE; -+ break; -+ } -+ } -+ cairo_set_line_cap(cr, lineCap); -+ cairo_line_join_t lineJoin; -+ switch (style.getLineJoin()) { -+ case CLineStyle::kLineJoinBevel: { -+ lineJoin = CAIRO_LINE_JOIN_BEVEL; -+ break; -+ } -+ case CLineStyle::kLineJoinMiter: { -+ lineJoin = CAIRO_LINE_JOIN_MITER; -+ break; -+ } -+ case CLineStyle::kLineJoinRound: { -+ lineJoin = CAIRO_LINE_JOIN_ROUND; -+ break; -+ } -+ } -+ -+ cairo_set_line_join(cr, lineJoin); - } - - //----------------------------------------------------------------------------- --void Context::draw (CDrawStyle drawStyle) --{ -- switch (drawStyle) -- { -- case kDrawStroked: -- { -- setupCurrentStroke (); -- setSourceColor (getFrameColor ()); -- cairo_stroke (cr); -- break; -- } -- case kDrawFilled: -- { -- setSourceColor (getFillColor ()); -- cairo_fill (cr); -- break; -- } -- case kDrawFilledAndStroked: -- { -- setSourceColor (getFillColor ()); -- cairo_fill_preserve (cr); -- setupCurrentStroke (); -- setSourceColor (getFrameColor ()); -- cairo_stroke (cr); -- break; -- } -- } -- checkCairoStatus (cr); -+void Context::draw(CDrawStyle drawStyle) -+{ -+ switch (drawStyle) { -+ case kDrawStroked: { -+ setupCurrentStroke(); -+ setSourceColor(getFrameColor()); -+ cairo_stroke(cr); -+ break; -+ } -+ case kDrawFilled: { -+ setSourceColor(getFillColor()); -+ cairo_fill(cr); -+ break; -+ } -+ case kDrawFilledAndStroked: { -+ setSourceColor(getFillColor()); -+ cairo_fill_preserve(cr); -+ setupCurrentStroke(); -+ setSourceColor(getFrameColor()); -+ cairo_stroke(cr); -+ break; -+ } -+ } -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --void Context::drawLine (const CDrawContext::LinePair& line) --{ -- if (auto cd = DrawBlock::begin (*this)) -- { -- setupCurrentStroke (); -- setSourceColor (getFrameColor ()); -- if (getDrawMode ().integralMode ()) -- { -- CPoint start = pixelAlign (getCurrentTransform (), line.first); -- CPoint end = pixelAlign (getCurrentTransform (), line.second); -- cairo_move_to (cr, start.x, start.y); -- cairo_line_to (cr, end.x, end.y); -- } -- else -- { -- cairo_move_to (cr, line.first.x, line.first.y); -- cairo_line_to (cr, line.second.x, line.second.y); -- } -- cairo_stroke (cr); -- } -- checkCairoStatus (cr); -+void Context::drawLine(const CDrawContext::LinePair &line) -+{ -+ if (auto cd = DrawBlock::begin(*this)) { -+ setupCurrentStroke(); -+ setSourceColor(getFrameColor()); -+ if (getDrawMode().integralMode()) { -+ CPoint start = pixelAlign(getCurrentTransform(), line.first); -+ CPoint end = pixelAlign(getCurrentTransform(), line.second); -+ cairo_move_to(cr, start.x, start.y); -+ cairo_line_to(cr, end.x, end.y); -+ } else { -+ cairo_move_to(cr, line.first.x, line.first.y); -+ cairo_line_to(cr, line.second.x, line.second.y); -+ } -+ cairo_stroke(cr); -+ } -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --void Context::drawLines (const CDrawContext::LineList& lines) --{ -- if (auto cd = DrawBlock::begin (*this)) -- { -- setupCurrentStroke (); -- setSourceColor (getFrameColor ()); -- if (getDrawMode ().integralMode ()) -- { -- for (auto& line : lines) -- { -- CPoint start = pixelAlign (getCurrentTransform (), line.first); -- CPoint end = pixelAlign (getCurrentTransform (), line.second); -- cairo_move_to (cr, start.x, start.y); -- cairo_line_to (cr, end.x, end.y); -- cairo_stroke (cr); -- } -- } -- else -- { -- for (auto& line : lines) -- { -- cairo_move_to (cr, line.first.x, line.first.y); -- cairo_line_to (cr, line.second.x, line.second.y); -- cairo_stroke (cr); -- } -- } -- } -+void Context::drawLines(const CDrawContext::LineList &lines) -+{ -+ if (auto cd = DrawBlock::begin(*this)) { -+ setupCurrentStroke(); -+ setSourceColor(getFrameColor()); -+ if (getDrawMode().integralMode()) { -+ for (auto &line : lines) { -+ CPoint start = pixelAlign(getCurrentTransform(), line.first); -+ CPoint end = pixelAlign(getCurrentTransform(), line.second); -+ cairo_move_to(cr, start.x, start.y); -+ cairo_line_to(cr, end.x, end.y); -+ cairo_stroke(cr); -+ } -+ } else { -+ for (auto &line : lines) { -+ cairo_move_to(cr, line.first.x, line.first.y); -+ cairo_line_to(cr, line.second.x, line.second.y); -+ cairo_stroke(cr); -+ } -+ } -+ } - } - - //----------------------------------------------------------------------------- --void Context::drawPolygon (const CDrawContext::PointList& polygonPointList, -- const CDrawStyle drawStyle) -+void Context::drawPolygon( -+ const CDrawContext::PointList &polygonPointList, const CDrawStyle drawStyle) - { -- if (polygonPointList.size () < 2) -- return; -- -- if (auto cd = DrawBlock::begin (*this)) -- { -- auto& last = polygonPointList.back (); -- cairo_move_to (cr, last.x, last.y); -- for (auto& it : polygonPointList) -- cairo_line_to (cr, it.x, it.y); -- -- draw (drawStyle); -- } -+ if (polygonPointList.size() < 2) return; -+ -+ if (auto cd = DrawBlock::begin(*this)) { -+ auto &first = polygonPointList.front(); -+ cairo_move_to(cr, first.x, first.y); -+ for (auto it = polygonPointList.begin() + 1; it != polygonPointList.end(); ++it) -+ cairo_line_to(cr, (*it).x, (*it).y); -+ -+ draw(drawStyle); -+ } - } - - //----------------------------------------------------------------------------- --void Context::drawRect (const CRect& rect, const CDrawStyle drawStyle) -+void Context::drawRect(const CRect &rect, const CDrawStyle drawStyle) - { -- if (auto cd = DrawBlock::begin (*this)) -- { -- CRect r (rect); -- if (needPixelAlignment (getDrawMode ())) -- { -- r = pixelAlign (getCurrentTransform (), r); -- cairo_rectangle (cr, r.left, r.top, r.getWidth (), r.getHeight ()); -- } -- else -- cairo_rectangle (cr, r.left + 0.5, r.top + 0.5, r.getWidth () - 0.5, -- r.getHeight () - 0.5); -- draw (drawStyle); -- } -+ if (auto cd = DrawBlock::begin(*this)) { -+ CRect r(rect); -+ if (needPixelAlignment(getDrawMode())) { -+ r = pixelAlign(getCurrentTransform(), r); -+ cairo_rectangle(cr, r.left, r.top, r.getWidth(), r.getHeight()); -+ } else -+ cairo_rectangle(cr, r.left, r.top, r.getWidth(), r.getHeight()); -+ draw(drawStyle); -+ } - } - - //----------------------------------------------------------------------------- --void Context::drawArc (const CRect& rect, const float startAngle1, const float endAngle2, -- const CDrawStyle drawStyle) --{ -- if (auto cd = DrawBlock::begin (*this)) -- { -- CPoint center = rect.getCenter (); -- cairo_translate (cr, center.x, center.y); -- cairo_scale (cr, 2.0 / rect.getWidth (), 2.0 / rect.getHeight ()); -- cairo_arc (cr, 0, 0, 1, startAngle1, endAngle2); -- draw (drawStyle); -- } -+void Context::drawArc( -+ const CRect &rect, -+ const float startAngle1, -+ const float endAngle2, -+ const CDrawStyle drawStyle) -+{ -+ if (auto cd = DrawBlock::begin(*this)) { -+ cairo_save(cr); -+ CPoint center = rect.getCenter(); -+ cairo_translate(cr, center.x, center.y); -+ cairo_scale(cr, rect.getWidth() / 2.0, rect.getHeight() / 2.0); -+ cairo_arc(cr, 0, 0, 1, startAngle1 / 180.0 * M_PI, endAngle2 / 180.0 * M_PI); -+ cairo_restore(cr); -+ draw(drawStyle); -+ } - } - - //----------------------------------------------------------------------------- --void Context::drawEllipse (const CRect& rect, const CDrawStyle drawStyle) -+void Context::drawEllipse(const CRect &rect, const CDrawStyle drawStyle) - { -- if (auto cd = DrawBlock::begin (*this)) -- { -- CPoint center = rect.getCenter (); -- cairo_translate (cr, center.x, center.y); -- cairo_scale (cr, 2.0 / rect.getWidth (), 2.0 / rect.getHeight ()); -- cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); -- draw (drawStyle); -- } -+ if (auto cd = DrawBlock::begin(*this)) { -+ cairo_save(cr); -+ CPoint center = rect.getCenter(); -+ cairo_translate(cr, center.x, center.y); -+ cairo_scale(cr, rect.getWidth() / 2.0, rect.getHeight() / 2.0); -+ cairo_arc(cr, 0, 0, 1, 0, 2 * M_PI); -+ cairo_restore(cr); -+ draw(drawStyle); -+ } - } - - //----------------------------------------------------------------------------- --void Context::drawPoint (const CPoint& point, const CColor& color) -+void Context::drawPoint(const CPoint &point, const CColor &color) - { -- if (auto cd = DrawBlock::begin (*this)) -- { -- setSourceColor (color); -- cairo_rectangle (cr, point.x + 0.5, point.y + 0.5, 1, 1); -- cairo_fill (cr); -- } -- checkCairoStatus (cr); -+ if (auto cd = DrawBlock::begin(*this)) { -+ setSourceColor(color); -+ cairo_rectangle(cr, point.x, point.y, 1, 1); -+ cairo_fill(cr); -+ } -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --void Context::drawBitmap (CBitmap* bitmap, const CRect& dest, const CPoint& offset, float alpha) --{ -- if (auto cd = DrawBlock::begin (*this)) -- { -- double transformedScaleFactor = getScaleFactor (); -- CGraphicsTransform t = getCurrentTransform (); -- if (t.m11 == t.m22 && t.m12 == 0 && t.m21 == 0) -- transformedScaleFactor *= t.m11; -- auto cairoBitmap = -- bitmap->getBestPlatformBitmapForScaleFactor (transformedScaleFactor).cast (); -- if (cairoBitmap) -- { -- cairo_translate (cr, dest.left, dest.top); -- cairo_rectangle (cr, 0, 0, dest.getWidth (), dest.getHeight ()); -- cairo_clip (cr); -- -- // Setup a pattern for scaling bitmaps and take it as source afterwards. -- auto pattern = cairo_pattern_create_for_surface (cairoBitmap->getSurface ()); -- cairo_matrix_t matrix; -- cairo_pattern_get_matrix (pattern, &matrix); -- cairo_matrix_init_scale (&matrix, cairoBitmap->getScaleFactor (), -- cairoBitmap->getScaleFactor ()); -- cairo_matrix_translate (&matrix, offset.x, offset.y); -- cairo_pattern_set_matrix (pattern, &matrix); -- cairo_set_source (cr, pattern); -- -- cairo_rectangle (cr, -offset.x, -offset.y, dest.getWidth () + offset.x, -- dest.getHeight () + offset.y); -- alpha *= getGlobalAlpha (); -- if (alpha != 1.f) -- { -- cairo_paint_with_alpha (cr, alpha); -- } -- else -- { -- cairo_fill (cr); -- } -- -- cairo_pattern_destroy (pattern); -- } -- } -- checkCairoStatus (cr); -+void Context::drawBitmap( -+ CBitmap *bitmap, const CRect &dest, const CPoint &offset, float alpha) -+{ -+ if (auto cd = DrawBlock::begin(*this)) { -+ double transformedScaleFactor = getScaleFactor(); -+ CGraphicsTransform t = getCurrentTransform(); -+ if (t.m11 == t.m22 && t.m12 == 0 && t.m21 == 0) transformedScaleFactor *= t.m11; -+ auto cairoBitmap = bitmap->getBestPlatformBitmapForScaleFactor(transformedScaleFactor) -+ .cast(); -+ if (cairoBitmap) { -+ cairo_translate(cr, dest.left, dest.top); -+ cairo_rectangle(cr, 0, 0, dest.getWidth(), dest.getHeight()); -+ cairo_clip(cr); -+ -+ // Setup a pattern for scaling bitmaps and take it as source afterwards. -+ auto pattern = cairo_pattern_create_for_surface(cairoBitmap->getSurface()); -+ cairo_matrix_t matrix; -+ cairo_pattern_get_matrix(pattern, &matrix); -+ cairo_matrix_init_scale( -+ &matrix, cairoBitmap->getScaleFactor(), cairoBitmap->getScaleFactor()); -+ cairo_matrix_translate(&matrix, offset.x, offset.y); -+ cairo_pattern_set_matrix(pattern, &matrix); -+ cairo_set_source(cr, pattern); -+ -+ cairo_rectangle( -+ cr, -offset.x, -offset.y, dest.getWidth() + offset.x, -+ dest.getHeight() + offset.y); -+ alpha *= getGlobalAlpha(); -+ if (alpha != 1.f) { -+ cairo_paint_with_alpha(cr, alpha); -+ } else { -+ cairo_fill(cr); -+ } -+ -+ cairo_pattern_destroy(pattern); -+ } -+ } -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --void Context::clearRect (const CRect& rect) -+void Context::clearRect(const CRect &rect) - { -- if (auto cd = DrawBlock::begin (*this)) -- { -- cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); -- cairo_rectangle (cr, rect.left, rect.top, rect.getWidth (), rect.getHeight ()); -- cairo_fill (cr); -- } -- checkCairoStatus (cr); -+ if (auto cd = DrawBlock::begin(*this)) { -+ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); -+ cairo_rectangle(cr, rect.left, rect.top, rect.getWidth(), rect.getHeight()); -+ cairo_fill(cr); -+ } -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --CGraphicsPath* Context::createGraphicsPath () -+CGraphicsPath *Context::createGraphicsPath() - { -- if (!graphicsPathFactory) -- graphicsPathFactory = std::make_shared (cr); -- return new CGraphicsPath (graphicsPathFactory); -+ if (!graphicsPathFactory) -+ graphicsPathFactory = std::make_shared(cr); -+ return new CGraphicsPath(graphicsPathFactory); - } - - //----------------------------------------------------------------------------- --CGraphicsPath* Context::createTextPath (const CFontRef font, UTF8StringPtr text) -+CGraphicsPath *Context::createTextPath(const CFontRef font, UTF8StringPtr text) - { - #warning TODO: Implementation -- return nullptr; -+ return nullptr; - } - - //----------------------------------------------------------------------------- --void Context::drawGraphicsPath (CGraphicsPath* path, CDrawContext::PathDrawMode mode, -- CGraphicsTransform* transformation) --{ -- if (path) -- { -- auto graphicsPath = dynamic_cast ( -- path->getPlatformPath (PlatformGraphicsPathFillMode::Ignored).get ()); -- if (!graphicsPath) -- return; -- if (auto cd = DrawBlock::begin (*this)) -- { -- std::unique_ptr alignedPath; -- if (needPixelAlignment (getDrawMode ())) -- alignedPath = graphicsPath->copyPixelAlign (getCurrentTransform ()); -- auto p = alignedPath ? alignedPath->getCairoPath () : graphicsPath->getCairoPath (); -- if (transformation) -- { -- cairo_matrix_t currentMatrix; -- cairo_matrix_t resultMatrix; -- auto matrix = convert (*transformation); -- cairo_get_matrix (cr, ¤tMatrix); -- cairo_matrix_multiply (&resultMatrix, ¤tMatrix, &matrix); -- cairo_set_matrix (cr, &resultMatrix); -- } -- cairo_append_path (cr, p); -- switch (mode) -- { -- case PathDrawMode::kPathFilled: -- { -- setSourceColor (getFillColor ()); -- cairo_fill (cr); -- break; -- } -- case PathDrawMode::kPathFilledEvenOdd: -- { -- setSourceColor (getFillColor ()); -- cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); -- cairo_fill (cr); -- break; -- } -- case PathDrawMode::kPathStroked: -- { -- setupCurrentStroke (); -- setSourceColor (getFrameColor ()); -- cairo_stroke (cr); -- break; -- } -- } -- } -- } -- checkCairoStatus (cr); -+void Context::drawGraphicsPath( -+ CGraphicsPath *path, -+ CDrawContext::PathDrawMode mode, -+ CGraphicsTransform *transformation) -+{ -+ if (path) { -+ auto graphicsPath = dynamic_cast( -+ path->getPlatformPath(PlatformGraphicsPathFillMode::Ignored).get()); -+ if (!graphicsPath) return; -+ if (auto cd = DrawBlock::begin(*this)) { -+ std::unique_ptr alignedPath; -+ if (needPixelAlignment(getDrawMode())) -+ alignedPath = graphicsPath->copyPixelAlign(getCurrentTransform()); -+ auto p = alignedPath ? alignedPath->getCairoPath() : graphicsPath->getCairoPath(); -+ if (transformation) { -+ cairo_matrix_t currentMatrix; -+ cairo_matrix_t resultMatrix; -+ auto matrix = convert(*transformation); -+ cairo_get_matrix(cr, ¤tMatrix); -+ cairo_matrix_multiply(&resultMatrix, ¤tMatrix, &matrix); -+ cairo_set_matrix(cr, &resultMatrix); -+ } -+ cairo_append_path(cr, p); -+ switch (mode) { -+ case PathDrawMode::kPathFilled: { -+ setSourceColor(getFillColor()); -+ cairo_fill(cr); -+ break; -+ } -+ case PathDrawMode::kPathFilledEvenOdd: { -+ setSourceColor(getFillColor()); -+ cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); -+ cairo_fill(cr); -+ break; -+ } -+ case PathDrawMode::kPathStroked: { -+ setupCurrentStroke(); -+ setSourceColor(getFrameColor()); -+ cairo_stroke(cr); -+ break; -+ } -+ } -+ } -+ } -+ checkCairoStatus(cr); - } - - //----------------------------------------------------------------------------- --void Context::fillLinearGradient (CGraphicsPath* path, const CGradient& gradient, -- const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, -- CGraphicsTransform* transformation) --{ -- if (path) -- { -- auto graphicsPath = dynamic_cast ( -- path->getPlatformPath (PlatformGraphicsPathFillMode::Ignored).get ()); -- if (!graphicsPath) -- return; -- std::unique_ptr alignedPath; -- if (needPixelAlignment (getDrawMode ())) -- alignedPath = graphicsPath->copyPixelAlign (getCurrentTransform ()); -- if (auto cairoGradient = dynamic_cast (gradient.getPlatformGradient ().get ())) -- { -- if (auto cd = DrawBlock::begin (*this)) -- { -- auto p = alignedPath ? alignedPath->getCairoPath () : graphicsPath->getCairoPath (); -- cairo_append_path (cr, p); -- cairo_set_source (cr, cairoGradient->getLinearGradient (startPoint, endPoint)); -- if (evenOdd) -- { -- cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); -- cairo_fill (cr); -- } -- else -- { -- cairo_fill (cr); -- } -- } -- } -- } -+void Context::fillLinearGradient( -+ CGraphicsPath *path, -+ const CGradient &gradient, -+ const CPoint &startPoint, -+ const CPoint &endPoint, -+ bool evenOdd, -+ CGraphicsTransform *transformation) -+{ -+ if (path) { -+ auto graphicsPath = dynamic_cast( -+ path->getPlatformPath(PlatformGraphicsPathFillMode::Ignored).get()); -+ if (!graphicsPath) return; -+ std::unique_ptr alignedPath; -+ if (needPixelAlignment(getDrawMode())) -+ alignedPath = graphicsPath->copyPixelAlign(getCurrentTransform()); -+ if ( -+ auto cairoGradient -+ = dynamic_cast(gradient.getPlatformGradient().get())) { -+ if (auto cd = DrawBlock::begin(*this)) { -+ auto p = alignedPath ? alignedPath->getCairoPath() : graphicsPath->getCairoPath(); -+ cairo_append_path(cr, p); -+ cairo_set_source(cr, cairoGradient->getLinearGradient(startPoint, endPoint)); -+ if (evenOdd) { -+ cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); -+ cairo_fill(cr); -+ } else { -+ cairo_fill(cr); -+ } -+ } -+ } -+ } - } - - //----------------------------------------------------------------------------- --void Context::fillRadialGradient (CGraphicsPath* path, const CGradient& gradient, -- const CPoint& center, CCoord radius, const CPoint& originOffset, -- bool evenOdd, CGraphicsTransform* transformation) -+void Context::fillRadialGradient( -+ CGraphicsPath *path, -+ const CGradient &gradient, -+ const CPoint ¢er, -+ CCoord radius, -+ const CPoint &originOffset, -+ bool evenOdd, -+ CGraphicsTransform *transformation) - { - #warning TODO: Implementation -- auto cd = DrawBlock::begin (*this); -- if (cd) -- { -- } -+ auto cd = DrawBlock::begin(*this); -+ if (cd) { -+ } - } - - //----------------------------------------------------------------------------- --} // Cairo --} // VSTGUI -+} // namespace Cairo -+} // namespace VSTGUI diff --git a/ci/linux_patch/x11frame.cpp.diff b/ci/linux_patch/x11frame.cpp.diff deleted file mode 100644 index 733da1ff..00000000 --- a/ci/linux_patch/x11frame.cpp.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/vstgui/lib/platform/linux/x11frame.cpp b/vstgui/lib/platform/linux/x11frame.cpp -index 99393735..5a549e40 100644 ---- a/vstgui/lib/platform/linux/x11frame.cpp -+++ b/vstgui/lib/platform/linux/x11frame.cpp -@@ -177,6 +177,7 @@ struct DrawHandler - - ~DrawHandler () - { -+ cairo_device_finish (device); - cairo_device_destroy (device); - } -