1af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com/*
2af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com * Copyright 2013 Google Inc.
3af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com *
4af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com * Use of this source code is governed by a BSD-style license that can be
5af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com * found in the LICENSE file.
6af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com */
7af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
8af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "gm.h"
9af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkCanvas.h"
10af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkFontMgr.h"
11af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkGraphics.h"
12af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkTypeface.h"
13af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
14bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com#ifdef SK_BUILD_FOR_WIN
15d1bcfc9a1938b051e5948b059a8259cd37fb8229reed@google.com    #include "SkTypeface_win.h"
16bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com#endif
17bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com
18af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com// limit this just so we don't take too long to draw
19af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#define MAX_FAMILIES    30
20af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
21af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comstatic SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
22af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                           SkScalar y, const SkPaint& paint) {
23af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    canvas->drawText(text.c_str(), text.size(), x, y, paint);
24af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    return x + paint.measureText(text.c_str(), text.size());
25af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com}
26af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
27af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comclass FontMgrGM : public skiagm::GM {
28af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.compublic:
296eddc77f6a0078570471277954c07d73b3a921d8bungeman@google.com    FontMgrGM(SkFontMgr* fontMgr = NULL) {
30af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
31bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com
32bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com        fName.set("fontmgr_iter");
336eddc77f6a0078570471277954c07d73b3a921d8bungeman@google.com        if (fontMgr) {
34bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com            fName.append("_factory");
356eddc77f6a0078570471277954c07d73b3a921d8bungeman@google.com            fFM.reset(fontMgr);
36bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com        } else {
37bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com            fFM.reset(SkFontMgr::RefDefault());
38bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com        }
39af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    }
40af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
41af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comprotected:
42af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    virtual SkString onShortName() {
43bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com        return fName;
44af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    }
45af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
46af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    virtual SkISize onISize() {
47af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        return SkISize::Make(640, 1024);
48af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    }
49af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
50af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
51af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        SkScalar y = 20;
52af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        SkPaint paint;
53af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setAntiAlias(true);
54af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setLCDRenderText(true);
55af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setSubpixelText(true);
56af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setTextSize(17);
576acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com
58bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com        SkFontMgr* fm = fFM;
59af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
60af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
61af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        for (int i = 0; i < count; ++i) {
62af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            SkString fname;
63af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            fm->getFamilyName(i, &fname);
64af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            paint.setTypeface(NULL);
65af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            (void)drawString(canvas, fname, 20, y, paint);
666acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com
67af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            SkScalar x = 220;
68964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
69af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i));
70af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            for (int j = 0; j < set->count(); ++j) {
71af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                SkString sname;
72af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                SkFontStyle fs;
73af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                set->getStyle(j, &fs, &sname);
745111648ceff9c61065cc013760ead4b531a2ad43reed@google.com                sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.isItalic());
756acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com
76af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                SkSafeUnref(paint.setTypeface(set->createTypeface(j)));
77af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                x = drawString(canvas, sname, x, y, paint) + 20;
786acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com            }
79af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            y += 24;
80af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        }
81af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    }
82af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
836518daf8156c9d2a154676f7f3436cf70f7caa1dreed@google.com    virtual uint32_t onGetFlags() const SK_OVERRIDE {
846518daf8156c9d2a154676f7f3436cf70f7caa1dreed@google.com        // fontdescriptors (and therefore serialization) don't yet understand
856518daf8156c9d2a154676f7f3436cf70f7caa1dreed@google.com        // these new styles, so skip tests that exercise that for now.
867103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com
877103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com        // If certain fonts are picked up (e.g. Microsoft Jhenghei 20MB for Regular, 12MB for Bold),
887103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com        // the resulting pdf can be ~700MB and crashes Chrome's PDF viewer.
897103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com
907103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com        return kSkipPicture_Flag | kSkipPipe_Flag | kSkipPDF_Flag;
916518daf8156c9d2a154676f7f3436cf70f7caa1dreed@google.com    }
926518daf8156c9d2a154676f7f3436cf70f7caa1dreed@google.com
93af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comprivate:
94bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com    SkAutoTUnref<SkFontMgr> fFM;
95bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com    SkString fName;
96af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    typedef GM INHERITED;
97af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com};
98af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
99964988f0e93f4a559b7e41db53d70d0282527350reed@google.comclass FontMgrMatchGM : public skiagm::GM {
100964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    SkAutoTUnref<SkFontMgr> fFM;
101964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
102964988f0e93f4a559b7e41db53d70d0282527350reed@google.compublic:
103964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) {
104964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
105964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
106d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
107964988f0e93f4a559b7e41db53d70d0282527350reed@google.comprotected:
108964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    virtual SkString onShortName() {
109964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        return SkString("fontmgr_match");
110964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
111d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
112964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    virtual SkISize onISize() {
113964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        return SkISize::Make(640, 1024);
114964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
115964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
116964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    void iterateFamily(SkCanvas* canvas, const SkPaint& paint,
117964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                       SkFontStyleSet* fset) {
118964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkPaint p(paint);
119964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkScalar y = 0;
120964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
121964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        for (int j = 0; j < fset->count(); ++j) {
122964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            SkString sname;
123964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            SkFontStyle fs;
124964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            fset->getStyle(j, &fs, &sname);
125964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
126964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            sname.appendf(" [%d %d]", fs.weight(), fs.width());
127964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
128964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            SkSafeUnref(p.setTypeface(fset->createTypeface(j)));
129964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            (void)drawString(canvas, sname, 0, y, p);
130964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            y += 24;
131964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
132964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
133964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
134964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    void exploreFamily(SkCanvas* canvas, const SkPaint& paint,
135964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                       SkFontStyleSet* fset) {
136964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkPaint p(paint);
137964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkScalar y = 0;
138964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
139964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        for (int weight = 100; weight <= 900; weight += 200) {
140964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            for (int width = 1; width <= 9; width += 2) {
141964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
142964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                SkTypeface* face = fset->matchStyle(fs);
143964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                if (face) {
144964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    SkString str;
145964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    str.printf("request [%d %d]", fs.weight(), fs.width());
146964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    p.setTypeface(face)->unref();
147964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    (void)drawString(canvas, str, 0, y, p);
148964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    y += 24;
149964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                }
150964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            }
151964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
152964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
153d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
154964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
155964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkPaint paint;
156964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setAntiAlias(true);
157964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setLCDRenderText(true);
158964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setSubpixelText(true);
159964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setTextSize(17);
160964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
161964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        static const char* gNames[] = {
162964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            "Helvetica Neue", "Arial"
163964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        };
164964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
1659fc5c68823c7e39e4769a41713ce070a7780df29bungeman@google.com        SkAutoTUnref<SkFontStyleSet> fset;
166d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com        for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
1679fc5c68823c7e39e4769a41713ce070a7780df29bungeman@google.com            fset.reset(fFM->matchFamily(gNames[i]));
1689fc5c68823c7e39e4769a41713ce070a7780df29bungeman@google.com            if (fset->count() > 0) {
169964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                break;
170964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            }
171964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
1729fc5c68823c7e39e4769a41713ce070a7780df29bungeman@google.com        if (NULL == fset.get()) {
173964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            return;
174964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
175964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
176964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        canvas->translate(20, 40);
177964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        this->exploreFamily(canvas, paint, fset);
178964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        canvas->translate(150, 0);
179964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        this->iterateFamily(canvas, paint, fset);
180964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
181d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
182964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    virtual uint32_t onGetFlags() const SK_OVERRIDE {
183964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        // fontdescriptors (and therefore serialization) don't yet understand
184964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        // these new styles, so skip tests that exercise that for now.
185964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        return kSkipPicture_Flag | kSkipPipe_Flag;
186964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
187d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
188964988f0e93f4a559b7e41db53d70d0282527350reed@google.comprivate:
189964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    typedef GM INHERITED;
190964988f0e93f4a559b7e41db53d70d0282527350reed@google.com};
191964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
192af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com//////////////////////////////////////////////////////////////////////////////
193af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
194af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comDEF_GM( return SkNEW(FontMgrGM); )
195964988f0e93f4a559b7e41db53d70d0282527350reed@google.comDEF_GM( return SkNEW(FontMgrMatchGM); )
196bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com
197bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com#ifdef SK_BUILD_FOR_WIN
1986eddc77f6a0078570471277954c07d73b3a921d8bungeman@google.com    DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite())); )
199bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com#endif
200