blob: 694e6a5701ed8439dc4eb063157e316b90b6c8ce [file] [log] [blame]
reed@google.comaf0fa6a2013-03-28 13:39:35 +00001/*
2 * Copyright 2013 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"
9#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"
13#include "include/core/SkFontMgr.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040014#include "include/core/SkFontStyle.h"
15#include "include/core/SkFontTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "include/core/SkGraphics.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040017#include "include/core/SkPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "include/core/SkPath.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040019#include "include/core/SkPoint.h"
20#include "include/core/SkRect.h"
21#include "include/core/SkRefCnt.h"
22#include "include/core/SkScalar.h"
23#include "include/core/SkSize.h"
24#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "include/core/SkTypeface.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040026#include "include/core/SkTypes.h"
Ben Wagner8bd6c982020-08-21 12:06:03 -040027#include "include/effects/SkDashPathEffect.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "src/core/SkFontPriv.h"
Hal Canarye574f1e2019-07-15 14:01:37 -040029#include "tools/SkMetaData.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "tools/ToolUtils.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040031
32#include <utility>
reed@google.comaf0fa6a2013-03-28 13:39:35 +000033
34// limit this just so we don't take too long to draw
35#define MAX_FAMILIES 30
36
37static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
Mike Reed560d5b32018-12-16 16:36:48 -050038 SkScalar y, const SkFont& font) {
Hal Canary89a644b2019-01-07 09:36:09 -050039 canvas->drawString(text, x, y, font, SkPaint());
Ben Wagner51e15a62019-05-07 15:38:46 -040040 return x + font.measureText(text.c_str(), text.size(), SkTextEncoding::kUTF8);
reed@google.comaf0fa6a2013-03-28 13:39:35 +000041}
42
djsollen0d393a92014-08-27 07:03:13 -070043static SkScalar drawCharacter(SkCanvas* canvas, uint32_t character, SkScalar x,
Mike Reed560d5b32018-12-16 16:36:48 -050044 SkScalar y, const SkFont& origFont, SkFontMgr* fm,
bungemanc9232dc2014-11-10 13:29:33 -080045 const char* fontName, const char* bcp47[], int bcp47Count,
djsollen0d393a92014-08-27 07:03:13 -070046 const SkFontStyle& fontStyle) {
Mike Reed560d5b32018-12-16 16:36:48 -050047 SkFont font = origFont;
djsollen0d393a92014-08-27 07:03:13 -070048 // find typeface containing the requested character and draw it
49 SkString ch;
50 ch.appendUnichar(character);
bungeman13b9c952016-05-12 10:09:30 -070051 sk_sp<SkTypeface> typeface(fm->matchFamilyStyleCharacter(fontName, fontStyle,
52 bcp47, bcp47Count, character));
Mike Reed560d5b32018-12-16 16:36:48 -050053 font.setTypeface(typeface);
54 x = drawString(canvas, ch, x, y, font) + 20;
djsollen0d393a92014-08-27 07:03:13 -070055
halcanary96fcdcc2015-08-27 07:41:13 -070056 if (nullptr == typeface) {
djsollen0d393a92014-08-27 07:03:13 -070057 return x;
58 }
59
60 // repeat the process, but this time use the family name of the typeface
61 // from the first pass. This emulates the behavior in Blink where it
62 // it expects to get the same glyph when following this pattern.
63 SkString familyName;
64 typeface->getFamilyName(&familyName);
Mike Reed560d5b32018-12-16 16:36:48 -050065 font.setTypeface(fm->legacyMakeTypeface(familyName.c_str(), typeface->fontStyle()));
66 return drawString(canvas, ch, x, y, font) + 20;
djsollen0d393a92014-08-27 07:03:13 -070067}
68
bungemanc9232dc2014-11-10 13:29:33 -080069static const char* zh = "zh";
70static const char* ja = "ja";
71
reed@google.comaf0fa6a2013-03-28 13:39:35 +000072class FontMgrGM : public skiagm::GM {
Hal Canary594fe852019-07-18 13:35:49 -040073 sk_sp<SkFontMgr> fFM;
Ben Wagner3546ff12017-01-03 13:32:36 -050074
Hal Canary594fe852019-07-18 13:35:49 -040075 void onOnceBeforeDraw() override {
76 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
Mike Klein8073e792017-11-13 18:10:54 -050077 fFM = SkFontMgr::RefDefault();
Ben Wagner3546ff12017-01-03 13:32:36 -050078 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +000079
Hal Canary594fe852019-07-18 13:35:49 -040080 SkString onShortName() override { return SkString("fontmgr_iter"); }
reed@google.comaf0fa6a2013-03-28 13:39:35 +000081
Hal Canary594fe852019-07-18 13:35:49 -040082 SkISize onISize() override { return {1536, 768}; }
reed@google.comaf0fa6a2013-03-28 13:39:35 +000083
mtklein36352bf2015-03-25 18:17:31 -070084 void onDraw(SkCanvas* canvas) override {
reed@google.comaf0fa6a2013-03-28 13:39:35 +000085 SkScalar y = 20;
Mike Reed560d5b32018-12-16 16:36:48 -050086 SkFont font;
87 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
88 font.setSubpixel(true);
89 font.setSize(17);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000090
Hal Canarycefc4312016-11-04 16:26:16 -040091 SkFontMgr* fm = fFM.get();
Brian Osman7f364052020-02-06 11:25:43 -050092 int count = std::min(fm->countFamilies(), MAX_FAMILIES);
reed@google.comaf0fa6a2013-03-28 13:39:35 +000093
94 for (int i = 0; i < count; ++i) {
bungemanc64239a2015-04-29 08:15:31 -070095 SkString familyName;
96 fm->getFamilyName(i, &familyName);
Mike Reed560d5b32018-12-16 16:36:48 -050097 font.setTypeface(nullptr);
98 (void)drawString(canvas, familyName, 20, y, font);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000099
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000100 SkScalar x = 220;
reed@google.com964988f2013-03-29 14:57:22 +0000101
Hal Canarycefc4312016-11-04 16:26:16 -0400102 sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000103 for (int j = 0; j < set->count(); ++j) {
104 SkString sname;
105 SkFontStyle fs;
106 set->getStyle(j, &fs, &sname);
bungemanb4bb7d82016-04-27 10:21:04 -0700107 sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.slant());
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000108
Mike Reed560d5b32018-12-16 16:36:48 -0500109 font.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
110 x = drawString(canvas, sname, x, y, font) + 20;
djsollen0d393a92014-08-27 07:03:13 -0700111
112 // check to see that we get different glyphs in japanese and chinese
Mike Reed560d5b32018-12-16 16:36:48 -0500113 x = drawCharacter(canvas, 0x5203, x, y, font, fm, familyName.c_str(), &zh, 1, fs);
114 x = drawCharacter(canvas, 0x5203, x, y, font, fm, familyName.c_str(), &ja, 1, fs);
djsollen0d393a92014-08-27 07:03:13 -0700115 // check that emoji characters are found
Mike Reed560d5b32018-12-16 16:36:48 -0500116 x = drawCharacter(canvas, 0x1f601, x, y, font, fm, familyName.c_str(), nullptr,0, fs);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000117 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000118 y += 24;
119 }
120 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000121};
122
reed@google.com964988f2013-03-29 14:57:22 +0000123class FontMgrMatchGM : public skiagm::GM {
Hal Canarycefc4312016-11-04 16:26:16 -0400124 sk_sp<SkFontMgr> fFM;
reed@google.com964988f2013-03-29 14:57:22 +0000125
Hal Canary594fe852019-07-18 13:35:49 -0400126 void onOnceBeforeDraw() override {
127 fFM = SkFontMgr::RefDefault();
reed@google.com964988f2013-03-29 14:57:22 +0000128 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
129 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000130
Hal Canary594fe852019-07-18 13:35:49 -0400131 SkString onShortName() override { return SkString("fontmgr_match"); }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000132
Hal Canary594fe852019-07-18 13:35:49 -0400133 SkISize onISize() override { return {640, 1024}; }
reed@google.com964988f2013-03-29 14:57:22 +0000134
Mike Reed560d5b32018-12-16 16:36:48 -0500135 void iterateFamily(SkCanvas* canvas, const SkFont& font, SkFontStyleSet* fset) {
136 SkFont f(font);
reed@google.com964988f2013-03-29 14:57:22 +0000137 SkScalar y = 0;
138
139 for (int j = 0; j < fset->count(); ++j) {
140 SkString sname;
141 SkFontStyle fs;
142 fset->getStyle(j, &fs, &sname);
143
144 sname.appendf(" [%d %d]", fs.weight(), fs.width());
145
Mike Reed560d5b32018-12-16 16:36:48 -0500146 f.setTypeface(sk_sp<SkTypeface>(fset->createTypeface(j)));
147 (void)drawString(canvas, sname, 0, y, f);
reed@google.com964988f2013-03-29 14:57:22 +0000148 y += 24;
149 }
150 }
151
Mike Reed560d5b32018-12-16 16:36:48 -0500152 void exploreFamily(SkCanvas* canvas, const SkFont& font, SkFontStyleSet* fset) {
153 SkFont f(font);
reed@google.com964988f2013-03-29 14:57:22 +0000154 SkScalar y = 0;
155
156 for (int weight = 100; weight <= 900; weight += 200) {
157 for (int width = 1; width <= 9; width += 2) {
158 SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
bungeman13b9c952016-05-12 10:09:30 -0700159 sk_sp<SkTypeface> face(fset->matchStyle(fs));
reed@google.com964988f2013-03-29 14:57:22 +0000160 if (face) {
161 SkString str;
162 str.printf("request [%d %d]", fs.weight(), fs.width());
Mike Reed560d5b32018-12-16 16:36:48 -0500163 f.setTypeface(std::move(face));
164 (void)drawString(canvas, str, 0, y, f);
reed@google.com964988f2013-03-29 14:57:22 +0000165 y += 24;
166 }
167 }
168 }
169 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000170
Chris Dalton50e24d72019-02-07 16:20:09 -0700171 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
Mike Reed560d5b32018-12-16 16:36:48 -0500172 SkFont font;
173 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
174 font.setSubpixel(true);
175 font.setSize(17);
reed@google.com964988f2013-03-29 14:57:22 +0000176
mtkleindbfd7ab2016-09-01 11:24:54 -0700177 const char* gNames[] = {
Ben Wagner83c6b962018-07-10 19:40:15 -0400178 "Helvetica Neue", "Arial", "sans"
reed@google.com964988f2013-03-29 14:57:22 +0000179 };
180
Hal Canarycefc4312016-11-04 16:26:16 -0400181 sk_sp<SkFontStyleSet> fset;
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000182 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
bungeman@google.com9fc5c682013-11-12 15:25:29 +0000183 fset.reset(fFM->matchFamily(gNames[i]));
184 if (fset->count() > 0) {
reed@google.com964988f2013-03-29 14:57:22 +0000185 break;
186 }
187 }
halcanary96fcdcc2015-08-27 07:41:13 -0700188 if (nullptr == fset.get()) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700189 *errorMsg = "No SkFontStyleSet";
190 return DrawResult::kFail;
reed@google.com964988f2013-03-29 14:57:22 +0000191 }
reed@google.com964988f2013-03-29 14:57:22 +0000192
193 canvas->translate(20, 40);
Mike Reed560d5b32018-12-16 16:36:48 -0500194 this->exploreFamily(canvas, font, fset.get());
reed@google.com964988f2013-03-29 14:57:22 +0000195 canvas->translate(150, 0);
Mike Reed560d5b32018-12-16 16:36:48 -0500196 this->iterateFamily(canvas, font, fset.get());
Chris Dalton50e24d72019-02-07 16:20:09 -0700197 return DrawResult::kOk;
reed@google.com964988f2013-03-29 14:57:22 +0000198 }
reed@google.com964988f2013-03-29 14:57:22 +0000199};
200
reeda0c814c2014-10-22 13:20:58 -0700201class FontMgrBoundsGM : public skiagm::GM {
202public:
Hal Canary594fe852019-07-18 13:35:49 -0400203 FontMgrBoundsGM(float scale, float skew) : fScaleX(scale) , fSkewX(skew) {}
204
205private:
206 SkString onShortName() override {
207 if (fScaleX != 1 || fSkewX != 0) {
208 return SkStringPrintf("fontmgr_bounds_%g_%g", fScaleX, fSkewX);
reed8893e5f2014-12-15 13:27:26 -0800209 }
Hal Canary594fe852019-07-18 13:35:49 -0400210 return SkString("fontmgr_bounds");
211 }
212
213 void onOnceBeforeDraw() override {
214 fFM = SkFontMgr::RefDefault();
Ben Wagner110c7032019-03-22 17:03:59 -0400215 }
216
217 bool onGetControls(SkMetaData* controls) override {
218 controls->setBool("Label Bounds", fLabelBounds);
219 return true;
220 }
221
222 void onSetControls(const SkMetaData& controls) override {
223 controls.findBool("Label Bounds", &fLabelBounds);
reeda0c814c2014-10-22 13:20:58 -0700224 }
225
Ben Wagner8bd6c982020-08-21 12:06:03 -0400226 static SkRect show_bounds(SkCanvas* canvas, const SkFont& font, SkScalar x, SkScalar y,
227 SkColor boundsColor, bool labelBounds)
Ben Wagner219f3622017-07-17 15:32:25 -0400228 {
Ben Wagner219f3622017-07-17 15:32:25 -0400229 SkGlyphID left = 0, right = 0, top = 0, bottom = 0;
Ben Wagner8bd6c982020-08-21 12:06:03 -0400230 SkRect min = SkRect::MakeLTRB(SK_ScalarInfinity, SK_ScalarInfinity,
231 SK_ScalarNegativeInfinity, SK_ScalarNegativeInfinity);
Ben Wagner219f3622017-07-17 15:32:25 -0400232 {
Herb Derby087fad72019-01-22 14:45:16 -0500233 int numGlyphs = font.getTypefaceOrDefault()->countGlyphs();
Ben Wagner219f3622017-07-17 15:32:25 -0400234 for (int i = 0; i < numGlyphs; ++i) {
235 SkGlyphID glyphId = i;
236 SkRect cur;
Mike Reed7d1eb332018-12-04 17:35:56 -0500237 font.getBounds(&glyphId, 1, &cur, nullptr);
Ben Wagner219f3622017-07-17 15:32:25 -0400238 if (cur.fLeft < min.fLeft ) { min.fLeft = cur.fLeft; left = i; }
239 if (cur.fTop < min.fTop ) { min.fTop = cur.fTop ; top = i; }
240 if (min.fRight < cur.fRight ) { min.fRight = cur.fRight; right = i; }
241 if (min.fBottom < cur.fBottom) { min.fBottom = cur.fBottom; bottom = i; }
242 }
243 }
Ben Wagner8bd6c982020-08-21 12:06:03 -0400244
245 SkRect fontBounds = SkFontPriv::GetFontBounds(font);
246
247 SkRect drawBounds = min;
248 drawBounds.join(fontBounds);
249
250 SkAutoCanvasRestore acr(canvas, true);
251 canvas->translate(x - drawBounds.left(), y);
252
253 SkPaint boundsPaint;
254 boundsPaint.setAntiAlias(true);
255 boundsPaint.setColor(boundsColor);
256 boundsPaint.setStyle(SkPaint::kStroke_Style);
257 canvas->drawRect(fontBounds, boundsPaint);
258
259 const SkScalar intervals[] = { 10.f, 10.f };
260 boundsPaint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.f));
261 canvas->drawRect(min, boundsPaint);
262
263 SkFontMetrics fm;
264 font.getMetrics(&fm);
265 SkPaint metricsPaint(boundsPaint);
266 metricsPaint.setStyle(SkPaint::kFill_Style);
267 metricsPaint.setAlphaf(0.25f);
268 if ((fm.fFlags & SkFontMetrics::kUnderlinePositionIsValid_Flag) &&
269 (fm.fFlags & SkFontMetrics::kUnderlineThicknessIsValid_Flag))
270 {
Ben Wagner19684732020-08-21 16:52:48 -0400271 SkRect underline{ min.fLeft, fm.fUnderlinePosition,
272 min.fRight, fm.fUnderlinePosition + fm.fUnderlineThickness };
Ben Wagner8bd6c982020-08-21 12:06:03 -0400273 canvas->drawRect(underline, metricsPaint);
274 }
275
276 if ((fm.fFlags & SkFontMetrics::kStrikeoutPositionIsValid_Flag) &&
277 (fm.fFlags & SkFontMetrics::kStrikeoutThicknessIsValid_Flag))
278 {
Ben Wagner19684732020-08-21 16:52:48 -0400279 SkRect strikeout{ min.fLeft, fm.fStrikeoutPosition - fm.fStrikeoutThickness,
280 min.fRight, fm.fStrikeoutPosition };
Ben Wagner8bd6c982020-08-21 12:06:03 -0400281 canvas->drawRect(strikeout, metricsPaint);
282 }
283
Ben Wagner19684732020-08-21 16:52:48 -0400284 struct GlyphToDraw {
285 SkGlyphID id;
286 SkPoint location;
287 SkScalar rotation;
288 } glyphsToDraw [] = {
289 {left, {min.left(), min.centerY()}, 270},
290 {right, {min.right(), min.centerY()}, 90},
291 {top, {min.centerX(), min.top() }, 0},
292 {bottom, {min.centerX(), min.bottom() }, 180},
Ben Wagner17bca9a2018-06-22 15:27:52 -0400293 };
294
Mike Reed7d1eb332018-12-04 17:35:56 -0500295 SkFont labelFont;
296 labelFont.setEdging(SkFont::Edging::kAntiAlias);
Mike Kleinea3f0142019-03-20 11:12:10 -0500297 labelFont.setTypeface(ToolUtils::create_portable_typeface());
Mike Reed7d1eb332018-12-04 17:35:56 -0500298
Ben Wagner110c7032019-03-22 17:03:59 -0400299 if (labelBounds) {
Ben Wagner17bca9a2018-06-22 15:27:52 -0400300 SkString name;
Herb Derby087fad72019-01-22 14:45:16 -0500301 font.getTypefaceOrDefault()->getFamilyName(&name);
Ben Wagner19684732020-08-21 16:52:48 -0400302 canvas->drawString(name, min.fLeft, min.fBottom, labelFont, SkPaint());
Ben Wagner17bca9a2018-06-22 15:27:52 -0400303 }
Ben Wagner19684732020-08-21 16:52:48 -0400304 for (const GlyphToDraw& glyphToDraw : glyphsToDraw) {
Ben Wagner97182cc2018-02-15 10:20:04 -0500305 SkPath path;
Ben Wagner19684732020-08-21 16:52:48 -0400306 font.getPath(glyphToDraw.id, &path);
Ben Wagner97182cc2018-02-15 10:20:04 -0500307 SkPaint::Style style = path.isEmpty() ? SkPaint::kFill_Style : SkPaint::kStroke_Style;
Mike Reed7d1eb332018-12-04 17:35:56 -0500308 SkPaint glyphPaint;
Ben Wagner97182cc2018-02-15 10:20:04 -0500309 glyphPaint.setStyle(style);
Ben Wagner19684732020-08-21 16:52:48 -0400310 canvas->drawSimpleText(&glyphToDraw.id, sizeof(glyphToDraw.id),
311 SkTextEncoding::kGlyphID, 0, 0, font, glyphPaint);
Ben Wagner17bca9a2018-06-22 15:27:52 -0400312
Ben Wagner110c7032019-03-22 17:03:59 -0400313 if (labelBounds) {
John Stilesacf71642021-08-12 22:33:57 -0400314 SkAutoCanvasRestore acr2(canvas, true);
Ben Wagner19684732020-08-21 16:52:48 -0400315 canvas->translate(glyphToDraw.location.fX, glyphToDraw.location.fY);
316 canvas->rotate(glyphToDraw.rotation);
Ben Wagner17bca9a2018-06-22 15:27:52 -0400317 SkString glyphStr;
Ben Wagner19684732020-08-21 16:52:48 -0400318 glyphStr.appendS32(glyphToDraw.id);
319 canvas->drawString(glyphStr, 0, 0, labelFont, SkPaint());
Ben Wagner17bca9a2018-06-22 15:27:52 -0400320 }
Ben Wagner219f3622017-07-17 15:32:25 -0400321 }
Ben Wagner8bd6c982020-08-21 12:06:03 -0400322
323 return drawBounds;
reeda0c814c2014-10-22 13:20:58 -0700324 }
325
Hal Canary594fe852019-07-18 13:35:49 -0400326 SkISize onISize() override { return {1024, 850}; }
tfarinaaa458fb2015-01-05 17:18:51 -0800327
mtklein36352bf2015-03-25 18:17:31 -0700328 void onDraw(SkCanvas* canvas) override {
Mike Reed7d1eb332018-12-04 17:35:56 -0500329 SkFont font;
330 font.setEdging(SkFont::Edging::kAntiAlias);
331 font.setSubpixel(true);
332 font.setSize(100);
333 font.setScaleX(fScaleX);
334 font.setSkewX(fSkewX);
reeda0c814c2014-10-22 13:20:58 -0700335
336 const SkColor boundsColors[2] = { SK_ColorRED, SK_ColorBLUE };
halcanary9d524f22016-03-29 09:03:52 -0700337
Hal Canarycefc4312016-11-04 16:26:16 -0400338 SkFontMgr* fm = fFM.get();
Brian Osman7f364052020-02-06 11:25:43 -0500339 int count = std::min(fm->countFamilies(), 32);
reeda0c814c2014-10-22 13:20:58 -0700340
341 int index = 0;
342 SkScalar x = 0, y = 0;
343
Ben Wagner219f3622017-07-17 15:32:25 -0400344 canvas->translate(10, 120);
reeda0c814c2014-10-22 13:20:58 -0700345
346 for (int i = 0; i < count; ++i) {
Hal Canarycefc4312016-11-04 16:26:16 -0400347 sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
Ben Wagner219f3622017-07-17 15:32:25 -0400348 for (int j = 0; j < set->count() && j < 3; ++j) {
Mike Reed7d1eb332018-12-04 17:35:56 -0500349 font.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
Ben Wagner2112df02017-07-24 11:04:21 -0400350 // Fonts with lots of glyphs are interesting, but can take a long time to find
351 // the glyphs which make up the maximum extent.
Ben Wagner8bd6c982020-08-21 12:06:03 -0400352 SkTypeface* typeface = font.getTypefaceOrDefault();
353 if (typeface && 0 < typeface->countGlyphs() && typeface->countGlyphs() < 1000) {
Ben Wagner19684732020-08-21 16:52:48 -0400354 SkColor color = boundsColors[index & 1];
355 SkRect drawBounds = show_bounds(canvas, font, x, y, color, fLabelBounds);
Ben Wagner8bd6c982020-08-21 12:06:03 -0400356 x += drawBounds.width() + 20;
reeda0c814c2014-10-22 13:20:58 -0700357 index += 1;
Ben Wagner219f3622017-07-17 15:32:25 -0400358 if (x > 900) {
reeda0c814c2014-10-22 13:20:58 -0700359 x = 0;
360 y += 160;
361 }
Ben Wagner219f3622017-07-17 15:32:25 -0400362 if (y >= 700) {
reeda0c814c2014-10-22 13:20:58 -0700363 return;
364 }
365 }
366 }
367 }
368 }
mtklein1c402922015-01-23 11:07:07 -0800369
Hal Canary594fe852019-07-18 13:35:49 -0400370 sk_sp<SkFontMgr> fFM;
Ben Wagner110c7032019-03-22 17:03:59 -0400371 const SkScalar fScaleX;
372 const SkScalar fSkewX;
Hal Canary594fe852019-07-18 13:35:49 -0400373 bool fLabelBounds = false;
reeda0c814c2014-10-22 13:20:58 -0700374};
375
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000376//////////////////////////////////////////////////////////////////////////////
377
halcanary385fe4d2015-08-26 13:07:48 -0700378DEF_GM(return new FontMgrGM;)
379DEF_GM(return new FontMgrMatchGM;)
Hal Canary594fe852019-07-18 13:35:49 -0400380DEF_GM(return new FontMgrBoundsGM(1, 0);)
381DEF_GM(return new FontMgrBoundsGM(0.75f, 0);)
382DEF_GM(return new FontMgrBoundsGM(1, -0.25f);)