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