aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/android
diff options
context:
space:
mode:
authorGravatar djsollen <djsollen@google.com>2015-12-18 09:34:08 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-18 09:34:08 -0800
commit14d8fa0f58bf7f814901d2ae068af8814d6ed1a4 (patch)
tree571c75c85240a91b8dfc0d129b7af6438edc4862 /tools/android
parent1e810b3cc290b5b5d95c7789661271256288977c (diff)
Move SkAndroidSDKCanvas to tools and ensure that it is built on all Android builds
Diffstat (limited to 'tools/android')
-rw-r--r--tools/android/SkAndroidSDKCanvas.cpp365
-rw-r--r--tools/android/SkAndroidSDKCanvas.h110
2 files changed, 475 insertions, 0 deletions
diff --git a/tools/android/SkAndroidSDKCanvas.cpp b/tools/android/SkAndroidSDKCanvas.cpp
new file mode 100644
index 0000000000..45fcc758f2
--- /dev/null
+++ b/tools/android/SkAndroidSDKCanvas.cpp
@@ -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
index 0000000000..d8ee0ed216
--- /dev/null
+++ b/tools/android/SkAndroidSDKCanvas.h
@@ -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
+