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"
933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h"
10af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkCanvas.h"
11af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkFontMgr.h"
12af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkGraphics.h"
13af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#include "SkTypeface.h"
14af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
15af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com// limit this just so we don't take too long to draw
16af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com#define MAX_FAMILIES    30
17af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
18af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comstatic SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
19af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                           SkScalar y, const SkPaint& paint) {
202a475eae622adc1e8fa29206be1eaf862c23548eCary Clark    canvas->drawString(text, x, y, paint);
21af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    return x + paint.measureText(text.c_str(), text.size());
22af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com}
23af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
240d393a92ca6c1a328e4fa0c4b311916789659de5djsollenstatic SkScalar drawCharacter(SkCanvas* canvas, uint32_t character, SkScalar x,
250d393a92ca6c1a328e4fa0c4b311916789659de5djsollen                              SkScalar y, SkPaint& paint, SkFontMgr* fm,
26c9232dcda016feb2d30abb51483b3b1862775f84bungeman                              const char* fontName, const char* bcp47[], int bcp47Count,
270d393a92ca6c1a328e4fa0c4b311916789659de5djsollen                              const SkFontStyle& fontStyle) {
280d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    // find typeface containing the requested character and draw it
290d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    SkString ch;
300d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    ch.appendUnichar(character);
3113b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    sk_sp<SkTypeface> typeface(fm->matchFamilyStyleCharacter(fontName, fontStyle,
3213b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                                                             bcp47, bcp47Count, character));
3313b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    paint.setTypeface(typeface);
340d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    x = drawString(canvas, ch, x, y, paint) + 20;
350d393a92ca6c1a328e4fa0c4b311916789659de5djsollen
3696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == typeface) {
370d393a92ca6c1a328e4fa0c4b311916789659de5djsollen        return x;
380d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    }
390d393a92ca6c1a328e4fa0c4b311916789659de5djsollen
400d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    // repeat the process, but this time use the family name of the typeface
410d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    // from the first pass.  This emulates the behavior in Blink where it
420d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    // it expects to get the same glyph when following this pattern.
430d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    SkString familyName;
440d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    typeface->getFamilyName(&familyName);
45592273965a7fc7fc403252e420d15f6555b8f25dMike Reed    paint.setTypeface(fm->legacyMakeTypeface(familyName.c_str(), typeface->fontStyle()));
460d393a92ca6c1a328e4fa0c4b311916789659de5djsollen    return drawString(canvas, ch, x, y, paint) + 20;
470d393a92ca6c1a328e4fa0c4b311916789659de5djsollen}
480d393a92ca6c1a328e4fa0c4b311916789659de5djsollen
49c9232dcda016feb2d30abb51483b3b1862775f84bungemanstatic const char* zh = "zh";
50c9232dcda016feb2d30abb51483b3b1862775f84bungemanstatic const char* ja = "ja";
51c9232dcda016feb2d30abb51483b3b1862775f84bungeman
52af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comclass FontMgrGM : public skiagm::GM {
53af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.compublic:
548073e79e5b8c7dab129112e4494b907b175b7217Mike Klein    FontMgrGM() {
553546ff10c2e1e91f5afe1efaab4e5e14f71689d1Ben Wagner        SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
563546ff10c2e1e91f5afe1efaab4e5e14f71689d1Ben Wagner
573546ff10c2e1e91f5afe1efaab4e5e14f71689d1Ben Wagner        fName.set("fontmgr_iter");
588073e79e5b8c7dab129112e4494b907b175b7217Mike Klein        fFM = SkFontMgr::RefDefault();
59b251b72d3d91fb7976f7984ae60793c87d0dae4cMike Klein        fName.append(sk_tool_utils::platform_font_manager());
603546ff10c2e1e91f5afe1efaab4e5e14f71689d1Ben Wagner    }
61af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
62af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comprotected:
6336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
64bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com        return fName;
65af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    }
66af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
6736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override {
680d393a92ca6c1a328e4fa0c4b311916789659de5djsollen        return SkISize::Make(1536, 768);
69af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    }
70af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
7136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
72af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        SkScalar y = 20;
73af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        SkPaint paint;
74af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setAntiAlias(true);
75af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setLCDRenderText(true);
76af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setSubpixelText(true);
77af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        paint.setTextSize(17);
786acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com
79cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary        SkFontMgr* fm = fFM.get();
80af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
81af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
82af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        for (int i = 0; i < count; ++i) {
83c64239a466b6e083ada93c2842d9e48bae606dfebungeman            SkString familyName;
84c64239a466b6e083ada93c2842d9e48bae606dfebungeman            fm->getFamilyName(i, &familyName);
8596fcdcc219d2a0d3579719b84b28bede76efba64halcanary            paint.setTypeface(nullptr);
86c64239a466b6e083ada93c2842d9e48bae606dfebungeman            (void)drawString(canvas, familyName, 20, y, paint);
876acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com
88af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            SkScalar x = 220;
89964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
90cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary            sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
91af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            for (int j = 0; j < set->count(); ++j) {
92af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                SkString sname;
93af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                SkFontStyle fs;
94af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                set->getStyle(j, &fs, &sname);
95b4bb7d825566042ed64697be49457dbac060e6c4bungeman                sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.slant());
966acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com
9713b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                paint.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
98af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com                x = drawString(canvas, sname, x, y, paint) + 20;
990d393a92ca6c1a328e4fa0c4b311916789659de5djsollen
1000d393a92ca6c1a328e4fa0c4b311916789659de5djsollen                // check to see that we get different glyphs in japanese and chinese
101c64239a466b6e083ada93c2842d9e48bae606dfebungeman                x = drawCharacter(canvas, 0x5203, x, y, paint, fm, familyName.c_str(), &zh, 1, fs);
102c64239a466b6e083ada93c2842d9e48bae606dfebungeman                x = drawCharacter(canvas, 0x5203, x, y, paint, fm, familyName.c_str(), &ja, 1, fs);
1030d393a92ca6c1a328e4fa0c4b311916789659de5djsollen                // check that emoji characters are found
10496fcdcc219d2a0d3579719b84b28bede76efba64halcanary                x = drawCharacter(canvas, 0x1f601, x, y, paint, fm, familyName.c_str(), nullptr,0, fs);
1056acd09e2b07ef547dbc0c3a69425a4dcda0cca51skia.committer@gmail.com            }
106af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com            y += 24;
107af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com        }
108af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    }
109af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
110af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.comprivate:
111cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary    sk_sp<SkFontMgr> fFM;
112bfc6cc4b6c41e99d3887d268fbf798aa3abc9a27bungeman@google.com    SkString fName;
113af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com    typedef GM INHERITED;
114af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com};
115af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
116964988f0e93f4a559b7e41db53d70d0282527350reed@google.comclass FontMgrMatchGM : public skiagm::GM {
117cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary    sk_sp<SkFontMgr> fFM;
118964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
119964988f0e93f4a559b7e41db53d70d0282527350reed@google.compublic:
120964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) {
121964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
122964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
123d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
124964988f0e93f4a559b7e41db53d70d0282527350reed@google.comprotected:
12536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
1266531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark        SkString name("fontmgr_match");
127b251b72d3d91fb7976f7984ae60793c87d0dae4cMike Klein        name.append(sk_tool_utils::platform_font_manager());
1286531c3619f08cc83aad34883c5f00f6a358c9fadcaryclark        return name;
129964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
130d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
13136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override {
132964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        return SkISize::Make(640, 1024);
133964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
134964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
135964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    void iterateFamily(SkCanvas* canvas, const SkPaint& paint,
136964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                       SkFontStyleSet* fset) {
137964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkPaint p(paint);
138964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkScalar y = 0;
139964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
140964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        for (int j = 0; j < fset->count(); ++j) {
141964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            SkString sname;
142964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            SkFontStyle fs;
143964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            fset->getStyle(j, &fs, &sname);
144964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
145964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            sname.appendf(" [%d %d]", fs.weight(), fs.width());
146964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
14713b9c95295f4c5732e34574789e721a6bc08f7b4bungeman            p.setTypeface(sk_sp<SkTypeface>(fset->createTypeface(j)));
148964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            (void)drawString(canvas, sname, 0, y, p);
149964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            y += 24;
150964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
151964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
152964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
153964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    void exploreFamily(SkCanvas* canvas, const SkPaint& paint,
154964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                       SkFontStyleSet* fset) {
155964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkPaint p(paint);
156964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkScalar y = 0;
157964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
158964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        for (int weight = 100; weight <= 900; weight += 200) {
159964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            for (int width = 1; width <= 9; width += 2) {
160964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
16113b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                sk_sp<SkTypeface> face(fset->matchStyle(fs));
162964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                if (face) {
163964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    SkString str;
164964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    str.printf("request [%d %d]", fs.weight(), fs.width());
16513b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                    p.setTypeface(std::move(face));
166964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    (void)drawString(canvas, str, 0, y, p);
167964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                    y += 24;
168964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                }
169964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            }
170964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
171964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
172d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
17336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
174964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        SkPaint paint;
175964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setAntiAlias(true);
176964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setLCDRenderText(true);
177964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setSubpixelText(true);
178964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        paint.setTextSize(17);
179964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
180dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein        const char* gNames[] = {
181964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            "Helvetica Neue", "Arial"
182964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        };
183964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
184cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary        sk_sp<SkFontStyleSet> fset;
185d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com        for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
1869fc5c68823c7e39e4769a41713ce070a7780df29bungeman@google.com            fset.reset(fFM->matchFamily(gNames[i]));
1879fc5c68823c7e39e4769a41713ce070a7780df29bungeman@google.com            if (fset->count() > 0) {
188964988f0e93f4a559b7e41db53d70d0282527350reed@google.com                break;
189964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            }
190964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
19196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == fset.get()) {
192964988f0e93f4a559b7e41db53d70d0282527350reed@google.com            return;
193964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        }
194964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
195964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        canvas->translate(20, 40);
196cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary        this->exploreFamily(canvas, paint, fset.get());
197964988f0e93f4a559b7e41db53d70d0282527350reed@google.com        canvas->translate(150, 0);
198cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary        this->iterateFamily(canvas, paint, fset.get());
199964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    }
200d55846d100bb09448b398b41798bd4ab100a753askia.committer@gmail.com
201964988f0e93f4a559b7e41db53d70d0282527350reed@google.comprivate:
202964988f0e93f4a559b7e41db53d70d0282527350reed@google.com    typedef GM INHERITED;
203964988f0e93f4a559b7e41db53d70d0282527350reed@google.com};
204964988f0e93f4a559b7e41db53d70d0282527350reed@google.com
205a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breedclass FontMgrBoundsGM : public skiagm::GM {
206a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breedpublic:
2078893e5f030cb2f6c3bdf698c1767a244ae098a5creed    FontMgrBoundsGM(double scale, double skew)
2088893e5f030cb2f6c3bdf698c1767a244ae098a5creed        : fScaleX(SkDoubleToScalar(scale))
2098893e5f030cb2f6c3bdf698c1767a244ae098a5creed        , fSkewX(SkDoubleToScalar(skew))
2108893e5f030cb2f6c3bdf698c1767a244ae098a5creed    {
211a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        fName.set("fontmgr_bounds");
2128893e5f030cb2f6c3bdf698c1767a244ae098a5creed        if (scale != 1 || skew != 0) {
2138893e5f030cb2f6c3bdf698c1767a244ae098a5creed            fName.appendf("_%g_%g", scale, skew);
2148893e5f030cb2f6c3bdf698c1767a244ae098a5creed        }
215b251b72d3d91fb7976f7984ae60793c87d0dae4cMike Klein        fName.append(sk_tool_utils::platform_font_manager());
2163546ff10c2e1e91f5afe1efaab4e5e14f71689d1Ben Wagner        fFM = SkFontMgr::RefDefault();
217a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    }
218a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
219a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    static void show_bounds(SkCanvas* canvas, const SkPaint& paint, SkScalar x, SkScalar y,
220219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                            SkColor boundsColor)
221219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner    {
222219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        SkPaint glyphPaint(paint);
223219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        SkRect fontBounds = glyphPaint.getFontBounds();
224219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        fontBounds.offset(x, y);
225219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        SkPaint boundsPaint(glyphPaint);
226219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        boundsPaint.setColor(boundsColor);
227219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        canvas->drawRect(fontBounds, boundsPaint);
228219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner
229219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        SkPaint::FontMetrics fm;
230219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        glyphPaint.getFontMetrics(&fm);
231219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        SkPaint metricsPaint(boundsPaint);
232219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        metricsPaint.setStyle(SkPaint::kFill_Style);
233219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        metricsPaint.setAlpha(0x40);
234219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        if ((fm.fFlags & SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag) &&
235219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            (fm.fFlags & SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag))
236219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        {
237219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            SkRect underline{ fontBounds.fLeft,  fm.fUnderlinePosition+y,
238219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                              fontBounds.fRight, fm.fUnderlinePosition+y + fm.fUnderlineThickness };
239219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            canvas->drawRect(underline, metricsPaint);
240219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        }
241a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
242219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        if ((fm.fFlags & SkPaint::FontMetrics::kStrikeoutPositionIsValid_Flag) &&
243219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            (fm.fFlags & SkPaint::FontMetrics::kStrikeoutPositionIsValid_Flag))
244219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        {
245219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            SkRect strikeout{ fontBounds.fLeft,  fm.fStrikeoutPosition+y - fm.fStrikeoutThickness,
246219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                              fontBounds.fRight, fm.fStrikeoutPosition+y };
247219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            canvas->drawRect(strikeout, metricsPaint);
248a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        }
249aa458fb20a4350da581f8ceec69ea16eec295cedtfarina
250219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        SkGlyphID left = 0, right = 0, top = 0, bottom = 0;
251219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        {
252219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            int numGlyphs = glyphPaint.getTypeface()->countGlyphs();
253219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            SkRect min = {0, 0, 0, 0};
254219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
255219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            for (int i = 0; i < numGlyphs; ++i) {
256219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                SkGlyphID glyphId = i;
257219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                SkRect cur;
258219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                glyphPaint.measureText(&glyphId, sizeof(glyphId), &cur);
259219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                if (cur.fLeft   < min.fLeft  ) { min.fLeft   = cur.fLeft;   left   = i; }
260219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                if (cur.fTop    < min.fTop   ) { min.fTop    = cur.fTop ;   top    = i; }
261219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                if (min.fRight  < cur.fRight ) { min.fRight  = cur.fRight;  right  = i; }
262219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                if (min.fBottom < cur.fBottom) { min.fBottom = cur.fBottom; bottom = i; }
263219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            }
264219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        }
265219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        SkGlyphID str[] = { left, right, top, bottom };
266219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        for (size_t i = 0; i < SK_ARRAY_COUNT(str); ++i) {
267219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            canvas->drawText(&str[i], sizeof(str[0]), x, y, glyphPaint);
268219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        }
269a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    }
270a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
271a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breedprotected:
27236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
273a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        return fName;
274a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    }
275aa458fb20a4350da581f8ceec69ea16eec295cedtfarina
27636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override {
277a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        return SkISize::Make(1024, 850);
278a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    }
279aa458fb20a4350da581f8ceec69ea16eec295cedtfarina
28036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
281a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        SkPaint paint;
282a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        paint.setAntiAlias(true);
283a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        paint.setSubpixelText(true);
284a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        paint.setTextSize(100);
285a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        paint.setStyle(SkPaint::kStroke_Style);
2868893e5f030cb2f6c3bdf698c1767a244ae098a5creed        paint.setTextScaleX(fScaleX);
2878893e5f030cb2f6c3bdf698c1767a244ae098a5creed        paint.setTextSkewX(fSkewX);
288a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
289a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        const SkColor boundsColors[2] = { SK_ColorRED, SK_ColorBLUE };
2909d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
291cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary        SkFontMgr* fm = fFM.get();
292a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        int count = SkMin32(fm->countFamilies(), 32);
293a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
294a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        int index = 0;
295a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        SkScalar x = 0, y = 0;
296a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
297219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner        canvas->translate(10, 120);
298a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
299a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        for (int i = 0; i < count; ++i) {
300cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary            sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
301219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner            for (int j = 0; j < set->count() && j < 3; ++j) {
30213b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                paint.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
3032112df028caf651bed28ee3203625b9a57d48333Ben Wagner                // Fonts with lots of glyphs are interesting, but can take a long time to find
3042112df028caf651bed28ee3203625b9a57d48333Ben Wagner                // the glyphs which make up the maximum extent.
3052112df028caf651bed28ee3203625b9a57d48333Ben Wagner                if (paint.getTypeface() && paint.getTypeface()->countGlyphs() < 1000) {
306219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                    SkRect fontBounds = paint.getFontBounds();
307219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                    x -= fontBounds.fLeft;
308a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                    show_bounds(canvas, paint, x, y, boundsColors[index & 1]);
309219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                    x += fontBounds.fRight + 20;
310a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                    index += 1;
311219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                    if (x > 900) {
312a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                        x = 0;
313a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                        y += 160;
314a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                    }
315219f3622ba32a1cb6380212a2ec1947513fbfeb9Ben Wagner                    if (y >= 700) {
316a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                        return;
317a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                    }
318a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed                }
319a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed            }
320a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        }
321a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    }
3221c4029296f518a84ef90095243ba210163a1e1f9mtklein
323a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breedprivate:
324cefc43112c8f6fe3702facb89447bdfcc2715345Hal Canary    sk_sp<SkFontMgr> fFM;
325a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    SkString fName;
3268893e5f030cb2f6c3bdf698c1767a244ae098a5creed    SkScalar fScaleX, fSkewX;
327a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    typedef GM INHERITED;
328a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed};
329a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
330af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com//////////////////////////////////////////////////////////////////////////////
331af0fa6a298365fd0e836a4b20f82bd047e50951freed@google.com
332385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new FontMgrGM;)
333385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new FontMgrMatchGM;)
334385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new FontMgrBoundsGM(1.0, 0);)
335385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new FontMgrBoundsGM(0.75, 0);)
336385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new FontMgrBoundsGM(1.0, -0.25);)
337