blob: 9290825e1d9ad60fe48d5433af938bd0b37ab7c7 [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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#include "src/core/SkFontPriv.h"
28#include "src/utils/SkMetaData.h"
29#include "tools/ToolUtils.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040030
31#include <utility>
reed@google.comaf0fa6a2013-03-28 13:39:35 +000032
33// limit this just so we don't take too long to draw
34#define MAX_FAMILIES 30
35
36static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
Mike Reed560d5b32018-12-16 16:36:48 -050037 SkScalar y, const SkFont& font) {
Hal Canary89a644b2019-01-07 09:36:09 -050038 canvas->drawString(text, x, y, font, SkPaint());
Ben Wagner51e15a62019-05-07 15:38:46 -040039 return x + font.measureText(text.c_str(), text.size(), SkTextEncoding::kUTF8);
reed@google.comaf0fa6a2013-03-28 13:39:35 +000040}
41
djsollen0d393a92014-08-27 07:03:13 -070042static SkScalar drawCharacter(SkCanvas* canvas, uint32_t character, SkScalar x,
Mike Reed560d5b32018-12-16 16:36:48 -050043 SkScalar y, const SkFont& origFont, SkFontMgr* fm,
bungemanc9232dc2014-11-10 13:29:33 -080044 const char* fontName, const char* bcp47[], int bcp47Count,
djsollen0d393a92014-08-27 07:03:13 -070045 const SkFontStyle& fontStyle) {
Mike Reed560d5b32018-12-16 16:36:48 -050046 SkFont font = origFont;
djsollen0d393a92014-08-27 07:03:13 -070047 // find typeface containing the requested character and draw it
48 SkString ch;
49 ch.appendUnichar(character);
bungeman13b9c952016-05-12 10:09:30 -070050 sk_sp<SkTypeface> typeface(fm->matchFamilyStyleCharacter(fontName, fontStyle,
51 bcp47, bcp47Count, character));
Mike Reed560d5b32018-12-16 16:36:48 -050052 font.setTypeface(typeface);
53 x = drawString(canvas, ch, x, y, font) + 20;
djsollen0d393a92014-08-27 07:03:13 -070054
halcanary96fcdcc2015-08-27 07:41:13 -070055 if (nullptr == typeface) {
djsollen0d393a92014-08-27 07:03:13 -070056 return x;
57 }
58
59 // repeat the process, but this time use the family name of the typeface
60 // from the first pass. This emulates the behavior in Blink where it
61 // it expects to get the same glyph when following this pattern.
62 SkString familyName;
63 typeface->getFamilyName(&familyName);
Mike Reed560d5b32018-12-16 16:36:48 -050064 font.setTypeface(fm->legacyMakeTypeface(familyName.c_str(), typeface->fontStyle()));
65 return drawString(canvas, ch, x, y, font) + 20;
djsollen0d393a92014-08-27 07:03:13 -070066}
67
bungemanc9232dc2014-11-10 13:29:33 -080068static const char* zh = "zh";
69static const char* ja = "ja";
70
reed@google.comaf0fa6a2013-03-28 13:39:35 +000071class FontMgrGM : public skiagm::GM {
72public:
Mike Klein8073e792017-11-13 18:10:54 -050073 FontMgrGM() {
Ben Wagner3546ff12017-01-03 13:32:36 -050074 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
75
76 fName.set("fontmgr_iter");
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
80protected:
mtklein36352bf2015-03-25 18:17:31 -070081 SkString onShortName() override {
bungeman@google.combfc6cc42013-08-21 15:20:43 +000082 return fName;
reed@google.comaf0fa6a2013-03-28 13:39:35 +000083 }
84
mtklein36352bf2015-03-25 18:17:31 -070085 SkISize onISize() override {
djsollen0d393a92014-08-27 07:03:13 -070086 return SkISize::Make(1536, 768);
reed@google.comaf0fa6a2013-03-28 13:39:35 +000087 }
88
mtklein36352bf2015-03-25 18:17:31 -070089 void onDraw(SkCanvas* canvas) override {
reed@google.comaf0fa6a2013-03-28 13:39:35 +000090 SkScalar y = 20;
Mike Reed560d5b32018-12-16 16:36:48 -050091 SkFont font;
92 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
93 font.setSubpixel(true);
94 font.setSize(17);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000095
Hal Canarycefc4312016-11-04 16:26:16 -040096 SkFontMgr* fm = fFM.get();
reed@google.comaf0fa6a2013-03-28 13:39:35 +000097 int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
98
99 for (int i = 0; i < count; ++i) {
bungemanc64239a2015-04-29 08:15:31 -0700100 SkString familyName;
101 fm->getFamilyName(i, &familyName);
Mike Reed560d5b32018-12-16 16:36:48 -0500102 font.setTypeface(nullptr);
103 (void)drawString(canvas, familyName, 20, y, font);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000104
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000105 SkScalar x = 220;
reed@google.com964988f2013-03-29 14:57:22 +0000106
Hal Canarycefc4312016-11-04 16:26:16 -0400107 sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000108 for (int j = 0; j < set->count(); ++j) {
109 SkString sname;
110 SkFontStyle fs;
111 set->getStyle(j, &fs, &sname);
bungemanb4bb7d82016-04-27 10:21:04 -0700112 sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.slant());
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000113
Mike Reed560d5b32018-12-16 16:36:48 -0500114 font.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
115 x = drawString(canvas, sname, x, y, font) + 20;
djsollen0d393a92014-08-27 07:03:13 -0700116
117 // check to see that we get different glyphs in japanese and chinese
Mike Reed560d5b32018-12-16 16:36:48 -0500118 x = drawCharacter(canvas, 0x5203, x, y, font, fm, familyName.c_str(), &zh, 1, fs);
119 x = drawCharacter(canvas, 0x5203, x, y, font, fm, familyName.c_str(), &ja, 1, fs);
djsollen0d393a92014-08-27 07:03:13 -0700120 // check that emoji characters are found
Mike Reed560d5b32018-12-16 16:36:48 -0500121 x = drawCharacter(canvas, 0x1f601, x, y, font, fm, familyName.c_str(), nullptr,0, fs);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000122 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000123 y += 24;
124 }
125 }
126
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000127private:
Hal Canarycefc4312016-11-04 16:26:16 -0400128 sk_sp<SkFontMgr> fFM;
bungeman@google.combfc6cc42013-08-21 15:20:43 +0000129 SkString fName;
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000130 typedef GM INHERITED;
131};
132
reed@google.com964988f2013-03-29 14:57:22 +0000133class FontMgrMatchGM : public skiagm::GM {
Hal Canarycefc4312016-11-04 16:26:16 -0400134 sk_sp<SkFontMgr> fFM;
reed@google.com964988f2013-03-29 14:57:22 +0000135
136public:
137 FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) {
138 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
139 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000140
reed@google.com964988f2013-03-29 14:57:22 +0000141protected:
mtklein36352bf2015-03-25 18:17:31 -0700142 SkString onShortName() override {
Mike Kleinbea1f942019-03-08 11:11:55 -0600143 return SkString("fontmgr_match");
reed@google.com964988f2013-03-29 14:57:22 +0000144 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000145
mtklein36352bf2015-03-25 18:17:31 -0700146 SkISize onISize() override {
reed@google.com964988f2013-03-29 14:57:22 +0000147 return SkISize::Make(640, 1024);
148 }
149
Mike Reed560d5b32018-12-16 16:36:48 -0500150 void iterateFamily(SkCanvas* canvas, const SkFont& font, SkFontStyleSet* fset) {
151 SkFont f(font);
reed@google.com964988f2013-03-29 14:57:22 +0000152 SkScalar y = 0;
153
154 for (int j = 0; j < fset->count(); ++j) {
155 SkString sname;
156 SkFontStyle fs;
157 fset->getStyle(j, &fs, &sname);
158
159 sname.appendf(" [%d %d]", fs.weight(), fs.width());
160
Mike Reed560d5b32018-12-16 16:36:48 -0500161 f.setTypeface(sk_sp<SkTypeface>(fset->createTypeface(j)));
162 (void)drawString(canvas, sname, 0, y, f);
reed@google.com964988f2013-03-29 14:57:22 +0000163 y += 24;
164 }
165 }
166
Mike Reed560d5b32018-12-16 16:36:48 -0500167 void exploreFamily(SkCanvas* canvas, const SkFont& font, SkFontStyleSet* fset) {
168 SkFont f(font);
reed@google.com964988f2013-03-29 14:57:22 +0000169 SkScalar y = 0;
170
171 for (int weight = 100; weight <= 900; weight += 200) {
172 for (int width = 1; width <= 9; width += 2) {
173 SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
bungeman13b9c952016-05-12 10:09:30 -0700174 sk_sp<SkTypeface> face(fset->matchStyle(fs));
reed@google.com964988f2013-03-29 14:57:22 +0000175 if (face) {
176 SkString str;
177 str.printf("request [%d %d]", fs.weight(), fs.width());
Mike Reed560d5b32018-12-16 16:36:48 -0500178 f.setTypeface(std::move(face));
179 (void)drawString(canvas, str, 0, y, f);
reed@google.com964988f2013-03-29 14:57:22 +0000180 y += 24;
181 }
182 }
183 }
184 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000185
Chris Dalton50e24d72019-02-07 16:20:09 -0700186 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
Mike Reed560d5b32018-12-16 16:36:48 -0500187 SkFont font;
188 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
189 font.setSubpixel(true);
190 font.setSize(17);
reed@google.com964988f2013-03-29 14:57:22 +0000191
mtkleindbfd7ab2016-09-01 11:24:54 -0700192 const char* gNames[] = {
Ben Wagner83c6b962018-07-10 19:40:15 -0400193 "Helvetica Neue", "Arial", "sans"
reed@google.com964988f2013-03-29 14:57:22 +0000194 };
195
Hal Canarycefc4312016-11-04 16:26:16 -0400196 sk_sp<SkFontStyleSet> fset;
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000197 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
bungeman@google.com9fc5c682013-11-12 15:25:29 +0000198 fset.reset(fFM->matchFamily(gNames[i]));
199 if (fset->count() > 0) {
reed@google.com964988f2013-03-29 14:57:22 +0000200 break;
201 }
202 }
halcanary96fcdcc2015-08-27 07:41:13 -0700203 if (nullptr == fset.get()) {
Chris Dalton50e24d72019-02-07 16:20:09 -0700204 *errorMsg = "No SkFontStyleSet";
205 return DrawResult::kFail;
reed@google.com964988f2013-03-29 14:57:22 +0000206 }
reed@google.com964988f2013-03-29 14:57:22 +0000207
208 canvas->translate(20, 40);
Mike Reed560d5b32018-12-16 16:36:48 -0500209 this->exploreFamily(canvas, font, fset.get());
reed@google.com964988f2013-03-29 14:57:22 +0000210 canvas->translate(150, 0);
Mike Reed560d5b32018-12-16 16:36:48 -0500211 this->iterateFamily(canvas, font, fset.get());
Chris Dalton50e24d72019-02-07 16:20:09 -0700212 return DrawResult::kOk;
reed@google.com964988f2013-03-29 14:57:22 +0000213 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000214
reed@google.com964988f2013-03-29 14:57:22 +0000215private:
216 typedef GM INHERITED;
217};
218
reeda0c814c2014-10-22 13:20:58 -0700219class FontMgrBoundsGM : public skiagm::GM {
220public:
reed8893e5f2014-12-15 13:27:26 -0800221 FontMgrBoundsGM(double scale, double skew)
Ben Wagner110c7032019-03-22 17:03:59 -0400222 : fFM(SkFontMgr::RefDefault())
223 , fName("fontmgr_bounds")
224 , fScaleX(SkDoubleToScalar(scale))
reed8893e5f2014-12-15 13:27:26 -0800225 , fSkewX(SkDoubleToScalar(skew))
Ben Wagner110c7032019-03-22 17:03:59 -0400226 , fLabelBounds(false)
reed8893e5f2014-12-15 13:27:26 -0800227 {
reed8893e5f2014-12-15 13:27:26 -0800228 if (scale != 1 || skew != 0) {
229 fName.appendf("_%g_%g", scale, skew);
230 }
Ben Wagner110c7032019-03-22 17:03:59 -0400231 }
232
233 bool onGetControls(SkMetaData* controls) override {
234 controls->setBool("Label Bounds", fLabelBounds);
235 return true;
236 }
237
238 void onSetControls(const SkMetaData& controls) override {
239 controls.findBool("Label Bounds", &fLabelBounds);
reeda0c814c2014-10-22 13:20:58 -0700240 }
241
Mike Reed7d1eb332018-12-04 17:35:56 -0500242 static void show_bounds(SkCanvas* canvas, const SkFont& font, SkScalar x, SkScalar y,
Ben Wagner110c7032019-03-22 17:03:59 -0400243 SkColor boundsColor, bool labelBounds)
Ben Wagner219f3622017-07-17 15:32:25 -0400244 {
Mike Reed7d1eb332018-12-04 17:35:56 -0500245 SkRect fontBounds = SkFontPriv::GetFontBounds(font).makeOffset(x, y);
246
247 SkPaint boundsPaint;
248 boundsPaint.setAntiAlias(true);
Ben Wagner219f3622017-07-17 15:32:25 -0400249 boundsPaint.setColor(boundsColor);
Ben Wagner97182cc2018-02-15 10:20:04 -0500250 boundsPaint.setStyle(SkPaint::kStroke_Style);
Ben Wagner219f3622017-07-17 15:32:25 -0400251 canvas->drawRect(fontBounds, boundsPaint);
reeda0c814c2014-10-22 13:20:58 -0700252
Mike Reedcb6f53e2018-11-06 12:44:54 -0500253 SkFontMetrics fm;
Mike Reed7d1eb332018-12-04 17:35:56 -0500254 font.getMetrics(&fm);
Ben Wagner219f3622017-07-17 15:32:25 -0400255 SkPaint metricsPaint(boundsPaint);
256 metricsPaint.setStyle(SkPaint::kFill_Style);
Mike Reed9407e242019-02-15 16:13:57 -0500257 metricsPaint.setAlphaf(0.25f);
Mike Reedb5784ac2018-11-12 09:35:15 -0500258 if ((fm.fFlags & SkFontMetrics::kUnderlinePositionIsValid_Flag) &&
Ben Wagner9ca55f22019-02-12 15:04:17 -0500259 (fm.fFlags & SkFontMetrics::kUnderlineThicknessIsValid_Flag))
Ben Wagner219f3622017-07-17 15:32:25 -0400260 {
261 SkRect underline{ fontBounds.fLeft, fm.fUnderlinePosition+y,
262 fontBounds.fRight, fm.fUnderlinePosition+y + fm.fUnderlineThickness };
263 canvas->drawRect(underline, metricsPaint);
reeda0c814c2014-10-22 13:20:58 -0700264 }
tfarinaaa458fb2015-01-05 17:18:51 -0800265
Mike Reedb5784ac2018-11-12 09:35:15 -0500266 if ((fm.fFlags & SkFontMetrics::kStrikeoutPositionIsValid_Flag) &&
Ben Wagner9ca55f22019-02-12 15:04:17 -0500267 (fm.fFlags & SkFontMetrics::kStrikeoutThicknessIsValid_Flag))
Ben Wagner219f3622017-07-17 15:32:25 -0400268 {
269 SkRect strikeout{ fontBounds.fLeft, fm.fStrikeoutPosition+y - fm.fStrikeoutThickness,
270 fontBounds.fRight, fm.fStrikeoutPosition+y };
271 canvas->drawRect(strikeout, metricsPaint);
272 }
273
274 SkGlyphID left = 0, right = 0, top = 0, bottom = 0;
275 {
Herb Derby087fad72019-01-22 14:45:16 -0500276 int numGlyphs = font.getTypefaceOrDefault()->countGlyphs();
Ben Wagner219f3622017-07-17 15:32:25 -0400277 SkRect min = {0, 0, 0, 0};
Ben Wagner219f3622017-07-17 15:32:25 -0400278 for (int i = 0; i < numGlyphs; ++i) {
279 SkGlyphID glyphId = i;
280 SkRect cur;
Mike Reed7d1eb332018-12-04 17:35:56 -0500281 font.getBounds(&glyphId, 1, &cur, nullptr);
Ben Wagner219f3622017-07-17 15:32:25 -0400282 if (cur.fLeft < min.fLeft ) { min.fLeft = cur.fLeft; left = i; }
283 if (cur.fTop < min.fTop ) { min.fTop = cur.fTop ; top = i; }
284 if (min.fRight < cur.fRight ) { min.fRight = cur.fRight; right = i; }
285 if (min.fBottom < cur.fBottom) { min.fBottom = cur.fBottom; bottom = i; }
286 }
287 }
288 SkGlyphID str[] = { left, right, top, bottom };
Ben Wagner17bca9a2018-06-22 15:27:52 -0400289 SkPoint location[] = {
290 {fontBounds.left(), fontBounds.centerY()},
291 {fontBounds.right(), fontBounds.centerY()},
292 {fontBounds.centerX(), fontBounds.top()},
293 {fontBounds.centerX(), fontBounds.bottom()}
294 };
295
Mike Reed7d1eb332018-12-04 17:35:56 -0500296 SkFont labelFont;
297 labelFont.setEdging(SkFont::Edging::kAntiAlias);
Mike Kleinea3f0142019-03-20 11:12:10 -0500298 labelFont.setTypeface(ToolUtils::create_portable_typeface());
Mike Reed7d1eb332018-12-04 17:35:56 -0500299
Ben Wagner110c7032019-03-22 17:03:59 -0400300 if (labelBounds) {
Ben Wagner17bca9a2018-06-22 15:27:52 -0400301 SkString name;
Herb Derby087fad72019-01-22 14:45:16 -0500302 font.getTypefaceOrDefault()->getFamilyName(&name);
Hal Canary89a644b2019-01-07 09:36:09 -0500303 canvas->drawString(name, fontBounds.fLeft, fontBounds.fBottom, labelFont, SkPaint());
Ben Wagner17bca9a2018-06-22 15:27:52 -0400304 }
Ben Wagner219f3622017-07-17 15:32:25 -0400305 for (size_t i = 0; i < SK_ARRAY_COUNT(str); ++i) {
Ben Wagner97182cc2018-02-15 10:20:04 -0500306 SkPath path;
Mike Reed7d1eb332018-12-04 17:35:56 -0500307 font.getPath(str[i], &path);
308 path.offset(x, y);
Ben Wagner97182cc2018-02-15 10:20:04 -0500309 SkPaint::Style style = path.isEmpty() ? SkPaint::kFill_Style : SkPaint::kStroke_Style;
Mike Reed7d1eb332018-12-04 17:35:56 -0500310 SkPaint glyphPaint;
Ben Wagner97182cc2018-02-15 10:20:04 -0500311 glyphPaint.setStyle(style);
Ben Wagner51e15a62019-05-07 15:38:46 -0400312 canvas->drawSimpleText(&str[i], sizeof(str[0]), SkTextEncoding::kGlyphID, x, y, font, glyphPaint);
Ben Wagner17bca9a2018-06-22 15:27:52 -0400313
Ben Wagner110c7032019-03-22 17:03:59 -0400314 if (labelBounds) {
Ben Wagner17bca9a2018-06-22 15:27:52 -0400315 SkString glyphStr;
316 glyphStr.appendS32(str[i]);
Hal Canary89a644b2019-01-07 09:36:09 -0500317 canvas->drawString(glyphStr, location[i].fX, location[i].fY, labelFont, SkPaint());
Ben Wagner17bca9a2018-06-22 15:27:52 -0400318 }
319
Ben Wagner219f3622017-07-17 15:32:25 -0400320 }
Ben Wagner17bca9a2018-06-22 15:27:52 -0400321
reeda0c814c2014-10-22 13:20:58 -0700322 }
323
324protected:
mtklein36352bf2015-03-25 18:17:31 -0700325 SkString onShortName() override {
reeda0c814c2014-10-22 13:20:58 -0700326 return fName;
327 }
tfarinaaa458fb2015-01-05 17:18:51 -0800328
mtklein36352bf2015-03-25 18:17:31 -0700329 SkISize onISize() override {
reeda0c814c2014-10-22 13:20:58 -0700330 return SkISize::Make(1024, 850);
331 }
tfarinaaa458fb2015-01-05 17:18:51 -0800332
mtklein36352bf2015-03-25 18:17:31 -0700333 void onDraw(SkCanvas* canvas) override {
Mike Reed7d1eb332018-12-04 17:35:56 -0500334 SkFont font;
335 font.setEdging(SkFont::Edging::kAntiAlias);
336 font.setSubpixel(true);
337 font.setSize(100);
338 font.setScaleX(fScaleX);
339 font.setSkewX(fSkewX);
reeda0c814c2014-10-22 13:20:58 -0700340
341 const SkColor boundsColors[2] = { SK_ColorRED, SK_ColorBLUE };
halcanary9d524f22016-03-29 09:03:52 -0700342
Hal Canarycefc4312016-11-04 16:26:16 -0400343 SkFontMgr* fm = fFM.get();
reeda0c814c2014-10-22 13:20:58 -0700344 int count = SkMin32(fm->countFamilies(), 32);
345
346 int index = 0;
347 SkScalar x = 0, y = 0;
348
Ben Wagner219f3622017-07-17 15:32:25 -0400349 canvas->translate(10, 120);
reeda0c814c2014-10-22 13:20:58 -0700350
351 for (int i = 0; i < count; ++i) {
Hal Canarycefc4312016-11-04 16:26:16 -0400352 sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
Ben Wagner219f3622017-07-17 15:32:25 -0400353 for (int j = 0; j < set->count() && j < 3; ++j) {
Mike Reed7d1eb332018-12-04 17:35:56 -0500354 font.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
Ben Wagner2112df02017-07-24 11:04:21 -0400355 // Fonts with lots of glyphs are interesting, but can take a long time to find
356 // the glyphs which make up the maximum extent.
Herb Derby087fad72019-01-22 14:45:16 -0500357 if (font.getTypefaceOrDefault() && font.getTypefaceOrDefault()->countGlyphs() < 1000) {
Mike Reed7d1eb332018-12-04 17:35:56 -0500358 SkRect fontBounds = SkFontPriv::GetFontBounds(font);
Ben Wagner219f3622017-07-17 15:32:25 -0400359 x -= fontBounds.fLeft;
Ben Wagner110c7032019-03-22 17:03:59 -0400360 show_bounds(canvas, font, x, y, boundsColors[index & 1], fLabelBounds);
Ben Wagner219f3622017-07-17 15:32:25 -0400361 x += fontBounds.fRight + 20;
reeda0c814c2014-10-22 13:20:58 -0700362 index += 1;
Ben Wagner219f3622017-07-17 15:32:25 -0400363 if (x > 900) {
reeda0c814c2014-10-22 13:20:58 -0700364 x = 0;
365 y += 160;
366 }
Ben Wagner219f3622017-07-17 15:32:25 -0400367 if (y >= 700) {
reeda0c814c2014-10-22 13:20:58 -0700368 return;
369 }
370 }
371 }
372 }
373 }
mtklein1c402922015-01-23 11:07:07 -0800374
reeda0c814c2014-10-22 13:20:58 -0700375private:
Ben Wagner110c7032019-03-22 17:03:59 -0400376 const sk_sp<SkFontMgr> fFM;
reeda0c814c2014-10-22 13:20:58 -0700377 SkString fName;
Ben Wagner110c7032019-03-22 17:03:59 -0400378 const SkScalar fScaleX;
379 const SkScalar fSkewX;
380 bool fLabelBounds;
reeda0c814c2014-10-22 13:20:58 -0700381 typedef GM INHERITED;
382};
383
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000384//////////////////////////////////////////////////////////////////////////////
385
halcanary385fe4d2015-08-26 13:07:48 -0700386DEF_GM(return new FontMgrGM;)
387DEF_GM(return new FontMgrMatchGM;)
388DEF_GM(return new FontMgrBoundsGM(1.0, 0);)
389DEF_GM(return new FontMgrBoundsGM(0.75, 0);)
390DEF_GM(return new FontMgrBoundsGM(1.0, -0.25);)