1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2013 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Sk2DPathEffect.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurMask.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurMaskFilter.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorMatrixFilter.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGradientShader.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGraphics.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkLayerDrawLooper.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRandom.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTextBlob.h"
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace skiagm {
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int kWidth = 1250;
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int kHeight = 700;
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Unlike the variant in sk_tool_utils, this version positions the glyphs on a diagonal
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPaint& origPaint,
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             SkScalar x, SkScalar y) {
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint(origPaint);
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTDArray<uint16_t> glyphs;
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t len = strlen(text);
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    glyphs.append(paint.textToGlyphs(text, len, nullptr));
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.textToGlyphs(text, len, glyphs.begin());
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar advanceX = paint.getTextSize() * 0.85f;
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar advanceY = paint.getTextSize() * 1.5f;
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTDArray<SkScalar> pos;
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (unsigned i = 0; i < len; ++i) {
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        *pos.append() = x + i * advanceX;
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        *pos.append() = y + i * (advanceY / len);
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkTextBlobBuilder::RunBuffer& run = builder->allocRunPos(paint, glyphs.count());
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    memcpy(run.glyphs, glyphs.begin(), glyphs.count() * sizeof(uint16_t));
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    memcpy(run.pos, pos.begin(), len * sizeof(SkScalar) * 2);
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottypedef void (*LooperProc)(SkPaint*);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct LooperSettings {
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBlendMode      fMode;
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColor          fColor;
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint::Style   fStyle;
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar         fWidth;
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar         fOffset;
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar         fSkewX;
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool             fEffect;
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void mask_filter(SkPaint* paint) {
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint->setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                SkBlurMask::ConvertRadiusToSigma(3.f)));
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkPathEffect> make_tile_effect() {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrix m;
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    m.setScale(1.f, 1.f);
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPath path;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    path.addCircle(0, 0, SkIntToScalar(5));
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkPath2DPathEffect::Make(m, path);
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void path_effect(SkPaint* paint) {
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint->setPathEffect(make_tile_effect());
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> make_shader(const SkRect& bounds) {
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkPoint pts[] = {
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        { bounds.left(), bounds.top() },
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        { bounds.right(), bounds.bottom() },
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkColor colors[] = {
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorBLACK,
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW,
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        SkShader::kClamp_TileMode);
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void color_filter(SkPaint* paint) {
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect r;
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.setWH(SkIntToScalar(kWidth), 50);
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint->setShader(make_shader(r));
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint->setColorFilter(SkColorMatrixFilter::MakeLightingFilter(0xF0F0F0, 0));
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void kitchen_sink(SkPaint* paint) {
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    color_filter(paint);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    path_effect(paint);
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mask_filter(paint);
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkDrawLooper> setupLooper(SkLayerDrawLooper::BitFlags bits,
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       LooperProc proc,
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       const LooperSettings settings[],
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       size_t size) {
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkLayerDrawLooper::Builder looperBuilder;
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkLayerDrawLooper::LayerInfo info;
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    info.fPaintBits = bits;
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    info.fColorMode = SkBlendMode::kSrc;
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (size_t i = 0; i < size; i++) {
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info.fOffset.set(settings[i].fOffset, settings[i].fOffset);
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint* paint = looperBuilder.addLayer(info);
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint->setBlendMode(settings[i].fMode);
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint->setColor(settings[i].fColor);
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint->setStyle(settings[i].fStyle);
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint->setStrokeWidth(settings[i].fWidth);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (settings[i].fEffect) {
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            (*proc)(paint);
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return looperBuilder.detach();
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass TextBlobLooperGM : public GM {
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TextBlobLooperGM() {}
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onOnceBeforeDraw() override {
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkTextBlobBuilder builder;
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // LCD
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setTextSize(32);
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* text = "The quick brown fox jumps over the lazy dog";
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setSubpixelText(true);
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setLCDRenderText(true);
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setAntiAlias(true);
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_tool_utils::set_portable_typeface(&paint);
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        add_to_text_blob(&builder, text, paint, 0, 0);
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBlob = builder.make();
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // create a looper which sandwhiches an effect in two normal draws
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LooperSettings looperSandwhich[] = {
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot           { SkBlendMode::kSrc, SK_ColorMAGENTA, SkPaint::kFill_Style, 0, 0, 0, false },
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot           { SkBlendMode::kSrcOver, 0x88000000, SkPaint::kFill_Style, 0, 10.f, 0, true },
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot           { SkBlendMode::kSrcOver, 0x50FF00FF, SkPaint::kFill_Style, 0, 20.f, 0, false },
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LooperSettings compound[] = {
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorWHITE, SkPaint::kStroke_Style, 1.f * 3/4, 0, 0, false },
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorRED, SkPaint::kStroke_Style, 4.f, 0, 0, false },
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorBLUE, SkPaint::kFill_Style, 0, 0, 0, false },
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrcOver, 0x88000000, SkPaint::kFill_Style, 0, 10.f, 0, true }
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LooperSettings xfermode[] = {
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kDifference, SK_ColorWHITE, SkPaint::kFill_Style, 0, 0, 0, false },
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrcOver, 0xFF000000, SkPaint::kFill_Style, 0, 1.f, 0, true },
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrcOver, 0x50FF00FF, SkPaint::kFill_Style, 0, 2.f, 0, false },
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // NOTE, this should be ignored by textblobs
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LooperSettings skew[] = {
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorRED, SkPaint::kFill_Style, 0, 0, -1.f, false },
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorGREEN, SkPaint::kFill_Style, 0, 10.f, -1.f, false },
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorBLUE, SkPaint::kFill_Style, 0, 20.f, -1.f, false },
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LooperSettings kitchenSink[] = {
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorWHITE, SkPaint::kStroke_Style, 1.f * 3/4, 0, 0, false },
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorBLACK, SkPaint::kFill_Style, 0, 0, 0, false },
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kDifference, SK_ColorWHITE, SkPaint::kFill_Style, 1.f, 10.f, 0, false },
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrc, SK_ColorWHITE, SkPaint::kFill_Style, 0, 10.f, 0, true },
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkBlendMode::kSrcOver, 0x50FF00FF, SkPaint::kFill_Style, 0, 20.f, 0, false },
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLoopers.push_back(setupLooper(SkLayerDrawLooper::kMaskFilter_Bit |
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kXfermode_Bit |
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kStyle_Bit, &mask_filter,
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       compound, SK_ARRAY_COUNT(compound)));
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLoopers.push_back(setupLooper(SkLayerDrawLooper::kPathEffect_Bit |
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kXfermode_Bit, &path_effect,
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       looperSandwhich, SK_ARRAY_COUNT(looperSandwhich)));
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLoopers.push_back(setupLooper(SkLayerDrawLooper::kShader_Bit |
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kColorFilter_Bit |
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kXfermode_Bit, &color_filter,
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       looperSandwhich, SK_ARRAY_COUNT(looperSandwhich)));
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLoopers.push_back(setupLooper(SkLayerDrawLooper::kShader_Bit |
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kColorFilter_Bit |
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kXfermode_Bit, &color_filter,
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       xfermode, SK_ARRAY_COUNT(xfermode)));
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLoopers.push_back(setupLooper(0, nullptr, skew, SK_ARRAY_COUNT(skew)));
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLoopers.push_back(setupLooper(SkLayerDrawLooper::kMaskFilter_Bit |
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kShader_Bit |
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kColorFilter_Bit |
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kPathEffect_Bit |
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kStyle_Bit |
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SkLayerDrawLooper::kXfermode_Bit, &kitchen_sink,
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       kitchenSink, SK_ARRAY_COUNT(kitchenSink)));
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Test we respect overrides
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLoopers.push_back(setupLooper(0, &kitchen_sink,
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       kitchenSink, SK_ARRAY_COUNT(kitchenSink)));
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("textbloblooper");
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override {
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkISize::Make(kWidth, kHeight);
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorGRAY));
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(10, 40);
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setTextSize(40);
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect bounds = fBlob->bounds();
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int y = 0;
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int looper = 0; looper < fLoopers.count(); looper++) {
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            paint.setLooper(fLoopers[looper]);
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->save();
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->translate(0, SkIntToScalar(y));
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawTextBlob(fBlob, 0, 0, paint);
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->restore();
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            y += SkScalarFloorToInt(bounds.height());
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkTextBlob> fBlob;
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTArray<sk_sp<SkDrawLooper>, true> fLoopers;
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//////////////////////////////////////////////////////////////////////////////
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM(return new TextBlobLooperGM;)
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
259