blob: d9a0aa5f4ba02ee5498b594e5b29d7ad049a4a5a [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
8#include "gm.h"
9#include "SkCanvas.h"
10#include "SkFontMgr.h"
11#include "SkGraphics.h"
12#include "SkTypeface.h"
13
bungeman@google.combfc6cc42013-08-21 15:20:43 +000014#ifdef SK_BUILD_FOR_WIN
reed@google.comd1bcfc92013-08-28 20:31:58 +000015 #include "SkTypeface_win.h"
bungeman@google.combfc6cc42013-08-21 15:20:43 +000016#endif
17
reed@google.comaf0fa6a2013-03-28 13:39:35 +000018// limit this just so we don't take too long to draw
19#define MAX_FAMILIES 30
20
21static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
22 SkScalar y, const SkPaint& paint) {
23 canvas->drawText(text.c_str(), text.size(), x, y, paint);
24 return x + paint.measureText(text.c_str(), text.size());
25}
26
27class FontMgrGM : public skiagm::GM {
28public:
bungeman@google.com6eddc772014-03-31 19:18:07 +000029 FontMgrGM(SkFontMgr* fontMgr = NULL) {
reed@google.comaf0fa6a2013-03-28 13:39:35 +000030 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
bungeman@google.combfc6cc42013-08-21 15:20:43 +000031
32 fName.set("fontmgr_iter");
bungeman@google.com6eddc772014-03-31 19:18:07 +000033 if (fontMgr) {
bungeman@google.combfc6cc42013-08-21 15:20:43 +000034 fName.append("_factory");
bungeman@google.com6eddc772014-03-31 19:18:07 +000035 fFM.reset(fontMgr);
bungeman@google.combfc6cc42013-08-21 15:20:43 +000036 } else {
37 fFM.reset(SkFontMgr::RefDefault());
38 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +000039 }
40
41protected:
42 virtual SkString onShortName() {
bungeman@google.combfc6cc42013-08-21 15:20:43 +000043 return fName;
reed@google.comaf0fa6a2013-03-28 13:39:35 +000044 }
45
46 virtual SkISize onISize() {
47 return SkISize::Make(640, 1024);
48 }
49
50 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
51 SkScalar y = 20;
52 SkPaint paint;
53 paint.setAntiAlias(true);
54 paint.setLCDRenderText(true);
55 paint.setSubpixelText(true);
56 paint.setTextSize(17);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000057
bungeman@google.combfc6cc42013-08-21 15:20:43 +000058 SkFontMgr* fm = fFM;
reed@google.comaf0fa6a2013-03-28 13:39:35 +000059 int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
60
61 for (int i = 0; i < count; ++i) {
62 SkString fname;
63 fm->getFamilyName(i, &fname);
64 paint.setTypeface(NULL);
65 (void)drawString(canvas, fname, 20, y, paint);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000066
reed@google.comaf0fa6a2013-03-28 13:39:35 +000067 SkScalar x = 220;
reed@google.com964988f2013-03-29 14:57:22 +000068
reed@google.comaf0fa6a2013-03-28 13:39:35 +000069 SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i));
70 for (int j = 0; j < set->count(); ++j) {
71 SkString sname;
72 SkFontStyle fs;
73 set->getStyle(j, &fs, &sname);
reed@google.com51116482013-04-24 19:14:39 +000074 sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.isItalic());
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000075
reed@google.comaf0fa6a2013-03-28 13:39:35 +000076 SkSafeUnref(paint.setTypeface(set->createTypeface(j)));
77 x = drawString(canvas, sname, x, y, paint) + 20;
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000078 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +000079 y += 24;
80 }
81 }
82
reed@google.com6518daf2013-03-28 15:03:22 +000083 virtual uint32_t onGetFlags() const SK_OVERRIDE {
84 // fontdescriptors (and therefore serialization) don't yet understand
85 // these new styles, so skip tests that exercise that for now.
bungeman@google.com71033442013-05-01 14:21:20 +000086
87 // If certain fonts are picked up (e.g. Microsoft Jhenghei 20MB for Regular, 12MB for Bold),
88 // the resulting pdf can be ~700MB and crashes Chrome's PDF viewer.
89
90 return kSkipPicture_Flag | kSkipPipe_Flag | kSkipPDF_Flag;
reed@google.com6518daf2013-03-28 15:03:22 +000091 }
92
reed@google.comaf0fa6a2013-03-28 13:39:35 +000093private:
bungeman@google.combfc6cc42013-08-21 15:20:43 +000094 SkAutoTUnref<SkFontMgr> fFM;
95 SkString fName;
reed@google.comaf0fa6a2013-03-28 13:39:35 +000096 typedef GM INHERITED;
97};
98
reed@google.com964988f2013-03-29 14:57:22 +000099class FontMgrMatchGM : public skiagm::GM {
100 SkAutoTUnref<SkFontMgr> fFM;
101
102public:
103 FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) {
104 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
105 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000106
reed@google.com964988f2013-03-29 14:57:22 +0000107protected:
108 virtual SkString onShortName() {
109 return SkString("fontmgr_match");
110 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000111
reed@google.com964988f2013-03-29 14:57:22 +0000112 virtual SkISize onISize() {
113 return SkISize::Make(640, 1024);
114 }
115
116 void iterateFamily(SkCanvas* canvas, const SkPaint& paint,
117 SkFontStyleSet* fset) {
118 SkPaint p(paint);
119 SkScalar y = 0;
120
121 for (int j = 0; j < fset->count(); ++j) {
122 SkString sname;
123 SkFontStyle fs;
124 fset->getStyle(j, &fs, &sname);
125
126 sname.appendf(" [%d %d]", fs.weight(), fs.width());
127
128 SkSafeUnref(p.setTypeface(fset->createTypeface(j)));
129 (void)drawString(canvas, sname, 0, y, p);
130 y += 24;
131 }
132 }
133
134 void exploreFamily(SkCanvas* canvas, const SkPaint& paint,
135 SkFontStyleSet* fset) {
136 SkPaint p(paint);
137 SkScalar y = 0;
138
139 for (int weight = 100; weight <= 900; weight += 200) {
140 for (int width = 1; width <= 9; width += 2) {
141 SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
142 SkTypeface* face = fset->matchStyle(fs);
143 if (face) {
144 SkString str;
145 str.printf("request [%d %d]", fs.weight(), fs.width());
146 p.setTypeface(face)->unref();
147 (void)drawString(canvas, str, 0, y, p);
148 y += 24;
149 }
150 }
151 }
152 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000153
reed@google.com964988f2013-03-29 14:57:22 +0000154 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
155 SkPaint paint;
156 paint.setAntiAlias(true);
157 paint.setLCDRenderText(true);
158 paint.setSubpixelText(true);
159 paint.setTextSize(17);
160
161 static const char* gNames[] = {
162 "Helvetica Neue", "Arial"
163 };
164
bungeman@google.com9fc5c682013-11-12 15:25:29 +0000165 SkAutoTUnref<SkFontStyleSet> fset;
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000166 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
bungeman@google.com9fc5c682013-11-12 15:25:29 +0000167 fset.reset(fFM->matchFamily(gNames[i]));
168 if (fset->count() > 0) {
reed@google.com964988f2013-03-29 14:57:22 +0000169 break;
170 }
171 }
bungeman@google.com9fc5c682013-11-12 15:25:29 +0000172 if (NULL == fset.get()) {
reed@google.com964988f2013-03-29 14:57:22 +0000173 return;
174 }
reed@google.com964988f2013-03-29 14:57:22 +0000175
176 canvas->translate(20, 40);
177 this->exploreFamily(canvas, paint, fset);
178 canvas->translate(150, 0);
179 this->iterateFamily(canvas, paint, fset);
180 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000181
reed@google.com964988f2013-03-29 14:57:22 +0000182 virtual uint32_t onGetFlags() const SK_OVERRIDE {
183 // fontdescriptors (and therefore serialization) don't yet understand
184 // these new styles, so skip tests that exercise that for now.
185 return kSkipPicture_Flag | kSkipPipe_Flag;
186 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000187
reed@google.com964988f2013-03-29 14:57:22 +0000188private:
189 typedef GM INHERITED;
190};
191
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000192//////////////////////////////////////////////////////////////////////////////
193
194DEF_GM( return SkNEW(FontMgrGM); )
reed@google.com964988f2013-03-29 14:57:22 +0000195DEF_GM( return SkNEW(FontMgrMatchGM); )
bungeman@google.combfc6cc42013-08-21 15:20:43 +0000196
197#ifdef SK_BUILD_FOR_WIN
bungeman@google.com6eddc772014-03-31 19:18:07 +0000198 DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite())); )
bungeman@google.combfc6cc42013-08-21 15:20:43 +0000199#endif