[Libreoffice-commits] core.git: Branch 'feature/skia' - RepositoryExternal.mk vcl/inc vcl/skia

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Thu Oct 17 22:32:06 UTC 2019


 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.vajngerl at collabora.co.uk>
AuthorDate: Fri Oct 18 00:29:46 2019 +0200
Commit:     Tomaž Vajngerl <tomaz.vajngerl at 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,


More information about the Libreoffice-commits mailing list