1483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner/* 2483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner * Copyright 2014 Google Inc. 3483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner * 4483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner * Use of this source code is governed by a BSD-style license that can be 5483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner * found in the LICENSE file. 6483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner */ 7483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 8483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "Resources.h" 9483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "SkCommonFlags.h" 10483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "SkFontMgr.h" 11483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "SkFontStyle.h" 12483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "SkMutex.h" 13483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "SkOSFile.h" 14483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "SkTestScalerContext.h" 15483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "SkUtils.h" 16483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "sk_tool_utils.h" 17483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 18483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnernamespace sk_tool_utils { 19483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 20483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "test_font_monospace.inc" 21483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "test_font_sans_serif.inc" 22483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "test_font_serif.inc" 23483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#include "test_font_index.inc" 24483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 25483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnervoid release_portable_typefaces() { 26483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner for (int index = 0; index < gTestFontsCount; ++index) { 27483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner SkTestFontData& fontData = gTestFonts[index]; 28483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner fontData.fCachedFont.reset(); 29483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 30483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 31483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 32483c772cfdd646fad3ae8aa187136191ae3babdcBen WagnerSK_DECLARE_STATIC_MUTEX(gTestFontMutex); 33483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 34483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnersk_sp<SkTypeface> create_font(const char* name, SkFontStyle style) { 35483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner SkTestFontData* fontData = nullptr; 36483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner const SubFont* sub; 37483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (name) { 38483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner for (int index = 0; index < gSubFontsCount; ++index) { 39483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner sub = &gSubFonts[index]; 40483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (!strcmp(name, sub->fName) && sub->fStyle == style) { 41483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner fontData = &sub->fFont; 42483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner break; 43483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 44483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 45483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (!fontData) { 46483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner // Once all legacy callers to portable fonts are converted, replace this with 47483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner // SK_ABORT(); 48483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner SkDebugf("missing %s weight %d, width %d, slant %d\n", 49483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner name, style.weight(), style.width(), style.slant()); 50483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner // If we called SkTypeface::CreateFromName() here we'd recurse infinitely, 51483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner // so we reimplement its core logic here inline without the recursive aspect. 52483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 53483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return fm->legacyMakeTypeface(name, style); 54483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 55483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } else { 56483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner sub = &gSubFonts[gDefaultFontIndex]; 57483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner fontData = &sub->fFont; 58483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 59483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner sk_sp<SkTestFont> font; 60483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner { 61483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner SkAutoMutexAcquire ac(gTestFontMutex); 62483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (fontData->fCachedFont) { 63483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner font = fontData->fCachedFont; 64483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } else { 65483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner font = sk_make_sp<SkTestFont>(*fontData); 66483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner fontData->fCachedFont = font; 67483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 68483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 69483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return sk_make_sp<SkTestTypeface>(std::move(font), style); 70483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 71483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 72483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnersk_sp<SkTypeface> emoji_typeface() { 73483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#if defined(SK_BUILD_FOR_WIN) 74483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 75483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner const char *colorEmojiFontName = "Segoe UI Emoji"; 76483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner sk_sp<SkTypeface> typeface(fm->matchFamilyStyle(colorEmojiFontName, SkFontStyle())); 77483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (typeface) { 78483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return typeface; 79483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 80483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner sk_sp<SkTypeface> fallback(fm->matchFamilyStyleCharacter( 81483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner colorEmojiFontName, SkFontStyle(), nullptr /* bcp47 */, 0 /* bcp47Count */, 82483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 0x1f4b0 /* character: */)); 83483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (fallback) { 84483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return fallback; 85483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 86483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner // If we don't have Segoe UI Emoji and can't find a fallback, try Segoe UI Symbol. 87483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner // Windows 7 does not have Segoe UI Emoji; Segoe UI Symbol has the (non - color) emoji. 88483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return SkTypeface::MakeFromName("Segoe UI Symbol", SkFontStyle()); 89483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 90483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 91483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return SkTypeface::MakeFromName("Apple Color Emoji", SkFontStyle()); 92483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 93483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#else 94483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return MakeResourceAsTypeface("fonts/Funkster.ttf"); 95483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 96483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#endif 97483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 98483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 99483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnerconst char* emoji_sample_text() { 100483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 101483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return "\xF0\x9F\x92\xB0" "\xF0\x9F\x8F\xA1" "\xF0\x9F\x8E\x85" // 102483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner "\xF0\x9F\x8D\xAA" "\xF0\x9F\x8D\x95" "\xF0\x9F\x9A\x80" // 103483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner "\xF0\x9F\x9A\xBB" "\xF0\x9F\x92\xA9" "\xF0\x9F\x93\xB7" // 104483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner "\xF0\x9F\x93\xA6" // 105483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner "\xF0\x9F\x87\xBA" "\xF0\x9F\x87\xB8" "\xF0\x9F\x87\xA6"; // 106483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#else 107483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return "Hamburgefons"; 108483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner#endif 109483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 110483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 111483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnerstatic const char* platform_os_name() { 112483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner for (int index = 0; index < FLAGS_key.count(); index += 2) { 113483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (!strcmp("os", FLAGS_key[index])) { 114483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return FLAGS_key[index + 1]; 115483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 116483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 117483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return ""; 118483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 119483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 120483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnerstatic bool extra_config_contains(const char* substring) { 121483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner for (int index = 0; index < FLAGS_key.count(); index += 2) { 122483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (0 == strcmp("extra_config", FLAGS_key[index]) 123483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner && strstr(FLAGS_key[index + 1], substring)) { 124483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return true; 125483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 126483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 127483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return false; 128483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 129483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 130483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnerconst char* platform_font_manager() { 131483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (extra_config_contains("GDI")) { 132483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return "GDI"; 133483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 134483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner if (extra_config_contains("NativeFonts")){ 135483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return platform_os_name(); 136483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner } 137483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return ""; 138483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 139483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 140483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnersk_sp<SkTypeface> create_portable_typeface(const char* name, SkFontStyle style) { 141483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner return create_font(name, style); 142483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 143483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 144483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagnervoid set_portable_typeface(SkPaint* paint, const char* name, SkFontStyle style) { 145483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner paint->setTypeface(create_font(name, style)); 146483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 147483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner 148483c772cfdd646fad3ae8aa187136191ae3babdcBen Wagner} 149