blob: 314ee71389942ed9100b1ab4b79b75cd666db968 [file] [log] [blame]
jvanverth9564ce62014-09-16 05:45:19 -07001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#include "gm.h"
jvanverthfca302c2014-10-20 13:12:54 -07008#include "Resources.h"
9#include "SkCanvas.h"
10#include "SkStream.h"
jvanverth9564ce62014-09-16 05:45:19 -070011#include "SkSurface.h"
12#include "SkTypeface.h"
13
jvanverthfca302c2014-10-20 13:12:54 -070014class DFTextGM : public skiagm::GM {
jvanverth9564ce62014-09-16 05:45:19 -070015public:
16 DFTextGM() {
17 this->setBGColor(0xFFFFFFFF);
jvanverthfca302c2014-10-20 13:12:54 -070018 fTypeface = NULL;
jvanverth9564ce62014-09-16 05:45:19 -070019 }
20
21 virtual ~DFTextGM() {
jvanverthfca302c2014-10-20 13:12:54 -070022 SkSafeUnref(fTypeface);
jvanverth9564ce62014-09-16 05:45:19 -070023 }
24
25protected:
mtklein36352bf2015-03-25 18:17:31 -070026 void onOnceBeforeDraw() override {
jvanverthfca302c2014-10-20 13:12:54 -070027 SkString filename = GetResourcePath("/Funkster.ttf");
scroggoa1193e42015-01-21 12:09:53 -080028 SkAutoTDelete<SkFILEStream> stream(new SkFILEStream(filename.c_str()));
jvanverthfca302c2014-10-20 13:12:54 -070029 if (!stream->isValid()) {
30 SkDebugf("Could not find Funkster.ttf, please set --resourcePath correctly.\n");
31 return;
32 }
33
scroggoa1193e42015-01-21 12:09:53 -080034 fTypeface = SkTypeface::CreateFromStream(stream.detach());
jvanverthfca302c2014-10-20 13:12:54 -070035 }
36
mtklein36352bf2015-03-25 18:17:31 -070037 SkString onShortName() override {
jvanverth9564ce62014-09-16 05:45:19 -070038 return SkString("dftext");
39 }
40
mtklein36352bf2015-03-25 18:17:31 -070041 SkISize onISize() override {
jvanverth9564ce62014-09-16 05:45:19 -070042 return SkISize::Make(1024, 768);
43 }
44
45 static void rotate_about(SkCanvas* canvas,
46 SkScalar degrees,
47 SkScalar px, SkScalar py) {
48 canvas->translate(px, py);
49 canvas->rotate(degrees);
50 canvas->translate(-px, -py);
51 }
52
mtklein36352bf2015-03-25 18:17:31 -070053 virtual void onDraw(SkCanvas* inputCanvas) override {
djsollen901704b2014-10-08 07:12:11 -070054#ifdef SK_BUILD_FOR_ANDROID
jvanverthed14f1d2014-10-06 12:50:54 -070055 SkScalar textSizes[] = { 9.0f, 9.0f*2.0f, 9.0f*5.0f, 9.0f*2.0f*5.0f };
56#else
jvanverth9564ce62014-09-16 05:45:19 -070057 SkScalar textSizes[] = { 11.0f, 11.0f*2.0f, 11.0f*5.0f, 11.0f*2.0f*5.0f };
jvanverthed14f1d2014-10-06 12:50:54 -070058#endif
jvanverth9564ce62014-09-16 05:45:19 -070059 SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f };
60
61 // set up offscreen rendering with distance field text
62#if SK_SUPPORT_GPU
63 GrContext* ctx = inputCanvas->getGrContext();
64 SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
reed4a8126e2014-09-22 07:29:03 -070065 SkSurfaceProps props(SkSurfaceProps::kUseDistanceFieldFonts_Flag,
66 SkSurfaceProps::kLegacyFontHost_InitType);
bsalomonafe30052015-01-16 07:32:33 -080067 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted,
68 info, 0, &props));
jvanverth76ce81e2014-09-22 14:26:53 -070069 SkCanvas* canvas = surface.get() ? surface->getCanvas() : inputCanvas;
jvanverthf9669f42014-10-07 07:59:45 -070070 // init our new canvas with the old canvas's matrix
71 canvas->setMatrix(inputCanvas->getTotalMatrix());
jvanverth9564ce62014-09-16 05:45:19 -070072#else
73 SkCanvas* canvas = inputCanvas;
74#endif
jvanverth76ce81e2014-09-22 14:26:53 -070075 // apply global scale to test glyph positioning
76 canvas->scale(1.05f, 1.05f);
jvanverth9564ce62014-09-16 05:45:19 -070077 canvas->clear(0xffffffff);
78
79 SkPaint paint;
80 paint.setAntiAlias(true);
81 paint.setSubpixelText(true);
82#if !SK_SUPPORT_GPU
83 paint.setDistanceFieldTextTEMP(true);
84#endif
85 sk_tool_utils::set_portable_typeface(&paint, "Times New Roman", SkTypeface::kNormal);
86
87 const char* text = "Hamburgefons";
88 const size_t textLen = strlen(text);
89
90 // check scaling up
91 SkScalar x = SkIntToScalar(0);
92 SkScalar y = SkIntToScalar(78);
93 for (size_t i = 0; i < SK_ARRAY_COUNT(textSizes); ++i) {
94 SkAutoCanvasRestore acr(canvas, true);
95 canvas->translate(x, y);
96 canvas->scale(scales[i], scales[i]);
97 paint.setTextSize(textSizes[i]);
98 canvas->drawText(text, textLen, 0, 0, paint);
99 y += paint.getFontMetrics(NULL)*scales[i];
100 }
101
102 // check rotation
103 for (size_t i = 0; i < 5; ++i) {
104 SkScalar rotX = SkIntToScalar(10);
105 SkScalar rotY = y;
106
107 SkAutoCanvasRestore acr(canvas, true);
108 canvas->translate(SkIntToScalar(10 + i * 200), -80);
109 rotate_about(canvas, SkIntToScalar(i * 5), rotX, rotY);
110 for (int ps = 6; ps <= 32; ps += 3) {
111 paint.setTextSize(SkIntToScalar(ps));
112 canvas->drawText(text, textLen, rotX, rotY, paint);
113 rotY += paint.getFontMetrics(NULL);
114 }
115 }
116
117 // check scaling down
118 paint.setLCDRenderText(true);
jvanverth76ce81e2014-09-22 14:26:53 -0700119 x = SkIntToScalar(680);
jvanverth9564ce62014-09-16 05:45:19 -0700120 y = SkIntToScalar(20);
121 size_t arraySize = SK_ARRAY_COUNT(textSizes);
122 for (size_t i = 0; i < arraySize; ++i) {
123 SkAutoCanvasRestore acr(canvas, true);
124 canvas->translate(x, y);
125 SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]);
126 canvas->scale(scaleFactor, scaleFactor);
127 paint.setTextSize(textSizes[i]);
128 canvas->drawText(text, textLen, 0, 0, paint);
129 y += paint.getFontMetrics(NULL)*scaleFactor;
130 }
131
jvanverth76ce81e2014-09-22 14:26:53 -0700132 // check pos text
133 {
134 SkAutoCanvasRestore acr(canvas, true);
135
136 canvas->scale(2.0f, 2.0f);
137
bsalomonfbaace02014-12-12 16:41:46 -0800138 SkAutoTArray<SkPoint> pos(SkToInt(textLen));
139 SkAutoTArray<SkScalar> widths(SkToInt(textLen));
jvanverth76ce81e2014-09-22 14:26:53 -0700140 paint.setTextSize(textSizes[0]);
141
142 paint.getTextWidths(text, textLen, &widths[0]);
143
144 SkScalar x = SkIntToScalar(340);
145 SkScalar y = SkIntToScalar(75);
146 for (unsigned int i = 0; i < textLen; ++i) {
147 pos[i].set(x, y);
148 x += widths[i];
149 }
150
151 canvas->drawPosText(text, textLen, &pos[0], paint);
152 }
153
154
jvanverth9564ce62014-09-16 05:45:19 -0700155 // check gamma-corrected blending
156 const SkColor fg[] = {
157 0xFFFFFFFF,
158 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
159 0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
160 0xFF000000,
161 };
162
163 paint.setColor(0xFFF1F1F1);
jvanverth76ce81e2014-09-22 14:26:53 -0700164 SkRect r = SkRect::MakeLTRB(670, 250, 820, 460);
jvanverth9564ce62014-09-16 05:45:19 -0700165 canvas->drawRect(r, paint);
166
jvanverth76ce81e2014-09-22 14:26:53 -0700167 x = SkIntToScalar(680);
jvanverth9564ce62014-09-16 05:45:19 -0700168 y = SkIntToScalar(270);
djsollen901704b2014-10-08 07:12:11 -0700169#ifdef SK_BUILD_FOR_ANDROID
jvanverthed14f1d2014-10-06 12:50:54 -0700170 paint.setTextSize(SkIntToScalar(19));
171#else
jvanverth9564ce62014-09-16 05:45:19 -0700172 paint.setTextSize(SkIntToScalar(22));
jvanverthed14f1d2014-10-06 12:50:54 -0700173#endif
jvanverth9564ce62014-09-16 05:45:19 -0700174 for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
175 paint.setColor(fg[i]);
176
177 canvas->drawText(text, textLen, x, y, paint);
178 y += paint.getFontMetrics(NULL);
179 }
180
181 paint.setColor(0xFF1F1F1F);
jvanverth76ce81e2014-09-22 14:26:53 -0700182 r = SkRect::MakeLTRB(820, 250, 970, 460);
jvanverth9564ce62014-09-16 05:45:19 -0700183 canvas->drawRect(r, paint);
184
jvanverth76ce81e2014-09-22 14:26:53 -0700185 x = SkIntToScalar(830);
jvanverth9564ce62014-09-16 05:45:19 -0700186 y = SkIntToScalar(270);
djsollen901704b2014-10-08 07:12:11 -0700187#ifdef SK_BUILD_FOR_ANDROID
jvanverthed14f1d2014-10-06 12:50:54 -0700188 paint.setTextSize(SkIntToScalar(19));
189#else
jvanverth9564ce62014-09-16 05:45:19 -0700190 paint.setTextSize(SkIntToScalar(22));
jvanverthed14f1d2014-10-06 12:50:54 -0700191#endif
jvanverth9564ce62014-09-16 05:45:19 -0700192 for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
193 paint.setColor(fg[i]);
194
195 canvas->drawText(text, textLen, x, y, paint);
196 y += paint.getFontMetrics(NULL);
197 }
198
jvanverth354eba52015-03-16 11:32:49 -0700199 // check skew
200 {
201 paint.setLCDRenderText(false);
202 SkAutoCanvasRestore acr(canvas, true);
203 canvas->skew(0.0f, 0.151515f);
jvanverthd68a5502015-03-16 12:58:43 -0700204 paint.setTextSize(SkIntToScalar(32));
jvanverth354eba52015-03-16 11:32:49 -0700205 canvas->drawText(text, textLen, 745, 70, paint);
206 }
207 {
208 paint.setLCDRenderText(true);
209 SkAutoCanvasRestore acr(canvas, true);
210 canvas->skew(0.5f, 0.0f);
jvanverthd68a5502015-03-16 12:58:43 -0700211 paint.setTextSize(SkIntToScalar(32));
jvanverth354eba52015-03-16 11:32:49 -0700212 canvas->drawText(text, textLen, 580, 230, paint);
213 }
214
jvanverthfca302c2014-10-20 13:12:54 -0700215 // check color emoji
216 paint.setTypeface(fTypeface);
jvanverthd68a5502015-03-16 12:58:43 -0700217#ifdef SK_BUILD_FOR_ANDROID
218 paint.setTextSize(SkIntToScalar(19));
219#else
220 paint.setTextSize(SkIntToScalar(22));
221#endif
jvanverthfca302c2014-10-20 13:12:54 -0700222 canvas->drawText(text, textLen, 670, 100, paint);
223
jvanverth9564ce62014-09-16 05:45:19 -0700224#if SK_SUPPORT_GPU
225 // render offscreen buffer
jvanverth76ce81e2014-09-22 14:26:53 -0700226 if (surface) {
jvanverthf9669f42014-10-07 07:59:45 -0700227 SkAutoCanvasRestore acr(inputCanvas, true);
228 // since we prepended this matrix already, we blit using identity
229 inputCanvas->resetMatrix();
jvanverth76ce81e2014-09-22 14:26:53 -0700230 SkImage* image = surface->newImageSnapshot();
piotaixrb5fae932014-09-24 13:03:30 -0700231 inputCanvas->drawImage(image, 0, 0, NULL);
jvanverth76ce81e2014-09-22 14:26:53 -0700232 image->unref();
233 }
jvanverth9564ce62014-09-16 05:45:19 -0700234#endif
235 }
236
237private:
jvanverthfca302c2014-10-20 13:12:54 -0700238 SkTypeface* fTypeface;
239
240 typedef skiagm::GM INHERITED;
jvanverth9564ce62014-09-16 05:45:19 -0700241};
242
jvanverthfca302c2014-10-20 13:12:54 -0700243DEF_GM( return SkNEW(DFTextGM); )