2 * Copyright 2018 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
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 "src/utils/SkUTF.h"
22 #include "tools/ToolUtils.h"
25 #include <initializer_list>
27 static sk_sp<SkTextBlob> make_hpos_test_blob_utf8(const char* text, const SkFont& font) {
28 constexpr SkTextEncoding enc = SkTextEncoding::kUTF8;
29 SkTextBlobBuilder builder;
30 size_t len = strlen(text);
31 int glyphCount = font.countText(text, len, enc);
32 const auto& buffer = builder.allocRunPosH(font, glyphCount, 0);
33 (void)font.textToGlyphs(text, len, enc, buffer.glyphs, glyphCount);
34 font.getXPos(buffer.glyphs, glyphCount, buffer.pos);
35 return builder.make();
40 class ScaledEmojiGM : public GM {
46 sk_sp<SkTypeface> fTypeface;
50 void onOnceBeforeDraw() override {
51 fEmojiFont.fTypeface = ToolUtils::emoji_typeface();
52 fEmojiFont.fText = ToolUtils::emoji_sample_text();
55 SkString onShortName() override {
56 return SkString("scaledemoji");
59 SkISize onISize() override { return SkISize::Make(1200, 1200); }
61 void onDraw(SkCanvas* canvas) override {
63 canvas->drawColor(SK_ColorGRAY);
66 SkFont font(fEmojiFont.fTypeface);
67 font.setEdging(SkFont::Edging::kAlias);
69 const char* text = fEmojiFont.fText;
71 // draw text at different point sizes
72 // Testing GPU bitmap path, SDF path with no scaling,
73 // SDF path with scaling, path rendering with scaling
74 SkFontMetrics metrics;
76 for (SkScalar textSize : { 70, 180, 270, 340 }) {
77 font.setSize(textSize);
78 font.getMetrics(&metrics);
79 y += -metrics.fAscent;
80 canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 10, y, font, paint);
81 y += metrics.fDescent + metrics.fLeading;
89 class ScaledEmojiPosGM : public GM {
95 sk_sp<SkTypeface> fTypeface;
99 void onOnceBeforeDraw() override {
100 fEmojiFont.fTypeface = ToolUtils::emoji_typeface();
101 fEmojiFont.fText = ToolUtils::emoji_sample_text();
104 SkString onShortName() override {
105 return SkString("scaledemojipos");
108 SkISize onISize() override { return SkISize::Make(1200, 1200); }
110 void onDraw(SkCanvas* canvas) override {
112 canvas->drawColor(SK_ColorGRAY);
116 font.setTypeface(fEmojiFont.fTypeface);
117 const char* text = fEmojiFont.fText;
119 // draw text at different point sizes
120 // Testing GPU bitmap path, SDF path with no scaling,
121 // SDF path with scaling, path rendering with scaling
122 SkFontMetrics metrics;
124 for (SkScalar textSize : { 70, 180, 270, 340 }) {
125 font.setSize(textSize);
126 font.getMetrics(&metrics);
127 y += -metrics.fAscent;
129 sk_sp<SkTextBlob> blob = make_hpos_test_blob_utf8(text, font);
130 // Draw with an origin.
131 canvas->drawTextBlob(blob, 10, y, paint);
133 // Draw with shifted canvas.
135 canvas->translate(750, 0);
136 canvas->drawTextBlob(blob, 10, y, paint);
139 y += metrics.fDescent + metrics.fLeading;
144 using INHERITED = GM;
147 class ScaledEmojiPerspectiveGM : public GM {
149 ScaledEmojiPerspectiveGM() {}
153 sk_sp<SkTypeface> fTypeface;
157 void onOnceBeforeDraw() override {
158 fEmojiFont.fTypeface = ToolUtils::emoji_typeface();
161 const char* ch_ptr = ToolUtils::emoji_sample_text();
162 const char* ch_end = ch_ptr + strlen(ch_ptr);
163 while (ch_ptr < ch_end && count < 2) {
164 SkUnichar ch = SkUTF::NextUTF8(&ch_ptr, ch_end);
166 fEmojiFont.fText.appendUnichar(ch);
172 SkString onShortName() override {
173 return SkString("scaledemojiperspective");
176 SkISize onISize() override { return SkISize::Make(1200, 1200); }
178 void onDraw(SkCanvas* canvas) override {
180 canvas->drawColor(SK_ColorGRAY);
182 taper.setPerspY(-0.0025f);
186 font.setTypeface(fEmojiFont.fTypeface);
188 sk_sp<SkTextBlob> blob = make_hpos_test_blob_utf8(fEmojiFont.fText.c_str(), font);
190 // draw text at different point sizes
191 // Testing GPU bitmap path, SDF path with no scaling,
192 // SDF path with scaling, path rendering with scaling
193 SkFontMetrics metrics;
194 font.getMetrics(&metrics);
195 for (auto rotate : {0.0, 45.0, 90.0, 135.0, 180.0, 225.0, 270.0, 315.0}) {
197 SkMatrix perspective;
198 perspective.postTranslate(-600, -600);
199 perspective.postConcat(taper);
200 perspective.postRotate(rotate);
201 perspective.postTranslate(600, 600);
202 canvas->concat(perspective);
204 for (int i = 0; i < 5; i++) {
206 y += -metrics.fAscent;
208 // Draw with an origin.
209 canvas->drawTextBlob(blob, 565, y, paint);
211 y += metrics.fDescent + metrics.fLeading;
218 using INHERITED = GM;
221 //////////////////////////////////////////////////////////////////////////////
223 DEF_GM(return new ScaledEmojiGM;)
224 DEF_GM(return new ScaledEmojiPosGM;)
225 DEF_GM(return new ScaledEmojiPerspectiveGM;)
226 } // namespace skiagm