1f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson/*
2f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson * Copyright 2015 Google Inc.
3f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson *
4f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson * Use of this source code is governed by a BSD-style license that can be
5f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson * found in the LICENSE file.
6f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson */
7f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
8f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#include "SkAndroidSDKCanvas.h"
9f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
10f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#include "SkColorFilter.h"
11f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#include "SkPathEffect.h"
12f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#include "SkShader.h"
13f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
14f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonnamespace {
15f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
16f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson/** Discard SkShaders not exposed by the Android Java API. */
17f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
18f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid CheckShader(SkPaint* paint) {
19f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkShader* shader = paint->getShader();
20f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (!shader) {
21f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        return;
22f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
23f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
24f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType) {
25f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        return;
26f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
27f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (shader->asACompose(NULL)) {
28f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        return;
29f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
30f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkShader::GradientType gtype = shader->asAGradient(NULL);
31f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (gtype == SkShader::kLinear_GradientType ||
32f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        gtype == SkShader::kRadial_GradientType ||
33f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        gtype == SkShader::kSweep_GradientType) {
34f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        return;
35f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
36f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    paint->setShader(NULL);
37f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
38f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
39f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid Filter(SkPaint* paint) {
40f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
41f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    uint32_t flags = paint->getFlags();
42f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    flags &= ~SkPaint::kLCDRenderText_Flag;
43f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    paint->setFlags(flags);
44f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
45f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    // Android doesn't support Xfermodes above kLighten_Mode
46f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkXfermode::Mode mode;
47f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkXfermode::AsMode(paint->getXfermode(), &mode);
48f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (mode > SkXfermode::kLighten_Mode) {
49f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        paint->setXfermode(NULL);
50f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
51f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
52f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    // Force bilinear scaling or none
53f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (paint->getFilterQuality() != kNone_SkFilterQuality) {
54f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        paint->setFilterQuality(kLow_SkFilterQuality);
55f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
56f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
57f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    CheckShader(paint);
58f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
59f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    // Android SDK only supports mode & matrix color filters
60f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    // (and, again, no modes above kLighten_Mode).
61f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkColorFilter* cf = paint->getColorFilter();
62f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (cf) {
63f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        SkColor color;
64f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        SkXfermode::Mode mode;
65f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        SkScalar srcColorMatrix[20];
66f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        bool isMode = cf->asColorMode(&color, &mode);
67f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        if (isMode && mode > SkXfermode::kLighten_Mode) {
68f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson            paint->setColorFilter(
69f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcOver_Mode));
70f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        } else if (!isMode && !cf->asColorMatrix(srcColorMatrix)) {
71f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson            paint->setColorFilter(NULL);
72f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        }
73f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
74f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
75f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
76f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkPathEffect* pe = paint->getPathEffect();
77f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (pe && !pe->exposedInAndroidJavaAPI()) {
78f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        paint->setPathEffect(NULL);
79f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
80f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#endif
81f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
82f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    // TODO: Android doesn't support all the flags that can be passed to
83f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    // blur filters; we need plumbing to get them out.
84f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
85f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    paint->setImageFilter(NULL);
86f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    paint->setLooper(NULL);
87f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson};
88f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
89f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}  // namespace
90f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
91f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#define FILTER(p)             \
92f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkPaint filteredPaint(p); \
93f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    Filter(&filteredPaint);
94f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
95f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson#define FILTER_PTR(p)                          \
96f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkTLazy<SkPaint> lazyPaint;                \
97f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    SkPaint* filteredPaint = (SkPaint*) p;     \
98f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    if (p) {                                   \
99f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        filteredPaint = lazyPaint.set(*p);     \
100f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson        Filter(filteredPaint);                 \
101f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    }
102f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
103f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
104f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonSkAndroidSDKCanvas::SkAndroidSDKCanvas() : fProxyTarget(NULL) { }
105f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
106f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::reset(SkCanvas* newTarget) { fProxyTarget = newTarget; }
107f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
108f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawPaint(const SkPaint& paint) {
109f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
110f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawPaint(filteredPaint);
111f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
112f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawPoints(PointMode pMode,
113f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               size_t count,
114f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               const SkPoint pts[],
115f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               const SkPaint& paint) {
116f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
117f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawPoints(pMode, count, pts, filteredPaint);
118f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
119f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawOval(const SkRect& r, const SkPaint& paint) {
120f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
121f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawOval(r, filteredPaint);
122f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
123f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
124f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
125f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawRect(r, filteredPaint);
126f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
127f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawRRect(const SkRRect& r, const SkPaint& paint) {
128f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
129f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawRRect(r, filteredPaint);
130f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
131f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
132f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
133f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawPath(path, filteredPaint);
134f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
135f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawBitmap(const SkBitmap& bitmap,
136f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               SkScalar left,
137f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               SkScalar top,
138f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               const SkPaint* paint) {
139f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER_PTR(paint);
140f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawBitmap(bitmap, left, top, filteredPaint);
141f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
142f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
143f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkRect* src,
144f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkRect& dst,
145f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkPaint* paint,
146f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   DrawBitmapRectFlags flags) {
147f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER_PTR(paint);
148f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawBitmapRectToRect(bitmap, src, dst, filteredPaint, flags);
149f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
150f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
151f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkIRect& center,
152f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkRect& dst,
153f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkPaint* paint) {
154f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER_PTR(paint);
155f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawBitmapNine(bitmap, center, dst, filteredPaint);
156f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
157f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawSprite(const SkBitmap& bitmap,
158f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               int left,
159f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               int top,
160f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               const SkPaint* paint) {
161f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER_PTR(paint);
162f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawSprite(bitmap, left, top, filteredPaint);
163f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
164f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawVertices(VertexMode vMode,
165f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 int vertexCount,
166f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 const SkPoint vertices[],
167f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                    const SkPoint texs[], const SkColor colors[], SkXfermode* xMode,
168f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                    const uint16_t indices[], int indexCount,
169f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                    const SkPaint& paint) {
170f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
171f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawVertices(vMode, vertexCount, vertices, texs, colors,
172f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                               xMode, indices, indexCount, filteredPaint);
173f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
174f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
175f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawDRRect(const SkRRect& outer,
176f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               const SkRRect& inner,
177f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                               const SkPaint& paint) {
178f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
179f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawDRRect(outer, inner, filteredPaint);
180f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
181f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
182f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawText(const void* text,
183f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             size_t byteLength,
184f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             SkScalar x,
185f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             SkScalar y,
186f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             const SkPaint& paint) {
187f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
188f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawText(text, byteLength, x, y, filteredPaint);
189f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
190f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawPosText(const void* text,
191f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                size_t byteLength,
192f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                const SkPoint pos[],
193f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                const SkPaint& paint) {
194f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
195f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawPosText(text, byteLength, pos, filteredPaint);
196f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
197f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawPosTextH(const void* text,
198f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 size_t byteLength,
199f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 const SkScalar xpos[],
200f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 SkScalar constY,
201f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 const SkPaint& paint) {
202f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
203f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawPosTextH(text, byteLength, xpos, constY, filteredPaint);
204f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
205f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawTextOnPath(const void* text,
206f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   size_t byteLength,
207f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkPath& path,
208f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkMatrix* matrix,
209f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                   const SkPaint& paint) {
210f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
211f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawTextOnPath(text, byteLength, path, matrix, filteredPaint);
212f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
213f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawTextBlob(const SkTextBlob* blob,
214f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 SkScalar x,
215f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 SkScalar y,
216f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                 const SkPaint& paint) {
217f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
218f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawTextBlob(blob, x, y, filteredPaint);
219f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
220f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
221f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawPatch(const SkPoint cubics[12],
222f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              const SkColor colors[4],
223f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              const SkPoint texCoords[4],
224f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              SkXfermode* xmode,
225f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              const SkPaint& paint) {
226f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER(paint);
227f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawPatch(cubics, colors, texCoords, xmode, filteredPaint);
228f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
229f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
230f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
231f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawImage(const SkImage* image,
232f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              SkScalar x,
233f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              SkScalar y,
234f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              const SkPaint* paint) {
235f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER_PTR(paint);
236f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawImage(image, x, y, filteredPaint);
237f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
238f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
239f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawImageRect(const SkImage* image,
240f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                  const SkRect* in,
241f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                  const SkRect& out,
242f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                  const SkPaint* paint) {
243f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER_PTR(paint);
244f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawImageRect(image, in, out, filteredPaint);
245f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
246f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
247f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawPicture(const SkPicture* picture,
248f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                const SkMatrix* matrix,
249f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                const SkPaint* paint) {
250f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    FILTER_PTR(paint);
251f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawPicture(picture, matrix, filteredPaint);
252f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
253f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
254f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDrawDrawable(SkDrawable* drawable) {
255f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->drawDrawable(drawable);
256f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
257f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
258f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonSkISize SkAndroidSDKCanvas::getBaseLayerSize() const {
259f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    return fProxyTarget->getBaseLayerSize();
260f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
261f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonbool SkAndroidSDKCanvas::getClipBounds(SkRect* rect) const {
262f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    return fProxyTarget->getClipBounds(rect);
263f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
264f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonbool SkAndroidSDKCanvas::getClipDeviceBounds(SkIRect* rect) const {
265f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    return fProxyTarget->getClipDeviceBounds(rect);
266f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
267f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
268f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonbool SkAndroidSDKCanvas::isClipEmpty() const { return fProxyTarget->isClipEmpty(); }
269f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonbool SkAndroidSDKCanvas::isClipRect() const { return fProxyTarget->isClipRect(); }
270f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
271f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonSkSurface* SkAndroidSDKCanvas::onNewSurface(const SkImageInfo& info,
272f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                                     const SkSurfaceProps& props) {
273f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    return fProxyTarget->newSurface(info, &props);
274f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
275f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
276f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonconst void* SkAndroidSDKCanvas::onPeekPixels(SkImageInfo* info, size_t* data) {
277f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    return fProxyTarget->peekPixels(info, data);
278f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
279f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
280f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid* SkAndroidSDKCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* data) {
281f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    return fProxyTarget->accessTopLayerPixels(info, data);
282f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
283f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
28405e4abae89d0609af91eef5dddc237c835443c9atomhudsonvoid SkAndroidSDKCanvas::willSave() {
28505e4abae89d0609af91eef5dddc237c835443c9atomhudson    fProxyTarget->save();
28605e4abae89d0609af91eef5dddc237c835443c9atomhudson}
28705e4abae89d0609af91eef5dddc237c835443c9atomhudson
28805e4abae89d0609af91eef5dddc237c835443c9atomhudsonSkCanvas::SaveLayerStrategy SkAndroidSDKCanvas::willSaveLayer(const SkRect* rect,
28905e4abae89d0609af91eef5dddc237c835443c9atomhudson                                                              const SkPaint* paint,
29005e4abae89d0609af91eef5dddc237c835443c9atomhudson                                                              SaveFlags flags) {
29105e4abae89d0609af91eef5dddc237c835443c9atomhudson    fProxyTarget->saveLayer(rect, paint, flags);
29205e4abae89d0609af91eef5dddc237c835443c9atomhudson    return SkCanvas::kNoLayer_SaveLayerStrategy;
29305e4abae89d0609af91eef5dddc237c835443c9atomhudson}
29405e4abae89d0609af91eef5dddc237c835443c9atomhudson
29505e4abae89d0609af91eef5dddc237c835443c9atomhudsonvoid SkAndroidSDKCanvas::willRestore() {
29605e4abae89d0609af91eef5dddc237c835443c9atomhudson    fProxyTarget->restore();
29705e4abae89d0609af91eef5dddc237c835443c9atomhudson}
29805e4abae89d0609af91eef5dddc237c835443c9atomhudson
299f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::didRestore() { }
30005e4abae89d0609af91eef5dddc237c835443c9atomhudson
301f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::didConcat(const SkMatrix& m) {
302f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->concat(m);
303f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
30405e4abae89d0609af91eef5dddc237c835443c9atomhudson
30505e4abae89d0609af91eef5dddc237c835443c9atomhudsonvoid SkAndroidSDKCanvas::didSetMatrix(const SkMatrix& m) {
30605e4abae89d0609af91eef5dddc237c835443c9atomhudson    fProxyTarget->setMatrix(m);
30705e4abae89d0609af91eef5dddc237c835443c9atomhudson}
308f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
309f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onClipRect(const SkRect& rect,
310f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             SkRegion::Op op,
311f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             ClipEdgeStyle style) {
312f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->clipRect(rect, op, style);
313f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
314f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
315f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onClipRRect(const SkRRect& rrect,
316f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              SkRegion::Op op,
317f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                              ClipEdgeStyle style) {
318f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->clipRRect(rrect, op, style);
319f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
320f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
321f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onClipPath(const SkPath& path,
322f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             SkRegion::Op op,
323f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson                                             ClipEdgeStyle style) {
324f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->clipPath(path, op, style);
325f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
326f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
327f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) {
328f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson    fProxyTarget->clipRegion(region, op);
329f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson}
330f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
331f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudsonvoid SkAndroidSDKCanvas::onDiscard() { fProxyTarget->discard(); }
332f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
333f7edcdedb64ee0d4a5c88807cd75ed1700e5bccetomhudson
334