RepositoryExternal.mk | 1 vcl/inc/skia/gdiimpl.hxx | 2 vcl/skia/gdiimpl.cxx | 128 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 119 insertions(+), 12 deletions(-)
New commits: commit d6646488423e761f86e9eee664c6b7f7bf212aea Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri Oct 18 00:29:46 2019 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Fri Oct 18 00:29:46 2019 +0200 skia: implement invert operation Change-Id: I248518283ee6a4604bc45f36f2af3804a15f5652 diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index 049ab3dbe317..c7963c83c380 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -115,6 +115,7 @@ ifneq ($(ENABLE_SKIA),) define gb_LinkTarget__use_skia $(call gb_LinkTarget_set_include,$(1),\ -I$(call gb_UnpackedTarball_get_dir,skia)/include/core \ + -I$(call gb_UnpackedTarball_get_dir,skia)/include/effects \ -I$(call gb_UnpackedTarball_get_dir,skia)/include/config \ -I$(call gb_UnpackedTarball_get_dir,skia)/include/third_party/vulkan \ -I$(call gb_UnpackedTarball_get_dir,skia) \ diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx index c4a1d74cc9ac..e0f5074c49d2 100644 --- a/vcl/inc/skia/gdiimpl.hxx +++ b/vcl/inc/skia/gdiimpl.hxx @@ -203,6 +203,8 @@ protected: bool isOffscreen() const { return mProvider == nullptr || mProvider->IsOffScreen(); } + void invert(basegfx::B2DPolygon const& rPoly, SalInvert eFlags); + protected: // get the width of the device int GetWidth() const { return mProvider ? mProvider->GetWidth() : 1; } diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index 6fbb82f8c1b5..2f0519bb3d16 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -27,11 +27,51 @@ #include <SkCanvas.h> #include <SkPath.h> #include <SkRegion.h> +#include <SkDashPathEffect.h> + +#include <basegfx/polygon/b2dpolygontools.hxx> #ifdef DBG_UTIL #include <fstream> #endif +namespace +{ +// Create Skia Path from B2DPolygon +// TODO - take bezier curves into account +// TODO - use this for all Polygon / PolyPolygon needs +static SkPath lclPolygonToPath(const basegfx::B2DPolygon& rPolygon) +{ + SkPath aPath; + + const sal_uInt32 nPointCount(rPolygon.count()); + + if (nPointCount == 0) + return aPath; + + const bool bClosePath(rPolygon.isClosed()); + + bool bFirst = true; + + for (sal_uInt32 nPointIndex = 0; nPointIndex < nPointCount; nPointIndex++) + { + auto const& rPoint = rPolygon.getB2DPoint(nPointIndex); + if (bFirst) + { + aPath.moveTo(rPoint.getX(), rPoint.getY()); + bFirst = false; + } + else + { + aPath.lineTo(rPoint.getX(), rPoint.getY()); + } + } + if (bClosePath) + aPath.close(); + return aPath; +} +} + // Class that triggers flushing the backing buffer when idle. class SkiaFlushIdle : public Idle { @@ -458,22 +498,86 @@ Color SkiaSalGraphicsImpl::getPixel(long nX, long nY) return fromSkColor(bitmap.getColor(nX, nY)); } -void SkiaSalGraphicsImpl::invert(long nX, long nY, long nWidth, long nHeight, SalInvert nFlags) +void SkiaSalGraphicsImpl::invert(basegfx::B2DPolygon const& rPoly, SalInvert eFlags) { - (void)nX; - (void)nY; - (void)nWidth; - (void)nHeight; - (void)nFlags; - // TODO + // TrackFrame just inverts a dashed path around the polygon + if (eFlags == SalInvert::TrackFrame) + { + SkPath aPath = lclPolygonToPath(rPoly); + SkPaint aPaint; + aPaint.setStrokeWidth(2); + float intervals[] = { 4.0f, 4.0f }; + aPaint.setStyle(SkPaint::kStroke_Style); + aPaint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 0)); + aPaint.setColor(SkColorSetARGB(255, 255, 255, 255)); + aPaint.setBlendMode(SkBlendMode::kDifference); + + mSurface->getCanvas()->drawPath(aPath, aPaint); + } + else + { + SkPath aPath = lclPolygonToPath(rPoly); + SkPaint aPaint; + aPaint.setColor(SkColorSetARGB(255, 255, 255, 255)); + aPaint.setStyle(SkPaint::kFill_Style); + aPaint.setBlendMode(SkBlendMode::kDifference); + + // N50 inverts in 4x4 checker pattern + if (eFlags == SalInvert::N50) + { + // This creates 4x4 checker pattern bitmap + // TODO Cache the bitmap + SkBitmap aBitmap; + aBitmap.allocN32Pixels(4, 4); + SkPMColor* scanline; + scanline = aBitmap.getAddr32(0, 0); + *scanline++ = 0xFFFFFFFF; + *scanline++ = 0xFFFFFFFF; + *scanline++ = 0xFF000000; + *scanline++ = 0xFF000000; + scanline = aBitmap.getAddr32(0, 1); + *scanline++ = 0xFFFFFFFF; + *scanline++ = 0xFFFFFFFF; + *scanline++ = 0xFF000000; + *scanline++ = 0xFF000000; + scanline = aBitmap.getAddr32(0, 2); + *scanline++ = 0xFF000000; + *scanline++ = 0xFF000000; + *scanline++ = 0xFFFFFFFF; + *scanline++ = 0xFFFFFFFF; + scanline = aBitmap.getAddr32(0, 3); + *scanline++ = 0xFF000000; + *scanline++ = 0xFF000000; + *scanline++ = 0xFFFFFFFF; + *scanline++ = 0xFFFFFFFF; + // The bitmap is repeated in both directions the checker pattern is as big + // as the polygon (usually rectangle) + aPaint.setShader(aBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat)); + } + + mSurface->getCanvas()->drawPath(aPath, aPaint); + } + scheduleFlush(); } -void SkiaSalGraphicsImpl::invert(sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags) +void SkiaSalGraphicsImpl::invert(long nX, long nY, long nWidth, long nHeight, SalInvert eFlags) { - (void)nPoints; - (void)pPtAry; - (void)nFlags; - abort(); + basegfx::B2DRectangle aRectangle(nX, nY, nX + nWidth, nY + nHeight); + auto aRect = basegfx::utils::createPolygonFromRect(aRectangle); + invert(aRect, eFlags); +} + +void SkiaSalGraphicsImpl::invert(sal_uInt32 nPoints, const SalPoint* pPointArray, SalInvert eFlags) +{ + basegfx::B2DPolygon aPolygon; + aPolygon.append(basegfx::B2DPoint(pPointArray[0].mnX, pPointArray[0].mnY), nPoints); + for (sal_uInt32 i = 1; i < nPoints; ++i) + { + aPolygon.setB2DPoint(i, basegfx::B2DPoint(pPointArray[i].mnX, pPointArray[i].mnY)); + } + aPolygon.setClosed(true); + + invert(aPolygon, eFlags); } bool SkiaSalGraphicsImpl::drawEPS(long nX, long nY, long nWidth, long nHeight, void* pPtr, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits