From 94941da28f69cbca6c3d125ec267fe2efadc0a1d Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Wed, 2 Oct 2019 14:11:25 +0200 Subject: implement Skia setClipRegion() Change-Id: I9e525936bba50b565704ee1b60d7464a7397dc80 --- vcl/skia/gdiimpl.cxx | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'vcl') diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index ba764cbdd0b9..b2341c90632c 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -24,6 +24,7 @@ #include #include +#include #ifdef DBG_UTIL #include @@ -43,26 +44,66 @@ void SkiaSalGraphicsImpl::Init() { // TODO mSurface = SkSurface::MakeRasterN32Premul(GetWidth(), GetHeight()); + mSurface->getCanvas()->save(); // see SetClipRegion() + mClipRegion = vcl::Region(tools::Rectangle(0, 0, GetWidth(), GetHeight())); } void SkiaSalGraphicsImpl::DeInit() { mSurface.reset(); } void SkiaSalGraphicsImpl::freeResources() {} -const vcl::Region& SkiaSalGraphicsImpl::getClipRegion() const { return mClipRegion; } +static SkIRect toSkIRect(const tools::Rectangle& rectangle) +{ + return SkIRect::MakeXYWH(rectangle.Left(), rectangle.Top(), rectangle.GetWidth(), + rectangle.GetHeight()); +} + +static SkRegion toSkRegion(const vcl::Region& region) +{ + if (region.IsEmpty()) + return SkRegion(); + if (region.IsRectangle()) + return SkRegion(toSkIRect(region.GetBoundRect())); + if (!region.HasPolyPolygonOrB2DPolyPolygon()) + { + SkRegion skRegion; + RectangleVector rectangles; + region.GetRegionRectangles(rectangles); + for (const tools::Rectangle& rect : rectangles) + skRegion.op(toSkIRect(rect), SkRegion::kUnion_Op); + return skRegion; + } + abort(); +} bool SkiaSalGraphicsImpl::setClipRegion(const vcl::Region& region) { + if (mClipRegion == region) + return true; mClipRegion = region; + SkCanvas* canvas = mSurface->getCanvas(); + // SkCanvas::clipRegion() can only further reduce the clip region, + // but we need to set the given region, which may extend it. + // So handle that by always having the full clip region saved on the stack + // and always go back to that. SkCanvas::restore() only affects the clip + // and the matrix. + canvas->restore(); + canvas->save(); + canvas->clipRegion(toSkRegion(region)); return true; } +void SkiaSalGraphicsImpl::ResetClipRegion() +{ + setClipRegion(vcl::Region(tools::Rectangle(0, 0, GetWidth(), GetHeight()))); +} + +const vcl::Region& SkiaSalGraphicsImpl::getClipRegion() const { return mClipRegion; } + sal_uInt16 SkiaSalGraphicsImpl::GetBitCount() const { return 32; } long SkiaSalGraphicsImpl::GetGraphicsWidth() const { return GetWidth(); } -void SkiaSalGraphicsImpl::ResetClipRegion() { mClipRegion.SetEmpty(); } - void SkiaSalGraphicsImpl::SetLineColor() { mLineColor = SALCOLOR_NONE; } void SkiaSalGraphicsImpl::SetLineColor(Color nColor) { mLineColor = nColor; } -- cgit