blob: 078184e47c173f9d14205bfa247e656acf708d03 [file] [log] [blame]
Jim Van Verth1b125452018-02-13 15:21:34 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -05009#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkColor.h"
11#include "include/core/SkFont.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkFontMetrics.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040013#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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "include/core/SkTextBlob.h"
20#include "include/core/SkTypeface.h"
Kevin Lubick1b3aa8b2023-01-19 14:03:31 -050021#include "src/base/SkUTF.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040022#include "tools/ToolUtils.h"
Kevin Lubicke836c3a2023-10-20 06:55:35 -040023#include "tools/fonts/FontToolUtils.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040024
25#include <string.h>
26#include <initializer_list>
Jim Van Verth1b125452018-02-13 15:21:34 -050027
Hal Canary7db6e282018-12-17 14:21:31 -050028static sk_sp<SkTextBlob> make_hpos_test_blob_utf8(const char* text, const SkFont& font) {
29 constexpr SkTextEncoding enc = SkTextEncoding::kUTF8;
30 SkTextBlobBuilder builder;
31 size_t len = strlen(text);
32 int glyphCount = font.countText(text, len, enc);
33 const auto& buffer = builder.allocRunPosH(font, glyphCount, 0);
34 (void)font.textToGlyphs(text, len, enc, buffer.glyphs, glyphCount);
35 font.getXPos(buffer.glyphs, glyphCount, buffer.pos);
36 return builder.make();
37}
38
Jim Van Verth1b125452018-02-13 15:21:34 -050039namespace skiagm {
40
41class ScaledEmojiGM : public GM {
42public:
43 ScaledEmojiGM() { }
44
45protected:
46 struct EmojiFont {
47 sk_sp<SkTypeface> fTypeface;
48 const char* fText;
49 } fEmojiFont;
50
51 void onOnceBeforeDraw() override {
Kevin Lubicke836c3a2023-10-20 06:55:35 -040052 fEmojiFont.fTypeface = ToolUtils::EmojiTypeface();
53 fEmojiFont.fText = ToolUtils::EmojiSampleText();
Jim Van Verth1b125452018-02-13 15:21:34 -050054 }
55
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000056 SkString getName() const override { return SkString("scaledemoji"); }
Jim Van Verth1b125452018-02-13 15:21:34 -050057
Leandro Lovisolo8f023882023-08-15 21:13:52 +000058 SkISize getISize() override { return SkISize::Make(1200, 1200); }
Jim Van Verth1b125452018-02-13 15:21:34 -050059
60 void onDraw(SkCanvas* canvas) override {
61
Mike Kleind46dce32018-08-16 10:17:03 -040062 canvas->drawColor(SK_ColorGRAY);
Jim Van Verth1b125452018-02-13 15:21:34 -050063
64 SkPaint paint;
Mike Reedf78b7ea2018-12-25 22:06:17 -050065 SkFont font(fEmojiFont.fTypeface);
66 font.setEdging(SkFont::Edging::kAlias);
67
Jim Van Verth1b125452018-02-13 15:21:34 -050068 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
Mike Reedb5784ac2018-11-12 09:35:15 -050073 SkFontMetrics metrics;
Jim Van Verth1b125452018-02-13 15:21:34 -050074 SkScalar y = 0;
75 for (SkScalar textSize : { 70, 180, 270, 340 }) {
Mike Reedf78b7ea2018-12-25 22:06:17 -050076 font.setSize(textSize);
77 font.getMetrics(&metrics);
Jim Van Verth1b125452018-02-13 15:21:34 -050078 y += -metrics.fAscent;
Ben Wagner51e15a62019-05-07 15:38:46 -040079 canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 10, y, font, paint);
Jim Van Verth1b125452018-02-13 15:21:34 -050080 y += metrics.fDescent + metrics.fLeading;
81 }
Jim Van Verth1b125452018-02-13 15:21:34 -050082 }
83
Jim Van Verth080a9282018-03-02 10:41:43 -050084private:
John Stiles7571f9e2020-09-02 22:42:33 -040085 using INHERITED = GM;
Jim Van Verth080a9282018-03-02 10:41:43 -050086};
87
88class ScaledEmojiPosGM : public GM {
89public:
90 ScaledEmojiPosGM() {}
91
92protected:
93 struct EmojiFont {
94 sk_sp<SkTypeface> fTypeface;
95 const char* fText;
96 } fEmojiFont;
97
98 void onOnceBeforeDraw() override {
Kevin Lubicke836c3a2023-10-20 06:55:35 -040099 fEmojiFont.fTypeface = ToolUtils::EmojiTypeface();
100 fEmojiFont.fText = ToolUtils::EmojiSampleText();
Jim Van Verth080a9282018-03-02 10:41:43 -0500101 }
102
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000103 SkString getName() const override { return SkString("scaledemojipos"); }
Jim Van Verth080a9282018-03-02 10:41:43 -0500104
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000105 SkISize getISize() override { return SkISize::Make(1200, 1200); }
Jim Van Verth080a9282018-03-02 10:41:43 -0500106
107 void onDraw(SkCanvas* canvas) override {
108
Mike Kleind46dce32018-08-16 10:17:03 -0400109 canvas->drawColor(SK_ColorGRAY);
Jim Van Verth080a9282018-03-02 10:41:43 -0500110
111 SkPaint paint;
Kevin Lubickbca43ec2023-10-30 10:11:22 -0400112 SkFont font(fEmojiFont.fTypeface, 12);
Jim Van Verth080a9282018-03-02 10:41:43 -0500113 const char* text = fEmojiFont.fText;
114
115 // draw text at different point sizes
116 // Testing GPU bitmap path, SDF path with no scaling,
117 // SDF path with scaling, path rendering with scaling
Mike Reedb5784ac2018-11-12 09:35:15 -0500118 SkFontMetrics metrics;
Jim Van Verth080a9282018-03-02 10:41:43 -0500119 SkScalar y = 0;
120 for (SkScalar textSize : { 70, 180, 270, 340 }) {
Herb Derby5f7b0142018-12-14 16:47:45 -0500121 font.setSize(textSize);
122 font.getMetrics(&metrics);
Jim Van Verth080a9282018-03-02 10:41:43 -0500123 y += -metrics.fAscent;
124
Hal Canary7db6e282018-12-17 14:21:31 -0500125 sk_sp<SkTextBlob> blob = make_hpos_test_blob_utf8(text, font);
Herb Derby5f7b0142018-12-14 16:47:45 -0500126 // Draw with an origin.
127 canvas->drawTextBlob(blob, 10, y, paint);
128
129 // Draw with shifted canvas.
130 canvas->save();
131 canvas->translate(750, 0);
132 canvas->drawTextBlob(blob, 10, y, paint);
133 canvas->restore();
134
Jim Van Verth080a9282018-03-02 10:41:43 -0500135 y += metrics.fDescent + metrics.fLeading;
136 }
Herb Derby47c88cc2021-04-23 16:21:58 -0400137 }
Jim Van Verth080a9282018-03-02 10:41:43 -0500138
Herb Derby47c88cc2021-04-23 16:21:58 -0400139private:
140 using INHERITED = GM;
141};
142
143class ScaledEmojiPerspectiveGM : public GM {
144public:
145 ScaledEmojiPerspectiveGM() {}
146
147protected:
148 struct EmojiFont {
149 sk_sp<SkTypeface> fTypeface;
Ben Wagnere961fd42022-04-04 16:08:54 -0400150 SkString fText;
Herb Derby47c88cc2021-04-23 16:21:58 -0400151 } fEmojiFont;
152
153 void onOnceBeforeDraw() override {
Kevin Lubicke836c3a2023-10-20 06:55:35 -0400154 fEmojiFont.fTypeface = ToolUtils::EmojiTypeface();
Ben Wagnere961fd42022-04-04 16:08:54 -0400155
156 int count = 0;
Kevin Lubicke836c3a2023-10-20 06:55:35 -0400157 const char* ch_ptr = ToolUtils::EmojiSampleText();
Ben Wagnere961fd42022-04-04 16:08:54 -0400158 const char* ch_end = ch_ptr + strlen(ch_ptr);
159 while (ch_ptr < ch_end && count < 2) {
160 SkUnichar ch = SkUTF::NextUTF8(&ch_ptr, ch_end);
161 if (ch != ' ') {
162 fEmojiFont.fText.appendUnichar(ch);
163 ++count;
164 }
165 }
Herb Derby47c88cc2021-04-23 16:21:58 -0400166 }
167
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000168 SkString getName() const override { return SkString("scaledemojiperspective"); }
Herb Derby47c88cc2021-04-23 16:21:58 -0400169
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000170 SkISize getISize() override { return SkISize::Make(1200, 1200); }
Herb Derby47c88cc2021-04-23 16:21:58 -0400171
172 void onDraw(SkCanvas* canvas) override {
173
174 canvas->drawColor(SK_ColorGRAY);
175 SkMatrix taper;
176 taper.setPerspY(-0.0025f);
177
178 SkPaint paint;
Kevin Lubickbca43ec2023-10-30 10:11:22 -0400179 SkFont font(fEmojiFont.fTypeface, 40);
Ben Wagnere961fd42022-04-04 16:08:54 -0400180 sk_sp<SkTextBlob> blob = make_hpos_test_blob_utf8(fEmojiFont.fText.c_str(), font);
Herb Derby47c88cc2021-04-23 16:21:58 -0400181
182 // draw text at different point sizes
183 // Testing GPU bitmap path, SDF path with no scaling,
184 // SDF path with scaling, path rendering with scaling
185 SkFontMetrics metrics;
186 font.getMetrics(&metrics);
187 for (auto rotate : {0.0, 45.0, 90.0, 135.0, 180.0, 225.0, 270.0, 315.0}) {
188 canvas->save();
189 SkMatrix perspective;
190 perspective.postTranslate(-600, -600);
191 perspective.postConcat(taper);
192 perspective.postRotate(rotate);
193 perspective.postTranslate(600, 600);
194 canvas->concat(perspective);
195 SkScalar y = 670;
196 for (int i = 0; i < 5; i++) {
197
198 y += -metrics.fAscent;
199
200 // Draw with an origin.
201 canvas->drawTextBlob(blob, 565, y, paint);
202
203 y += metrics.fDescent + metrics.fLeading;
204 }
205 canvas->restore();
206 }
Jim Van Verth080a9282018-03-02 10:41:43 -0500207 }
208
209private:
John Stiles7571f9e2020-09-02 22:42:33 -0400210 using INHERITED = GM;
Jim Van Verth1b125452018-02-13 15:21:34 -0500211};
212
213//////////////////////////////////////////////////////////////////////////////
214
215DEF_GM(return new ScaledEmojiGM;)
Jim Van Verth080a9282018-03-02 10:41:43 -0500216DEF_GM(return new ScaledEmojiPosGM;)
Herb Derby47c88cc2021-04-23 16:21:58 -0400217DEF_GM(return new ScaledEmojiPerspectiveGM;)
John Stilesa6841be2020-08-06 14:11:56 -0400218} // namespace skiagm