blob: 9c300ab502e38d805d89f43bae5cfd07029ffc50 [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
15 extern SkFontMgr* SkFontMgr_New_GDI();
16 extern SkFontMgr* SkFontMgr_New_DirectWrite();
17#endif
18
reed@google.comaf0fa6a2013-03-28 13:39:35 +000019// limit this just so we don't take too long to draw
20#define MAX_FAMILIES 30
21
22static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
23 SkScalar y, const SkPaint& paint) {
24 canvas->drawText(text.c_str(), text.size(), x, y, paint);
25 return x + paint.measureText(text.c_str(), text.size());
26}
27
28class FontMgrGM : public skiagm::GM {
29public:
bungeman@google.combfc6cc42013-08-21 15:20:43 +000030 FontMgrGM(SkFontMgr* (*factory)() = NULL) {
reed@google.comaf0fa6a2013-03-28 13:39:35 +000031 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
bungeman@google.combfc6cc42013-08-21 15:20:43 +000032
33 fName.set("fontmgr_iter");
34 if (factory) {
35 fName.append("_factory");
36 fFM.reset(factory());
37 } else {
38 fFM.reset(SkFontMgr::RefDefault());
39 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +000040 }
41
42protected:
43 virtual SkString onShortName() {
bungeman@google.combfc6cc42013-08-21 15:20:43 +000044 return fName;
reed@google.comaf0fa6a2013-03-28 13:39:35 +000045 }
46
47 virtual SkISize onISize() {
48 return SkISize::Make(640, 1024);
49 }
50
51 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
52 SkScalar y = 20;
53 SkPaint paint;
54 paint.setAntiAlias(true);
55 paint.setLCDRenderText(true);
56 paint.setSubpixelText(true);
57 paint.setTextSize(17);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000058
bungeman@google.combfc6cc42013-08-21 15:20:43 +000059 SkFontMgr* fm = fFM;
reed@google.comaf0fa6a2013-03-28 13:39:35 +000060 int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
61
62 for (int i = 0; i < count; ++i) {
63 SkString fname;
64 fm->getFamilyName(i, &fname);
65 paint.setTypeface(NULL);
66 (void)drawString(canvas, fname, 20, y, paint);
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000067
reed@google.comaf0fa6a2013-03-28 13:39:35 +000068 SkScalar x = 220;
reed@google.com964988f2013-03-29 14:57:22 +000069
reed@google.comaf0fa6a2013-03-28 13:39:35 +000070 SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i));
71 for (int j = 0; j < set->count(); ++j) {
72 SkString sname;
73 SkFontStyle fs;
74 set->getStyle(j, &fs, &sname);
reed@google.com51116482013-04-24 19:14:39 +000075 sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.isItalic());
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000076
reed@google.comaf0fa6a2013-03-28 13:39:35 +000077 SkSafeUnref(paint.setTypeface(set->createTypeface(j)));
78 x = drawString(canvas, sname, x, y, paint) + 20;
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +000079 }
reed@google.comaf0fa6a2013-03-28 13:39:35 +000080 y += 24;
81 }
82 }
83
reed@google.com6518daf2013-03-28 15:03:22 +000084 virtual uint32_t onGetFlags() const SK_OVERRIDE {
85 // fontdescriptors (and therefore serialization) don't yet understand
86 // these new styles, so skip tests that exercise that for now.
bungeman@google.com71033442013-05-01 14:21:20 +000087
88 // If certain fonts are picked up (e.g. Microsoft Jhenghei 20MB for Regular, 12MB for Bold),
89 // the resulting pdf can be ~700MB and crashes Chrome's PDF viewer.
90
91 return kSkipPicture_Flag | kSkipPipe_Flag | kSkipPDF_Flag;
reed@google.com6518daf2013-03-28 15:03:22 +000092 }
93
reed@google.comaf0fa6a2013-03-28 13:39:35 +000094private:
bungeman@google.combfc6cc42013-08-21 15:20:43 +000095 SkAutoTUnref<SkFontMgr> fFM;
96 SkString fName;
reed@google.comaf0fa6a2013-03-28 13:39:35 +000097 typedef GM INHERITED;
98};
99
reed@google.com964988f2013-03-29 14:57:22 +0000100class FontMgrMatchGM : public skiagm::GM {
101 SkAutoTUnref<SkFontMgr> fFM;
102
103public:
104 FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) {
105 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
106 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000107
reed@google.com964988f2013-03-29 14:57:22 +0000108protected:
109 virtual SkString onShortName() {
110 return SkString("fontmgr_match");
111 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000112
reed@google.com964988f2013-03-29 14:57:22 +0000113 virtual SkISize onISize() {
114 return SkISize::Make(640, 1024);
115 }
116
117 void iterateFamily(SkCanvas* canvas, const SkPaint& paint,
118 SkFontStyleSet* fset) {
119 SkPaint p(paint);
120 SkScalar y = 0;
121
122 for (int j = 0; j < fset->count(); ++j) {
123 SkString sname;
124 SkFontStyle fs;
125 fset->getStyle(j, &fs, &sname);
126
127 sname.appendf(" [%d %d]", fs.weight(), fs.width());
128
129 SkSafeUnref(p.setTypeface(fset->createTypeface(j)));
130 (void)drawString(canvas, sname, 0, y, p);
131 y += 24;
132 }
133 }
134
135 void exploreFamily(SkCanvas* canvas, const SkPaint& paint,
136 SkFontStyleSet* fset) {
137 SkPaint p(paint);
138 SkScalar y = 0;
139
140 for (int weight = 100; weight <= 900; weight += 200) {
141 for (int width = 1; width <= 9; width += 2) {
142 SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
143 SkTypeface* face = fset->matchStyle(fs);
144 if (face) {
145 SkString str;
146 str.printf("request [%d %d]", fs.weight(), fs.width());
147 p.setTypeface(face)->unref();
148 (void)drawString(canvas, str, 0, y, p);
149 y += 24;
150 }
151 }
152 }
153 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000154
reed@google.com964988f2013-03-29 14:57:22 +0000155 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
156 SkPaint paint;
157 paint.setAntiAlias(true);
158 paint.setLCDRenderText(true);
159 paint.setSubpixelText(true);
160 paint.setTextSize(17);
161
162 static const char* gNames[] = {
163 "Helvetica Neue", "Arial"
164 };
165
166 SkFontStyleSet* fset = NULL;
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000167 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
reed@google.com964988f2013-03-29 14:57:22 +0000168 fset = fFM->matchFamily(gNames[i]);
169 if (fset && fset->count() > 0) {
170 break;
171 }
172 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000173
reed@google.com964988f2013-03-29 14:57:22 +0000174 if (NULL == fset) {
175 return;
176 }
177 SkAutoUnref aur(fset);
178
179 canvas->translate(20, 40);
180 this->exploreFamily(canvas, paint, fset);
181 canvas->translate(150, 0);
182 this->iterateFamily(canvas, paint, fset);
183 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000184
reed@google.com964988f2013-03-29 14:57:22 +0000185 virtual uint32_t onGetFlags() const SK_OVERRIDE {
186 // fontdescriptors (and therefore serialization) don't yet understand
187 // these new styles, so skip tests that exercise that for now.
188 return kSkipPicture_Flag | kSkipPipe_Flag;
189 }
skia.committer@gmail.comd55846d2013-03-30 07:01:27 +0000190
reed@google.com964988f2013-03-29 14:57:22 +0000191private:
192 typedef GM INHERITED;
193};
194
reed@google.comaf0fa6a2013-03-28 13:39:35 +0000195//////////////////////////////////////////////////////////////////////////////
196
197DEF_GM( return SkNEW(FontMgrGM); )
reed@google.com964988f2013-03-29 14:57:22 +0000198DEF_GM( return SkNEW(FontMgrMatchGM); )
bungeman@google.combfc6cc42013-08-21 15:20:43 +0000199
200#ifdef SK_BUILD_FOR_WIN
201 DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite)); )
202#endif