Move SkAndroidSDKCanvas to tools and ensure that it is built on all Android builds
authordjsollen <djsollen@google.com>
Fri, 18 Dec 2015 17:34:08 +0000 (09:34 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 18 Dec 2015 17:34:08 +0000 (09:34 -0800)
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1536013003

Review URL: https://codereview.chromium.org/1536013003

gyp/bench.gyp
gyp/dm.gyp
gyp/tools.gyp
gyp/utils.gyp
src/utils/android/SkAndroidSDKCanvas.cpp [deleted file]
src/utils/android/SkAndroidSDKCanvas.h [deleted file]
tools/android/SkAndroidSDKCanvas.cpp [new file with mode: 0644]
tools/android/SkAndroidSDKCanvas.h [new file with mode: 0644]

index c7a03b8d04158fb46ec4f27586f226908c1dac36..7b84ab9d37ed3dc96b8af587c4afc35253ff4492 100644 (file)
@@ -39,7 +39,7 @@
             '../../../frameworks/base/libs/hwui/',
           ],
           'dependencies': [
-            'utils.gyp:android_utils',
+            'tools.gyp:android_utils',
           ],
         }],
       ],
index 2a4c1c2c4311f88dd90a21f12bc0f58fe8e3076d..a05d079b8c0b986773b0176decf736c139984509 100644 (file)
@@ -27,7 +27,7 @@
                 '../dm/DMSrcSinkAndroid.cpp',
               ],
               'dependencies': [
-                'utils.gyp:android_utils',
+                'tools.gyp:android_utils',
               ],
           }],
         ],
index 590ac3b1755b7d2b5b1a7a37c3fc4e14465ae464..1e7eabbecf8810b7a451f7cb0ee6b1ab000ed5f2 100644 (file)
             ],
           },
         ],
+        [ 'skia_os == "android"',
+          {
+            'dependencies': [
+               # Build this by default to catch compile errors more quickly, since
+               # the only other time this code is exercised in the android framework
+              'android_utils',
+            ],
+          },
+        ],
+      ],
+    },
+    {
+      'target_name': 'android_utils',
+      'type': 'static_library',
+      'dependencies': [
+        'core.gyp:core',
+      ],
+      'sources': [
+        '../tools/android/SkAndroidSDKCanvas.h',
+        '../tools/android/SkAndroidSDKCanvas.cpp',
       ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '../tools/android',
+        ],
+      },
     },
     {
         'target_name': 'dump_record',
index 39486deb5611b1f7c68dc1f431af768da864180a..eb225e62a25c85d99e39ee0f5a5088eaaf277916 100644 (file)
         ],
       },
     },
-    {
-      'target_name': 'android_utils',
-      'product_name': 'skia_android_utils',
-      'type': 'static_library',
-      'standalone_static_library': 1,
-      'dependencies': [
-        'core.gyp:*',
-      ],
-      'sources': [
-        '../src/utils/android/SkAndroidSDKCanvas.h',
-        '../src/utils/android/SkAndroidSDKCanvas.cpp',
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          '../src/utils/android',
-        ],
-      },
-    },
   ],
 }
diff --git a/src/utils/android/SkAndroidSDKCanvas.cpp b/src/utils/android/SkAndroidSDKCanvas.cpp
deleted file mode 100644 (file)
index 45fcc75..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkAndroidSDKCanvas.h"
-
-#include "SkColorFilter.h"
-#include "SkPaint.h"
-#include "SkPathEffect.h"
-#include "SkShader.h"
-#include "SkTLazy.h"
-
-namespace {
-
-/** Discard SkShaders not exposed by the Android Java API. */
-
-void CheckShader(SkPaint* paint) {
-    SkShader* shader = paint->getShader();
-    if (!shader) {
-        return;
-    }
-
-    if (shader->isABitmap()) {
-        return;
-    }
-    if (shader->asACompose(nullptr)) {
-        return;
-    }
-    SkShader::GradientType gtype = shader->asAGradient(nullptr);
-    if (gtype == SkShader::kLinear_GradientType ||
-        gtype == SkShader::kRadial_GradientType ||
-        gtype == SkShader::kSweep_GradientType) {
-        return;
-    }
-    paint->setShader(nullptr);
-}
-
-void Filter(SkPaint* paint) {
-
-    uint32_t flags = paint->getFlags();
-    flags &= ~SkPaint::kLCDRenderText_Flag;
-    paint->setFlags(flags);
-
-    // Android doesn't support Xfermodes above kLighten_Mode
-    SkXfermode::Mode mode;
-    SkXfermode::AsMode(paint->getXfermode(), &mode);
-    if (mode > SkXfermode::kLighten_Mode) {
-        paint->setXfermode(nullptr);
-    }
-
-    // Force bilinear scaling or none
-    if (paint->getFilterQuality() != kNone_SkFilterQuality) {
-        paint->setFilterQuality(kLow_SkFilterQuality);
-    }
-
-    CheckShader(paint);
-
-    // Android SDK only supports mode & matrix color filters
-    // (and, again, no modes above kLighten_Mode).
-    SkColorFilter* cf = paint->getColorFilter();
-    if (cf) {
-        SkColor color;
-        SkXfermode::Mode mode;
-        SkScalar srcColorMatrix[20];
-        bool isMode = cf->asColorMode(&color, &mode);
-        if (isMode && mode > SkXfermode::kLighten_Mode) {
-            paint->setColorFilter(
-                SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcOver_Mode));
-        } else if (!isMode && !cf->asColorMatrix(srcColorMatrix)) {
-            paint->setColorFilter(nullptr);
-        }
-    }
-
-#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
-    SkPathEffect* pe = paint->getPathEffect();
-    if (pe && !pe->exposedInAndroidJavaAPI()) {
-        paint->setPathEffect(nullptr);
-    }
-#endif
-
-    // TODO: Android doesn't support all the flags that can be passed to
-    // blur filters; we need plumbing to get them out.
-
-    paint->setImageFilter(nullptr);
-    paint->setLooper(nullptr);
-};
-
-}  // namespace
-
-#define FILTER(p)             \
-    SkPaint filteredPaint(p); \
-    Filter(&filteredPaint);
-
-#define FILTER_PTR(p)                          \
-    SkTLazy<SkPaint> lazyPaint;                \
-    SkPaint* filteredPaint = (SkPaint*) p;     \
-    if (p) {                                   \
-        filteredPaint = lazyPaint.set(*p);     \
-        Filter(filteredPaint);                 \
-    }
-
-
-SkAndroidSDKCanvas::SkAndroidSDKCanvas() : fProxyTarget(nullptr) { }
-
-void SkAndroidSDKCanvas::reset(SkCanvas* newTarget) { fProxyTarget = newTarget; }
-
-void SkAndroidSDKCanvas::onDrawPaint(const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawPaint(filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawPoints(PointMode pMode,
-                                               size_t count,
-                                               const SkPoint pts[],
-                                               const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawPoints(pMode, count, pts, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawOval(const SkRect& r, const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawOval(r, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawRect(r, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawRRect(const SkRRect& r, const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawRRect(r, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawPath(path, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawBitmap(const SkBitmap& bitmap,
-                                               SkScalar left,
-                                               SkScalar top,
-                                               const SkPaint* paint) {
-    FILTER_PTR(paint);
-    fProxyTarget->drawBitmap(bitmap, left, top, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
-                                                   const SkRect* src,
-                                                   const SkRect& dst,
-                                                   const SkPaint* paint,
-                                                   SkCanvas::SrcRectConstraint constraint) {
-    FILTER_PTR(paint);
-    fProxyTarget->legacy_drawBitmapRect(bitmap, src, dst, filteredPaint, constraint);
-}
-void SkAndroidSDKCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
-                                                   const SkIRect& center,
-                                                   const SkRect& dst,
-                                                   const SkPaint* paint) {
-    FILTER_PTR(paint);
-    fProxyTarget->drawBitmapNine(bitmap, center, dst, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawVertices(VertexMode vMode,
-                                                 int vertexCount,
-                                                 const SkPoint vertices[],
-                    const SkPoint texs[], const SkColor colors[], SkXfermode* xMode,
-                    const uint16_t indices[], int indexCount,
-                    const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawVertices(vMode, vertexCount, vertices, texs, colors,
-                               xMode, indices, indexCount, filteredPaint);
-}
-
-void SkAndroidSDKCanvas::onDrawDRRect(const SkRRect& outer,
-                                               const SkRRect& inner,
-                                               const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawDRRect(outer, inner, filteredPaint);
-}
-
-void SkAndroidSDKCanvas::onDrawText(const void* text,
-                                             size_t byteLength,
-                                             SkScalar x,
-                                             SkScalar y,
-                                             const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawText(text, byteLength, x, y, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawPosText(const void* text,
-                                                size_t byteLength,
-                                                const SkPoint pos[],
-                                                const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawPosText(text, byteLength, pos, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawPosTextH(const void* text,
-                                                 size_t byteLength,
-                                                 const SkScalar xpos[],
-                                                 SkScalar constY,
-                                                 const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawPosTextH(text, byteLength, xpos, constY, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawTextOnPath(const void* text,
-                                                   size_t byteLength,
-                                                   const SkPath& path,
-                                                   const SkMatrix* matrix,
-                                                   const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawTextOnPath(text, byteLength, path, matrix, filteredPaint);
-}
-void SkAndroidSDKCanvas::onDrawTextBlob(const SkTextBlob* blob,
-                                                 SkScalar x,
-                                                 SkScalar y,
-                                                 const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawTextBlob(blob, x, y, filteredPaint);
-}
-
-void SkAndroidSDKCanvas::onDrawPatch(const SkPoint cubics[12],
-                                              const SkColor colors[4],
-                                              const SkPoint texCoords[4],
-                                              SkXfermode* xmode,
-                                              const SkPaint& paint) {
-    FILTER(paint);
-    fProxyTarget->drawPatch(cubics, colors, texCoords, xmode, filteredPaint);
-}
-
-
-void SkAndroidSDKCanvas::onDrawImage(const SkImage* image,
-                                              SkScalar x,
-                                              SkScalar y,
-                                              const SkPaint* paint) {
-    FILTER_PTR(paint);
-    fProxyTarget->drawImage(image, x, y, filteredPaint);
-}
-
-void SkAndroidSDKCanvas::onDrawImageRect(const SkImage* image,
-                                         const SkRect* in,
-                                         const SkRect& out,
-                                         const SkPaint* paint,
-                                         SrcRectConstraint constraint) {
-    FILTER_PTR(paint);
-    fProxyTarget->legacy_drawImageRect(image, in, out, filteredPaint, constraint);
-}
-
-void SkAndroidSDKCanvas::onDrawPicture(const SkPicture* picture,
-                                       const SkMatrix* matrix,
-                                       const SkPaint* paint) {
-    FILTER_PTR(paint);
-    fProxyTarget->drawPicture(picture, matrix, filteredPaint);
-}
-
-void SkAndroidSDKCanvas::onDrawAtlas(const SkImage* atlas,
-                                     const SkRSXform xform[],
-                                     const SkRect tex[],
-                                     const SkColor colors[],
-                                     int count,
-                                     SkXfermode::Mode mode,
-                                     const SkRect* cullRect,
-                                     const SkPaint* paint) {
-    FILTER_PTR(paint);
-    fProxyTarget->drawAtlas(atlas, xform, tex, colors, count, mode, cullRect,
-                            filteredPaint);
-}
-
-void SkAndroidSDKCanvas::onDrawImageNine(const SkImage* image,
-                                         const SkIRect& center,
-                                         const SkRect& dst,
-                                         const SkPaint* paint) {
-    FILTER_PTR(paint);
-    fProxyTarget->drawImageNine(image, center, dst, filteredPaint);
-}
-
-
-void SkAndroidSDKCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
-    fProxyTarget->drawDrawable(drawable, matrix);
-}
-
-SkISize SkAndroidSDKCanvas::getBaseLayerSize() const {
-    return fProxyTarget->getBaseLayerSize();
-}
-bool SkAndroidSDKCanvas::getClipBounds(SkRect* rect) const {
-    return fProxyTarget->getClipBounds(rect);
-}
-bool SkAndroidSDKCanvas::getClipDeviceBounds(SkIRect* rect) const {
-    return fProxyTarget->getClipDeviceBounds(rect);
-}
-
-bool SkAndroidSDKCanvas::isClipEmpty() const { return fProxyTarget->isClipEmpty(); }
-bool SkAndroidSDKCanvas::isClipRect() const { return fProxyTarget->isClipRect(); }
-
-SkSurface* SkAndroidSDKCanvas::onNewSurface(const SkImageInfo& info,
-                                                     const SkSurfaceProps& props) {
-    return fProxyTarget->newSurface(info, &props);
-}
-
-bool SkAndroidSDKCanvas::onPeekPixels(SkPixmap* pmap) {
-    SkASSERT(pmap);
-    SkImageInfo info;
-    size_t rowBytes;
-    const void* addr = fProxyTarget->peekPixels(&info, &rowBytes);
-    if (addr) {
-        pmap->reset(info, addr, rowBytes);
-        return true;
-    }
-    return false;
-}
-
-bool SkAndroidSDKCanvas::onAccessTopLayerPixels(SkPixmap* pmap) {
-    SkASSERT(pmap);
-    SkImageInfo info;
-    size_t rowBytes; 
-    const void* addr = fProxyTarget->accessTopLayerPixels(&info, &rowBytes, nullptr);
-    if (addr) {
-        pmap->reset(info, addr, rowBytes);
-        return true;
-    }
-    return false;
-}
-
-void SkAndroidSDKCanvas::willSave() {
-    fProxyTarget->save();
-}
-
-SkCanvas::SaveLayerStrategy SkAndroidSDKCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
-    fProxyTarget->saveLayer(rec);
-    return SkCanvas::kNoLayer_SaveLayerStrategy;
-}
-
-void SkAndroidSDKCanvas::willRestore() {
-    fProxyTarget->restore();
-}
-
-void SkAndroidSDKCanvas::didRestore() { }
-
-void SkAndroidSDKCanvas::didConcat(const SkMatrix& m) {
-    fProxyTarget->concat(m);
-}
-
-void SkAndroidSDKCanvas::didSetMatrix(const SkMatrix& m) {
-    fProxyTarget->setMatrix(m);
-}
-
-void SkAndroidSDKCanvas::onClipRect(const SkRect& rect,
-                                             SkRegion::Op op,
-                                             ClipEdgeStyle style) {
-    fProxyTarget->clipRect(rect, op, style);
-}
-
-void SkAndroidSDKCanvas::onClipRRect(const SkRRect& rrect,
-                                              SkRegion::Op op,
-                                              ClipEdgeStyle style) {
-    fProxyTarget->clipRRect(rrect, op, style);
-}
-
-void SkAndroidSDKCanvas::onClipPath(const SkPath& path,
-                                             SkRegion::Op op,
-                                             ClipEdgeStyle style) {
-    fProxyTarget->clipPath(path, op, style);
-}
-
-void SkAndroidSDKCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) {
-    fProxyTarget->clipRegion(region, op);
-}
-
-void SkAndroidSDKCanvas::onDiscard() { fProxyTarget->discard(); }
-
-
diff --git a/src/utils/android/SkAndroidSDKCanvas.h b/src/utils/android/SkAndroidSDKCanvas.h
deleted file mode 100644 (file)
index d8ee0ed..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkAndroidSDKCanvas_DEFINED
-#define SkAndroidSDKCanvas_DEFINED
-
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
-#include "SkPath.h"
-#include "SkRect.h"
-
-/** SkDrawFilter is likely to be deprecated; this is a proxy
-    canvas that does the same thing: alter SkPaint fields.
-
-    onDraw*() functions may have their SkPaint modified, and are then
-    passed on to the same function on proxyTarget. THIS BREAKS CONSTNESS!
-
-    This still suffers one of the same architectural flaws as SkDrawFilter:
-    TextBlob paints are incomplete when filter is called.
-*/
-
-class SkAndroidSDKCanvas : public SkCanvas {
-public:
-    SkAndroidSDKCanvas();
-    void reset(SkCanvas* newTarget);
-
-protected:
-
-    // FILTERING
-
-    void onDrawPaint(const SkPaint& paint) override;
-    void onDrawPoints(PointMode pMode, size_t count, const SkPoint pts[],
-                      const SkPaint& paint) override;
-    void onDrawOval(const SkRect& r, const SkPaint& paint) override;
-    void onDrawRect(const SkRect& r, const SkPaint& paint) override;
-    void onDrawRRect(const SkRRect& r, const SkPaint& paint) override;
-    void onDrawPath(const SkPath& path, const SkPaint& paint) override;
-    void onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
-                      const SkPaint* paint) override;
-    void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                          const SkPaint* paint, SkCanvas::SrcRectConstraint) override;
-    void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
-                          const SkRect& dst, const SkPaint* paint) override;
-    void onDrawVertices(VertexMode vMode, int vertexCount, const SkPoint vertices[],
-                        const SkPoint texs[], const SkColor colors[], SkXfermode* xMode,
-                        const uint16_t indices[], int indexCount,
-                        const SkPaint& paint) override;
-
-    void onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
-                      const SkPaint& paint) override;
-
-    void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
-                    const SkPaint& paint) override;
-    void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
-                       const SkPaint& paint) override;
-    void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
-                        SkScalar constY, const SkPaint& paint) override;
-    void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
-                          const SkMatrix* matrix, const SkPaint& paint) override;
-    void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
-                        const SkPaint& paint) override;
-
-    void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
-                     const SkPoint texCoords[4], SkXfermode* xmode,
-                     const SkPaint& paint) override;
-
-    void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
-    void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
-                         SrcRectConstraint) override;
-    void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
-    void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[],
-                     const SkColor[], int count, SkXfermode::Mode,
-                     const SkRect* cull, const SkPaint*) override;
-    void onDrawImageNine(const SkImage*, const SkIRect& center,
-                         const SkRect& dst, const SkPaint*) override;
-
-    // PASS THROUGH
-
-    void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
-    SkISize getBaseLayerSize() const override;
-    bool getClipBounds(SkRect*) const override;
-    bool getClipDeviceBounds(SkIRect*) const override;
-    bool isClipEmpty() const override;
-    bool isClipRect() const override;
-    SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
-    bool onPeekPixels(SkPixmap*) override;
-    bool onAccessTopLayerPixels(SkPixmap*) override;
-    void willSave() override;
-    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
-    void willRestore() override;
-    void didRestore() override;
-    void didConcat(const SkMatrix&) override;
-    void didSetMatrix(const SkMatrix&) override;
-    void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
-    void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
-    void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
-    void onClipRegion(const SkRegion&, SkRegion::Op) override;
-    void onDiscard() override;
-
-protected:
-    SkCanvas* fProxyTarget;
-};
-
-#endif  // SkAndroidSDKCanvas_DEFINED
-
diff --git a/tools/android/SkAndroidSDKCanvas.cpp b/tools/android/SkAndroidSDKCanvas.cpp
new file mode 100644 (file)
index 0000000..45fcc75
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkAndroidSDKCanvas.h"
+
+#include "SkColorFilter.h"
+#include "SkPaint.h"
+#include "SkPathEffect.h"
+#include "SkShader.h"
+#include "SkTLazy.h"
+
+namespace {
+
+/** Discard SkShaders not exposed by the Android Java API. */
+
+void CheckShader(SkPaint* paint) {
+    SkShader* shader = paint->getShader();
+    if (!shader) {
+        return;
+    }
+
+    if (shader->isABitmap()) {
+        return;
+    }
+    if (shader->asACompose(nullptr)) {
+        return;
+    }
+    SkShader::GradientType gtype = shader->asAGradient(nullptr);
+    if (gtype == SkShader::kLinear_GradientType ||
+        gtype == SkShader::kRadial_GradientType ||
+        gtype == SkShader::kSweep_GradientType) {
+        return;
+    }
+    paint->setShader(nullptr);
+}
+
+void Filter(SkPaint* paint) {
+
+    uint32_t flags = paint->getFlags();
+    flags &= ~SkPaint::kLCDRenderText_Flag;
+    paint->setFlags(flags);
+
+    // Android doesn't support Xfermodes above kLighten_Mode
+    SkXfermode::Mode mode;
+    SkXfermode::AsMode(paint->getXfermode(), &mode);
+    if (mode > SkXfermode::kLighten_Mode) {
+        paint->setXfermode(nullptr);
+    }
+
+    // Force bilinear scaling or none
+    if (paint->getFilterQuality() != kNone_SkFilterQuality) {
+        paint->setFilterQuality(kLow_SkFilterQuality);
+    }
+
+    CheckShader(paint);
+
+    // Android SDK only supports mode & matrix color filters
+    // (and, again, no modes above kLighten_Mode).
+    SkColorFilter* cf = paint->getColorFilter();
+    if (cf) {
+        SkColor color;
+        SkXfermode::Mode mode;
+        SkScalar srcColorMatrix[20];
+        bool isMode = cf->asColorMode(&color, &mode);
+        if (isMode && mode > SkXfermode::kLighten_Mode) {
+            paint->setColorFilter(
+                SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcOver_Mode));
+        } else if (!isMode && !cf->asColorMatrix(srcColorMatrix)) {
+            paint->setColorFilter(nullptr);
+        }
+    }
+
+#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
+    SkPathEffect* pe = paint->getPathEffect();
+    if (pe && !pe->exposedInAndroidJavaAPI()) {
+        paint->setPathEffect(nullptr);
+    }
+#endif
+
+    // TODO: Android doesn't support all the flags that can be passed to
+    // blur filters; we need plumbing to get them out.
+
+    paint->setImageFilter(nullptr);
+    paint->setLooper(nullptr);
+};
+
+}  // namespace
+
+#define FILTER(p)             \
+    SkPaint filteredPaint(p); \
+    Filter(&filteredPaint);
+
+#define FILTER_PTR(p)                          \
+    SkTLazy<SkPaint> lazyPaint;                \
+    SkPaint* filteredPaint = (SkPaint*) p;     \
+    if (p) {                                   \
+        filteredPaint = lazyPaint.set(*p);     \
+        Filter(filteredPaint);                 \
+    }
+
+
+SkAndroidSDKCanvas::SkAndroidSDKCanvas() : fProxyTarget(nullptr) { }
+
+void SkAndroidSDKCanvas::reset(SkCanvas* newTarget) { fProxyTarget = newTarget; }
+
+void SkAndroidSDKCanvas::onDrawPaint(const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawPaint(filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawPoints(PointMode pMode,
+                                               size_t count,
+                                               const SkPoint pts[],
+                                               const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawPoints(pMode, count, pts, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawOval(const SkRect& r, const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawOval(r, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawRect(r, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawRRect(const SkRRect& r, const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawRRect(r, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawPath(path, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawBitmap(const SkBitmap& bitmap,
+                                               SkScalar left,
+                                               SkScalar top,
+                                               const SkPaint* paint) {
+    FILTER_PTR(paint);
+    fProxyTarget->drawBitmap(bitmap, left, top, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
+                                                   const SkRect* src,
+                                                   const SkRect& dst,
+                                                   const SkPaint* paint,
+                                                   SkCanvas::SrcRectConstraint constraint) {
+    FILTER_PTR(paint);
+    fProxyTarget->legacy_drawBitmapRect(bitmap, src, dst, filteredPaint, constraint);
+}
+void SkAndroidSDKCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
+                                                   const SkIRect& center,
+                                                   const SkRect& dst,
+                                                   const SkPaint* paint) {
+    FILTER_PTR(paint);
+    fProxyTarget->drawBitmapNine(bitmap, center, dst, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawVertices(VertexMode vMode,
+                                                 int vertexCount,
+                                                 const SkPoint vertices[],
+                    const SkPoint texs[], const SkColor colors[], SkXfermode* xMode,
+                    const uint16_t indices[], int indexCount,
+                    const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawVertices(vMode, vertexCount, vertices, texs, colors,
+                               xMode, indices, indexCount, filteredPaint);
+}
+
+void SkAndroidSDKCanvas::onDrawDRRect(const SkRRect& outer,
+                                               const SkRRect& inner,
+                                               const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawDRRect(outer, inner, filteredPaint);
+}
+
+void SkAndroidSDKCanvas::onDrawText(const void* text,
+                                             size_t byteLength,
+                                             SkScalar x,
+                                             SkScalar y,
+                                             const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawText(text, byteLength, x, y, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawPosText(const void* text,
+                                                size_t byteLength,
+                                                const SkPoint pos[],
+                                                const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawPosText(text, byteLength, pos, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawPosTextH(const void* text,
+                                                 size_t byteLength,
+                                                 const SkScalar xpos[],
+                                                 SkScalar constY,
+                                                 const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawPosTextH(text, byteLength, xpos, constY, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawTextOnPath(const void* text,
+                                                   size_t byteLength,
+                                                   const SkPath& path,
+                                                   const SkMatrix* matrix,
+                                                   const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawTextOnPath(text, byteLength, path, matrix, filteredPaint);
+}
+void SkAndroidSDKCanvas::onDrawTextBlob(const SkTextBlob* blob,
+                                                 SkScalar x,
+                                                 SkScalar y,
+                                                 const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawTextBlob(blob, x, y, filteredPaint);
+}
+
+void SkAndroidSDKCanvas::onDrawPatch(const SkPoint cubics[12],
+                                              const SkColor colors[4],
+                                              const SkPoint texCoords[4],
+                                              SkXfermode* xmode,
+                                              const SkPaint& paint) {
+    FILTER(paint);
+    fProxyTarget->drawPatch(cubics, colors, texCoords, xmode, filteredPaint);
+}
+
+
+void SkAndroidSDKCanvas::onDrawImage(const SkImage* image,
+                                              SkScalar x,
+                                              SkScalar y,
+                                              const SkPaint* paint) {
+    FILTER_PTR(paint);
+    fProxyTarget->drawImage(image, x, y, filteredPaint);
+}
+
+void SkAndroidSDKCanvas::onDrawImageRect(const SkImage* image,
+                                         const SkRect* in,
+                                         const SkRect& out,
+                                         const SkPaint* paint,
+                                         SrcRectConstraint constraint) {
+    FILTER_PTR(paint);
+    fProxyTarget->legacy_drawImageRect(image, in, out, filteredPaint, constraint);
+}
+
+void SkAndroidSDKCanvas::onDrawPicture(const SkPicture* picture,
+                                       const SkMatrix* matrix,
+                                       const SkPaint* paint) {
+    FILTER_PTR(paint);
+    fProxyTarget->drawPicture(picture, matrix, filteredPaint);
+}
+
+void SkAndroidSDKCanvas::onDrawAtlas(const SkImage* atlas,
+                                     const SkRSXform xform[],
+                                     const SkRect tex[],
+                                     const SkColor colors[],
+                                     int count,
+                                     SkXfermode::Mode mode,
+                                     const SkRect* cullRect,
+                                     const SkPaint* paint) {
+    FILTER_PTR(paint);
+    fProxyTarget->drawAtlas(atlas, xform, tex, colors, count, mode, cullRect,
+                            filteredPaint);
+}
+
+void SkAndroidSDKCanvas::onDrawImageNine(const SkImage* image,
+                                         const SkIRect& center,
+                                         const SkRect& dst,
+                                         const SkPaint* paint) {
+    FILTER_PTR(paint);
+    fProxyTarget->drawImageNine(image, center, dst, filteredPaint);
+}
+
+
+void SkAndroidSDKCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
+    fProxyTarget->drawDrawable(drawable, matrix);
+}
+
+SkISize SkAndroidSDKCanvas::getBaseLayerSize() const {
+    return fProxyTarget->getBaseLayerSize();
+}
+bool SkAndroidSDKCanvas::getClipBounds(SkRect* rect) const {
+    return fProxyTarget->getClipBounds(rect);
+}
+bool SkAndroidSDKCanvas::getClipDeviceBounds(SkIRect* rect) const {
+    return fProxyTarget->getClipDeviceBounds(rect);
+}
+
+bool SkAndroidSDKCanvas::isClipEmpty() const { return fProxyTarget->isClipEmpty(); }
+bool SkAndroidSDKCanvas::isClipRect() const { return fProxyTarget->isClipRect(); }
+
+SkSurface* SkAndroidSDKCanvas::onNewSurface(const SkImageInfo& info,
+                                                     const SkSurfaceProps& props) {
+    return fProxyTarget->newSurface(info, &props);
+}
+
+bool SkAndroidSDKCanvas::onPeekPixels(SkPixmap* pmap) {
+    SkASSERT(pmap);
+    SkImageInfo info;
+    size_t rowBytes;
+    const void* addr = fProxyTarget->peekPixels(&info, &rowBytes);
+    if (addr) {
+        pmap->reset(info, addr, rowBytes);
+        return true;
+    }
+    return false;
+}
+
+bool SkAndroidSDKCanvas::onAccessTopLayerPixels(SkPixmap* pmap) {
+    SkASSERT(pmap);
+    SkImageInfo info;
+    size_t rowBytes; 
+    const void* addr = fProxyTarget->accessTopLayerPixels(&info, &rowBytes, nullptr);
+    if (addr) {
+        pmap->reset(info, addr, rowBytes);
+        return true;
+    }
+    return false;
+}
+
+void SkAndroidSDKCanvas::willSave() {
+    fProxyTarget->save();
+}
+
+SkCanvas::SaveLayerStrategy SkAndroidSDKCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
+    fProxyTarget->saveLayer(rec);
+    return SkCanvas::kNoLayer_SaveLayerStrategy;
+}
+
+void SkAndroidSDKCanvas::willRestore() {
+    fProxyTarget->restore();
+}
+
+void SkAndroidSDKCanvas::didRestore() { }
+
+void SkAndroidSDKCanvas::didConcat(const SkMatrix& m) {
+    fProxyTarget->concat(m);
+}
+
+void SkAndroidSDKCanvas::didSetMatrix(const SkMatrix& m) {
+    fProxyTarget->setMatrix(m);
+}
+
+void SkAndroidSDKCanvas::onClipRect(const SkRect& rect,
+                                             SkRegion::Op op,
+                                             ClipEdgeStyle style) {
+    fProxyTarget->clipRect(rect, op, style);
+}
+
+void SkAndroidSDKCanvas::onClipRRect(const SkRRect& rrect,
+                                              SkRegion::Op op,
+                                              ClipEdgeStyle style) {
+    fProxyTarget->clipRRect(rrect, op, style);
+}
+
+void SkAndroidSDKCanvas::onClipPath(const SkPath& path,
+                                             SkRegion::Op op,
+                                             ClipEdgeStyle style) {
+    fProxyTarget->clipPath(path, op, style);
+}
+
+void SkAndroidSDKCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) {
+    fProxyTarget->clipRegion(region, op);
+}
+
+void SkAndroidSDKCanvas::onDiscard() { fProxyTarget->discard(); }
+
+
diff --git a/tools/android/SkAndroidSDKCanvas.h b/tools/android/SkAndroidSDKCanvas.h
new file mode 100644 (file)
index 0000000..d8ee0ed
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkAndroidSDKCanvas_DEFINED
+#define SkAndroidSDKCanvas_DEFINED
+
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkRect.h"
+
+/** SkDrawFilter is likely to be deprecated; this is a proxy
+    canvas that does the same thing: alter SkPaint fields.
+
+    onDraw*() functions may have their SkPaint modified, and are then
+    passed on to the same function on proxyTarget. THIS BREAKS CONSTNESS!
+
+    This still suffers one of the same architectural flaws as SkDrawFilter:
+    TextBlob paints are incomplete when filter is called.
+*/
+
+class SkAndroidSDKCanvas : public SkCanvas {
+public:
+    SkAndroidSDKCanvas();
+    void reset(SkCanvas* newTarget);
+
+protected:
+
+    // FILTERING
+
+    void onDrawPaint(const SkPaint& paint) override;
+    void onDrawPoints(PointMode pMode, size_t count, const SkPoint pts[],
+                      const SkPaint& paint) override;
+    void onDrawOval(const SkRect& r, const SkPaint& paint) override;
+    void onDrawRect(const SkRect& r, const SkPaint& paint) override;
+    void onDrawRRect(const SkRRect& r, const SkPaint& paint) override;
+    void onDrawPath(const SkPath& path, const SkPaint& paint) override;
+    void onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+                      const SkPaint* paint) override;
+    void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
+                          const SkPaint* paint, SkCanvas::SrcRectConstraint) override;
+    void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+                          const SkRect& dst, const SkPaint* paint) override;
+    void onDrawVertices(VertexMode vMode, int vertexCount, const SkPoint vertices[],
+                        const SkPoint texs[], const SkColor colors[], SkXfermode* xMode,
+                        const uint16_t indices[], int indexCount,
+                        const SkPaint& paint) override;
+
+    void onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+                      const SkPaint& paint) override;
+
+    void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+                    const SkPaint& paint) override;
+    void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+                       const SkPaint& paint) override;
+    void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+                        SkScalar constY, const SkPaint& paint) override;
+    void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+                          const SkMatrix* matrix, const SkPaint& paint) override;
+    void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                        const SkPaint& paint) override;
+
+    void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                     const SkPoint texCoords[4], SkXfermode* xmode,
+                     const SkPaint& paint) override;
+
+    void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
+    void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
+                         SrcRectConstraint) override;
+    void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
+    void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[],
+                     const SkColor[], int count, SkXfermode::Mode,
+                     const SkRect* cull, const SkPaint*) override;
+    void onDrawImageNine(const SkImage*, const SkIRect& center,
+                         const SkRect& dst, const SkPaint*) override;
+
+    // PASS THROUGH
+
+    void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
+    SkISize getBaseLayerSize() const override;
+    bool getClipBounds(SkRect*) const override;
+    bool getClipDeviceBounds(SkIRect*) const override;
+    bool isClipEmpty() const override;
+    bool isClipRect() const override;
+    SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
+    bool onPeekPixels(SkPixmap*) override;
+    bool onAccessTopLayerPixels(SkPixmap*) override;
+    void willSave() override;
+    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
+    void willRestore() override;
+    void didRestore() override;
+    void didConcat(const SkMatrix&) override;
+    void didSetMatrix(const SkMatrix&) override;
+    void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
+    void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
+    void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
+    void onClipRegion(const SkRegion&, SkRegion::Op) override;
+    void onDiscard() override;
+
+protected:
+    SkCanvas* fProxyTarget;
+};
+
+#endif  // SkAndroidSDKCanvas_DEFINED
+