• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
8 #include "sk_tool_utils.h"
9 #include "Resources.h"
10 #include "SkCanvas.h"
11 #include "SkStream.h"
12 #include "SkSurface.h"
13 #include "SkTypeface.h"
14 
15 class DFTextGM : public skiagm::GM {
16 public:
DFTextGM()17     DFTextGM() {
18         this->setBGColor(0xFFFFFFFF);
19     }
20 
21 protected:
onOnceBeforeDraw()22     void onOnceBeforeDraw() override {
23         fEmojiTypeface = sk_tool_utils::emoji_typeface();
24         fEmojiText = sk_tool_utils::emoji_sample_text();
25     }
26 
onShortName()27     SkString onShortName() override {
28         SkString name("dftext");
29         name.append(sk_tool_utils::platform_os_emoji());
30         return name;
31     }
32 
onISize()33     SkISize onISize() override {
34         return SkISize::Make(1024, 768);
35     }
36 
onDraw(SkCanvas * inputCanvas)37     virtual void onDraw(SkCanvas* inputCanvas) override {
38         SkScalar textSizes[] = { 9.0f, 9.0f*2.0f, 9.0f*5.0f, 9.0f*2.0f*5.0f };
39         SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f };
40 
41         // set up offscreen rendering with distance field text
42 #if SK_SUPPORT_GPU
43         GrContext* ctx = inputCanvas->getGrContext();
44         SkISize size = onISize();
45         SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType,
46                                                 inputCanvas->imageInfo().refColorSpace());
47         SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
48                              SkSurfaceProps::kLegacyFontHost_InitType);
49         auto surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props));
50         SkCanvas* canvas = surface ? surface->getCanvas() : inputCanvas;
51         // init our new canvas with the old canvas's matrix
52         canvas->setMatrix(inputCanvas->getTotalMatrix());
53 #else
54         SkCanvas* canvas = inputCanvas;
55 #endif
56         // apply global scale to test glyph positioning
57         canvas->scale(1.05f, 1.05f);
58         canvas->clear(0xffffffff);
59 
60         SkPaint paint;
61         paint.setAntiAlias(true);
62         paint.setSubpixelText(true);
63 
64         sk_tool_utils::set_portable_typeface(&paint, "serif");
65 
66         const char* text = "Hamburgefons";
67         const size_t textLen = strlen(text);
68 
69         // check scaling up
70         SkScalar x = SkIntToScalar(0);
71         SkScalar y = SkIntToScalar(78);
72         for (size_t i = 0; i < SK_ARRAY_COUNT(textSizes); ++i) {
73             SkAutoCanvasRestore acr(canvas, true);
74             canvas->translate(x, y);
75             canvas->scale(scales[i], scales[i]);
76             paint.setTextSize(textSizes[i]);
77             canvas->drawText(text, textLen, 0, 0, paint);
78             y += paint.getFontMetrics(nullptr)*scales[i];
79         }
80 
81         // check rotation
82         for (size_t i = 0; i < 5; ++i) {
83             SkScalar rotX = SkIntToScalar(10);
84             SkScalar rotY = y;
85 
86             SkAutoCanvasRestore acr(canvas, true);
87             canvas->translate(SkIntToScalar(10 + i * 200), -80);
88             canvas->rotate(SkIntToScalar(i * 5), rotX, rotY);
89             for (int ps = 6; ps <= 32; ps += 3) {
90                 paint.setTextSize(SkIntToScalar(ps));
91                 canvas->drawText(text, textLen, rotX, rotY, paint);
92                 rotY += paint.getFontMetrics(nullptr);
93             }
94         }
95 
96         // check scaling down
97         paint.setLCDRenderText(true);
98         x = SkIntToScalar(680);
99         y = SkIntToScalar(20);
100         size_t arraySize = SK_ARRAY_COUNT(textSizes);
101         for (size_t i = 0; i < arraySize; ++i) {
102             SkAutoCanvasRestore acr(canvas, true);
103             canvas->translate(x, y);
104             SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]);
105             canvas->scale(scaleFactor, scaleFactor);
106             paint.setTextSize(textSizes[i]);
107             canvas->drawText(text, textLen, 0, 0, paint);
108             y += paint.getFontMetrics(nullptr)*scaleFactor;
109         }
110 
111         // check pos text
112         {
113             SkAutoCanvasRestore acr(canvas, true);
114 
115             canvas->scale(2.0f, 2.0f);
116 
117             SkAutoTArray<SkPoint>  pos(SkToInt(textLen));
118             SkAutoTArray<SkScalar> widths(SkToInt(textLen));
119             paint.setTextSize(textSizes[0]);
120 
121             paint.getTextWidths(text, textLen, &widths[0]);
122 
123             SkScalar x = SkIntToScalar(340);
124             SkScalar y = SkIntToScalar(75);
125             for (unsigned int i = 0; i < textLen; ++i) {
126                 pos[i].set(x, y);
127                 x += widths[i];
128             }
129 
130             canvas->drawPosText(text, textLen, &pos[0], paint);
131         }
132 
133 
134         // check gamma-corrected blending
135         const SkColor fg[] = {
136             0xFFFFFFFF,
137             0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
138             0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
139             0xFF000000,
140         };
141 
142         paint.setColor(0xFFF7F3F7);
143         SkRect r = SkRect::MakeLTRB(670, 215, 820, 397);
144         canvas->drawRect(r, paint);
145 
146         x = SkIntToScalar(680);
147         y = SkIntToScalar(235);
148         paint.setTextSize(SkIntToScalar(19));
149         for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
150             paint.setColor(fg[i]);
151 
152             canvas->drawText(text, textLen, x, y, paint);
153             y += paint.getFontMetrics(nullptr);
154         }
155 
156         paint.setColor(0xFF181C18);
157         r = SkRect::MakeLTRB(820, 215, 970, 397);
158         canvas->drawRect(r, paint);
159 
160         x = SkIntToScalar(830);
161         y = SkIntToScalar(235);
162         paint.setTextSize(SkIntToScalar(19));
163         for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
164             paint.setColor(fg[i]);
165 
166             canvas->drawText(text, textLen, x, y, paint);
167             y += paint.getFontMetrics(nullptr);
168         }
169 
170         // check skew
171         {
172             paint.setLCDRenderText(false);
173             SkAutoCanvasRestore acr(canvas, true);
174             canvas->skew(0.0f, 0.151515f);
175             paint.setTextSize(SkIntToScalar(32));
176             canvas->drawText(text, textLen, 745, 70, paint);
177         }
178         {
179             paint.setLCDRenderText(true);
180             SkAutoCanvasRestore acr(canvas, true);
181             canvas->skew(0.5f, 0.0f);
182             paint.setTextSize(SkIntToScalar(32));
183             canvas->drawText(text, textLen, 580, 125, paint);
184         }
185 
186         // check color emoji
187         if (fEmojiTypeface) {
188             paint.setTypeface(fEmojiTypeface);
189             paint.setTextSize(SkIntToScalar(19));
190             canvas->drawString(fEmojiText, 670, 90, paint);
191         }
192 #if SK_SUPPORT_GPU
193         // render offscreen buffer
194         if (surface) {
195             SkAutoCanvasRestore acr(inputCanvas, true);
196             // since we prepended this matrix already, we blit using identity
197             inputCanvas->resetMatrix();
198             inputCanvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, nullptr);
199         }
200 #endif
201     }
202 
203 private:
204     sk_sp<SkTypeface> fEmojiTypeface;
205     const char* fEmojiText;
206 
207     typedef skiagm::GM INHERITED;
208 };
209 
210 DEF_GM(return new DFTextGM;)
211