Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / gm / fontmgr.cpp
1 /*
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
14 #ifdef SK_BUILD_FOR_WIN
15     #include "SkTypeface_win.h"
16 #endif
17
18 // limit this just so we don't take too long to draw
19 #define MAX_FAMILIES    30
20
21 static 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
27 static SkScalar drawCharacter(SkCanvas* canvas, uint32_t character, SkScalar x,
28                               SkScalar y, SkPaint& paint, SkFontMgr* fm,
29                               const char* fontName, const char* bpc47,
30                               const SkFontStyle& fontStyle) {
31     // find typeface containing the requested character and draw it
32     SkString ch;
33     ch.appendUnichar(character);
34     SkTypeface* typeface = fm->matchFamilyStyleCharacter(fontName, fontStyle, bpc47, character);
35     SkSafeUnref(paint.setTypeface(typeface));
36     x = drawString(canvas, ch, x, y, paint) + 20;
37
38     if (NULL == typeface) {
39         return x;
40     }
41
42     // repeat the process, but this time use the family name of the typeface
43     // from the first pass.  This emulates the behavior in Blink where it
44     // it expects to get the same glyph when following this pattern.
45     SkString familyName;
46     typeface->getFamilyName(&familyName);
47     SkTypeface* typefaceCopy = fm->legacyCreateTypeface(familyName.c_str(), typeface->style());
48     SkSafeUnref(paint.setTypeface(typefaceCopy));
49     return drawString(canvas, ch, x, y, paint) + 20;
50 }
51
52 class FontMgrGM : public skiagm::GM {
53 public:
54     FontMgrGM(SkFontMgr* fontMgr = NULL) {
55         SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
56
57         fName.set("fontmgr_iter");
58         if (fontMgr) {
59             fName.append("_factory");
60             fFM.reset(fontMgr);
61         } else {
62             fFM.reset(SkFontMgr::RefDefault());
63         }
64     }
65
66 protected:
67     virtual SkString onShortName() {
68         return fName;
69     }
70
71     virtual SkISize onISize() {
72         return SkISize::Make(1536, 768);
73     }
74
75     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
76         SkScalar y = 20;
77         SkPaint paint;
78         paint.setAntiAlias(true);
79         paint.setLCDRenderText(true);
80         paint.setSubpixelText(true);
81         paint.setTextSize(17);
82
83         SkFontMgr* fm = fFM;
84         int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
85
86         for (int i = 0; i < count; ++i) {
87             SkString fname;
88             fm->getFamilyName(i, &fname);
89             paint.setTypeface(NULL);
90             (void)drawString(canvas, fname, 20, y, paint);
91
92             SkScalar x = 220;
93
94             SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i));
95             for (int j = 0; j < set->count(); ++j) {
96                 SkString sname;
97                 SkFontStyle fs;
98                 set->getStyle(j, &fs, &sname);
99                 sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.isItalic());
100
101                 SkSafeUnref(paint.setTypeface(set->createTypeface(j)));
102                 x = drawString(canvas, sname, x, y, paint) + 20;
103
104                 // check to see that we get different glyphs in japanese and chinese
105                 x = drawCharacter(canvas, 0x5203, x, y, paint, fm, fName.c_str(), "zh", fs);
106                 x = drawCharacter(canvas, 0x5203, x, y, paint, fm, fName.c_str(), "ja", fs);
107                 // check that emoji characters are found
108                 x = drawCharacter(canvas, 0x1f601, x, y, paint, fm, fName.c_str(), NULL, fs);
109             }
110             y += 24;
111         }
112     }
113
114     virtual uint32_t onGetFlags() const SK_OVERRIDE {
115         // fontdescriptors (and therefore serialization) don't yet understand
116         // these new styles, so skip tests that exercise that for now.
117
118         // If certain fonts are picked up (e.g. Microsoft Jhenghei 20MB for Regular, 12MB for Bold),
119         // the resulting pdf can be ~700MB and crashes Chrome's PDF viewer.
120
121         return kSkipPicture_Flag | kSkipPipe_Flag | kSkipPDF_Flag;
122     }
123
124 private:
125     SkAutoTUnref<SkFontMgr> fFM;
126     SkString fName;
127     typedef GM INHERITED;
128 };
129
130 class FontMgrMatchGM : public skiagm::GM {
131     SkAutoTUnref<SkFontMgr> fFM;
132
133 public:
134     FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) {
135         SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
136     }
137
138 protected:
139     virtual SkString onShortName() {
140         return SkString("fontmgr_match");
141     }
142
143     virtual SkISize onISize() {
144         return SkISize::Make(640, 1024);
145     }
146
147     void iterateFamily(SkCanvas* canvas, const SkPaint& paint,
148                        SkFontStyleSet* fset) {
149         SkPaint p(paint);
150         SkScalar y = 0;
151
152         for (int j = 0; j < fset->count(); ++j) {
153             SkString sname;
154             SkFontStyle fs;
155             fset->getStyle(j, &fs, &sname);
156
157             sname.appendf(" [%d %d]", fs.weight(), fs.width());
158
159             SkSafeUnref(p.setTypeface(fset->createTypeface(j)));
160             (void)drawString(canvas, sname, 0, y, p);
161             y += 24;
162         }
163     }
164
165     void exploreFamily(SkCanvas* canvas, const SkPaint& paint,
166                        SkFontStyleSet* fset) {
167         SkPaint p(paint);
168         SkScalar y = 0;
169
170         for (int weight = 100; weight <= 900; weight += 200) {
171             for (int width = 1; width <= 9; width += 2) {
172                 SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
173                 SkTypeface* face = fset->matchStyle(fs);
174                 if (face) {
175                     SkString str;
176                     str.printf("request [%d %d]", fs.weight(), fs.width());
177                     p.setTypeface(face)->unref();
178                     (void)drawString(canvas, str, 0, y, p);
179                     y += 24;
180                 }
181             }
182         }
183     }
184
185     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
186         SkPaint paint;
187         paint.setAntiAlias(true);
188         paint.setLCDRenderText(true);
189         paint.setSubpixelText(true);
190         paint.setTextSize(17);
191
192         static const char* gNames[] = {
193             "Helvetica Neue", "Arial"
194         };
195
196         SkAutoTUnref<SkFontStyleSet> fset;
197         for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
198             fset.reset(fFM->matchFamily(gNames[i]));
199             if (fset->count() > 0) {
200                 break;
201             }
202         }
203         if (NULL == fset.get()) {
204             return;
205         }
206
207         canvas->translate(20, 40);
208         this->exploreFamily(canvas, paint, fset);
209         canvas->translate(150, 0);
210         this->iterateFamily(canvas, paint, fset);
211     }
212
213     virtual uint32_t onGetFlags() const SK_OVERRIDE {
214         // fontdescriptors (and therefore serialization) don't yet understand
215         // these new styles, so skip tests that exercise that for now.
216         return kSkipPicture_Flag | kSkipPipe_Flag;
217     }
218
219 private:
220     typedef GM INHERITED;
221 };
222
223 //////////////////////////////////////////////////////////////////////////////
224
225 DEF_GM( return SkNEW(FontMgrGM); )
226 DEF_GM( return SkNEW(FontMgrMatchGM); )
227
228 #ifdef SK_BUILD_FOR_WIN
229     DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite())); )
230 #endif