1523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt/*
2523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt * Copyright 2015 Google Inc.
3523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt *
4523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt * Use of this source code is governed by a BSD-style license that can be
5523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt * found in the LICENSE file.
6523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt */
7523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
8523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "gm.h"
933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h"
10523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
11523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "Resources.h"
12523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkCanvas.h"
13523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkGradientShader.h"
14523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkStream.h"
15523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkTextBlob.h"
16523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkTypeface.h"
17523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
18523ed6c0c1ac9029be315542258e02ba9854365cjoshualittnamespace skiagm {
19523ed6c0c1ac9029be315542258e02ba9854365cjoshualittclass TextBlobTransforms : public GM {
20523ed6c0c1ac9029be315542258e02ba9854365cjoshualittpublic:
21523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    // This gm tests that textblobs can be translated, rotated, and scaled
22523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    TextBlobTransforms() {}
23523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
24523ed6c0c1ac9029be315542258e02ba9854365cjoshualittprotected:
25523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    void onOnceBeforeDraw() override {
26523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkTextBlobBuilder builder;
27523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
28523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // make textblob.  To stress distance fields, we choose sizes appropriately
29523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkPaint paint;
30523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        paint.setTextSize(162);
31523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        const char* text = "A";
321818acb6a4b11cd9a1d44ce5dde77452502a9796caryclark        sk_tool_utils::set_portable_typeface(&paint);
33523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
34523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkRect bounds;
35523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        paint.measureText(text, strlen(text), &bounds);
36567ff2f6143ecb993dbedede402a43feb71c420atfarina        sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, 0);
37523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
38523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // Medium
39523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkScalar xOffset = bounds.width() + 5;
40523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        paint.setTextSize(72);
41523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        text = "B";
42523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset, 0);
43523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
44523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        paint.measureText(text, strlen(text), &bounds);
45523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkScalar yOffset = bounds.height();
46523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
47523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // Small
48523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        paint.setTextSize(32);
49523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        text = "C";
50523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset, -yOffset - 10);
51523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
52523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // build
5337283c28aa5bea2204c18956e74f83b238d7a891fmalita        fBlob = builder.make();
54523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    }
55523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
56523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    SkString onShortName() override {
57523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        return SkString("textblobtransforms");
58523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    }
59523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
60523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    SkISize onISize() override {
61523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        return SkISize::Make(kWidth, kHeight);
62523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    }
63523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
64523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    void onDraw(SkCanvas* canvas) override {
65523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
6685693c15c8948911afb0036a1a01bda64157a0abcaryclark        canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorGRAY));
67523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
68523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkPaint paint;
69523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
70523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkRect bounds = fBlob->bounds();
71523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(20, 20);
72523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
73523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // Colors were chosen to map to pairs of canonical colors.  The GPU Backend will cache A8
74523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // Texture Blobs based on the canonical color they map to.  Canonical colors are used to
75523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // create masks.  For A8 there are 8 of them.
7685693c15c8948911afb0036a1a01bda64157a0abcaryclark        //SkColor colors[] = {SK_ColorCYAN, sk_tool_utils::color_to_565(SK_ColorLTGRAY), SK_ColorYELLOW, SK_ColorWHITE};
77523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
78523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkScalar xOffset = SkScalarCeilToScalar(bounds.width());
79523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        SkScalar yOffset = SkScalarCeilToScalar(bounds.height());
80523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // first translate
81523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 2 * yOffset);
82523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
83523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(-xOffset, 0);
84523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
85523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(2 * xOffset, 0);
86523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
87523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(-xOffset, -yOffset);
88523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
89523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(0, 2 * yOffset);
90523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
91523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
92523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // now rotate
93523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(4 * xOffset, -yOffset);
94523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(180.f);
95523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
96523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(-180.f);
97523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(0, -yOffset);
98523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(-180.f);
99523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
100523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(270.f);
101523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
102523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(-90.f);
103523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(-xOffset, yOffset);
104523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(-90.f);
105523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
106523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(90.f);
107523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
108523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // and scales
109523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(- 3 * xOffset, 3 * yOffset);
110523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(1.5f, 1.5f);
111523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
112523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
113523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(.25f, .25f);
114523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
115523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
116523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(3.f, 2.f);
117523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
118523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
119523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        // finally rotates, scales, and translates together
120523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
121523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(23.f);
122523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(.33f, .5f);
123523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
124523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
125523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(-46.f);
126523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
127523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(1.2f, 1.1f);
128523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
129523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
130523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(46.f);
131523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
132523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(1.1f, 1.2f);
133523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
134523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
135523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(46.f);
136523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
137523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(.95f, 1.1f);
138523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
139523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
140523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(46.f);
141523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
142523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(1.3f, .7f);
143523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
144523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
145523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(46.f);
146523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
147523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(.8f, 1.1f);
148523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
149523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
150523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(10.f);
151523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
152523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(1.f, 5.f);
153523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
154523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
155523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->rotate(5.f);
156523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->translate(xOffset, 0);
157523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->scale(5.f, 1.f);
158523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt        canvas->drawTextBlob(fBlob, 0, 0, paint);
159523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    }
160523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
161523ed6c0c1ac9029be315542258e02ba9854365cjoshualittprivate:
16237283c28aa5bea2204c18956e74f83b238d7a891fmalita    sk_sp<SkTextBlob> fBlob;
163523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
164dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein    static constexpr int kWidth = 1000;
165dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein    static constexpr int kHeight = 1200;
166523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
167523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt    typedef GM INHERITED;
168523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt};
169523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
170523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt//////////////////////////////////////////////////////////////////////////////
171523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt
172385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new TextBlobTransforms;)
173523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt}
174