• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 
8 #include "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkFont.h"
12 #include "include/core/SkFontMetrics.h"
13 #include "include/core/SkFontTypes.h"
14 #include "include/core/SkPaint.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkScalar.h"
17 #include "include/core/SkSize.h"
18 #include "include/core/SkString.h"
19 #include "include/core/SkTextBlob.h"
20 #include "include/core/SkTypeface.h"
21 #include "tools/ToolUtils.h"
22 
23 #include <string.h>
24 #include <initializer_list>
25 
make_hpos_test_blob_utf8(const char * text,const SkFont & font)26 static sk_sp<SkTextBlob> make_hpos_test_blob_utf8(const char* text, const SkFont& font) {
27     constexpr SkTextEncoding enc = SkTextEncoding::kUTF8;
28     SkTextBlobBuilder builder;
29     size_t len = strlen(text);
30     int glyphCount = font.countText(text, len, enc);
31     const auto& buffer = builder.allocRunPosH(font, glyphCount, 0);
32     (void)font.textToGlyphs(text, len, enc, buffer.glyphs, glyphCount);
33     font.getXPos(buffer.glyphs, glyphCount, buffer.pos);
34     return builder.make();
35 }
36 
37 namespace skiagm {
38 
39 class ScaledEmojiGM : public GM {
40 public:
ScaledEmojiGM()41     ScaledEmojiGM() { }
42 
43 protected:
44     struct EmojiFont {
45         sk_sp<SkTypeface> fTypeface;
46         const char* fText;
47     } fEmojiFont;
48 
onOnceBeforeDraw()49     void onOnceBeforeDraw() override {
50         fEmojiFont.fTypeface = ToolUtils::emoji_typeface();
51         fEmojiFont.fText     = ToolUtils::emoji_sample_text();
52     }
53 
onShortName()54     SkString onShortName() override {
55         return SkString("scaledemoji");
56     }
57 
onISize()58     SkISize onISize() override { return SkISize::Make(1200, 1200); }
59 
onDraw(SkCanvas * canvas)60     void onDraw(SkCanvas* canvas) override {
61 
62         canvas->drawColor(SK_ColorGRAY);
63 
64         SkPaint paint;
65         SkFont font(fEmojiFont.fTypeface);
66         font.setEdging(SkFont::Edging::kAlias);
67 
68         const char* text = fEmojiFont.fText;
69 
70         // draw text at different point sizes
71         // Testing GPU bitmap path, SDF path with no scaling,
72         // SDF path with scaling, path rendering with scaling
73         SkFontMetrics metrics;
74         SkScalar y = 0;
75         for (SkScalar textSize : { 70, 180, 270, 340 }) {
76             font.setSize(textSize);
77             font.getMetrics(&metrics);
78             y += -metrics.fAscent;
79             canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 10, y, font, paint);
80             y += metrics.fDescent + metrics.fLeading;
81         }
82     }
83 
84 private:
85     using INHERITED = GM;
86 };
87 
88 class ScaledEmojiPosGM : public GM {
89 public:
ScaledEmojiPosGM()90     ScaledEmojiPosGM() {}
91 
92 protected:
93     struct EmojiFont {
94         sk_sp<SkTypeface> fTypeface;
95         const char* fText;
96     } fEmojiFont;
97 
onOnceBeforeDraw()98     void onOnceBeforeDraw() override {
99         fEmojiFont.fTypeface = ToolUtils::emoji_typeface();
100         fEmojiFont.fText     = ToolUtils::emoji_sample_text();
101     }
102 
onShortName()103     SkString onShortName() override {
104         return SkString("scaledemojipos");
105     }
106 
onISize()107     SkISize onISize() override { return SkISize::Make(1200, 1200); }
108 
onDraw(SkCanvas * canvas)109     void onDraw(SkCanvas* canvas) override {
110 
111         canvas->drawColor(SK_ColorGRAY);
112 
113         SkPaint paint;
114         SkFont font;
115         font.setTypeface(fEmojiFont.fTypeface);
116         const char* text = fEmojiFont.fText;
117 
118         // draw text at different point sizes
119         // Testing GPU bitmap path, SDF path with no scaling,
120         // SDF path with scaling, path rendering with scaling
121         SkFontMetrics metrics;
122         SkScalar y = 0;
123         for (SkScalar textSize : { 70, 180, 270, 340 }) {
124             font.setSize(textSize);
125             font.getMetrics(&metrics);
126             y += -metrics.fAscent;
127 
128             sk_sp<SkTextBlob> blob = make_hpos_test_blob_utf8(text, font);
129             // Draw with an origin.
130             canvas->drawTextBlob(blob, 10, y, paint);
131 
132             // Draw with shifted canvas.
133             canvas->save();
134             canvas->translate(750, 0);
135             canvas->drawTextBlob(blob, 10, y, paint);
136             canvas->restore();
137 
138             y += metrics.fDescent + metrics.fLeading;
139         }
140     }
141 
142 private:
143     using INHERITED = GM;
144 };
145 
146 class ScaledEmojiPerspectiveGM : public GM {
147 public:
ScaledEmojiPerspectiveGM()148     ScaledEmojiPerspectiveGM() {}
149 
150 protected:
151     struct EmojiFont {
152         sk_sp<SkTypeface> fTypeface;
153         const char* fText;
154     } fEmojiFont;
155 
onOnceBeforeDraw()156     void onOnceBeforeDraw() override {
157         fEmojiFont.fTypeface = ToolUtils::emoji_typeface();
158         fEmojiFont.fText     = ToolUtils::emoji_sample_text();
159     }
160 
onShortName()161     SkString onShortName() override {
162         return SkString("scaledemojiperspective");
163     }
164 
onISize()165     SkISize onISize() override { return SkISize::Make(1200, 1200); }
166 
onDraw(SkCanvas * canvas)167     void onDraw(SkCanvas* canvas) override {
168 
169         canvas->drawColor(SK_ColorGRAY);
170         SkMatrix taper;
171         taper.setPerspY(-0.0025f);
172 
173         SkPaint paint;
174         SkFont font;
175         font.setTypeface(fEmojiFont.fTypeface);
176         font.setSize(40);
177         const char* text = "\xF0\x9F\x98\x80"
178                            "\xE2\x99\xA2";  // ��♢;
179         sk_sp<SkTextBlob> blob = make_hpos_test_blob_utf8(text, font);
180 
181         // draw text at different point sizes
182         // Testing GPU bitmap path, SDF path with no scaling,
183         // SDF path with scaling, path rendering with scaling
184         SkFontMetrics metrics;
185         font.getMetrics(&metrics);
186         for (auto rotate : {0.0, 45.0, 90.0, 135.0, 180.0, 225.0, 270.0, 315.0}) {
187             canvas->save();
188             SkMatrix perspective;
189             perspective.postTranslate(-600, -600);
190             perspective.postConcat(taper);
191             perspective.postRotate(rotate);
192             perspective.postTranslate(600, 600);
193             canvas->concat(perspective);
194             SkScalar y = 670;
195             for (int i = 0; i < 5; i++) {
196 
197                 y += -metrics.fAscent;
198 
199                 // Draw with an origin.
200                 canvas->drawTextBlob(blob, 565, y, paint);
201 
202                 y += metrics.fDescent + metrics.fLeading;
203             }
204             canvas->restore();
205         }
206     }
207 
208 private:
209     using INHERITED = GM;
210 };
211 
212 //////////////////////////////////////////////////////////////////////////////
213 
214 DEF_GM(return new ScaledEmojiGM;)
215 DEF_GM(return new ScaledEmojiPosGM;)
216 DEF_GM(return new ScaledEmojiPerspectiveGM;)
217 }  // namespace skiagm
218