1/* 2 * Copyright 2014 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 "Resources.h" 9#include "SkCommonFlags.h" 10#include "SkFontMgr.h" 11#include "SkFontStyle.h" 12#include "SkMutex.h" 13#include "SkOSFile.h" 14#include "SkTestScalerContext.h" 15#include "SkUtils.h" 16#include "sk_tool_utils.h" 17 18namespace sk_tool_utils { 19 20#include "test_font_monospace.inc" 21#include "test_font_sans_serif.inc" 22#include "test_font_serif.inc" 23#include "test_font_index.inc" 24 25void release_portable_typefaces() { 26 for (int index = 0; index < gTestFontsCount; ++index) { 27 SkTestFontData& fontData = gTestFonts[index]; 28 fontData.fCachedFont.reset(); 29 } 30} 31 32SK_DECLARE_STATIC_MUTEX(gTestFontMutex); 33 34sk_sp<SkTypeface> create_font(const char* name, SkFontStyle style) { 35 SkTestFontData* fontData = nullptr; 36 const SubFont* sub; 37 if (name) { 38 for (int index = 0; index < gSubFontsCount; ++index) { 39 sub = &gSubFonts[index]; 40 if (!strcmp(name, sub->fName) && sub->fStyle == style) { 41 fontData = &sub->fFont; 42 break; 43 } 44 } 45 if (!fontData) { 46 // Once all legacy callers to portable fonts are converted, replace this with 47 // SK_ABORT(); 48 SkDebugf("missing %s weight %d, width %d, slant %d\n", 49 name, style.weight(), style.width(), style.slant()); 50 // If we called SkTypeface::CreateFromName() here we'd recurse infinitely, 51 // so we reimplement its core logic here inline without the recursive aspect. 52 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 53 return fm->legacyMakeTypeface(name, style); 54 } 55 } else { 56 sub = &gSubFonts[gDefaultFontIndex]; 57 fontData = &sub->fFont; 58 } 59 sk_sp<SkTestFont> font; 60 { 61 SkAutoMutexAcquire ac(gTestFontMutex); 62 if (fontData->fCachedFont) { 63 font = fontData->fCachedFont; 64 } else { 65 font = sk_make_sp<SkTestFont>(*fontData); 66 fontData->fCachedFont = font; 67 } 68 } 69 return sk_make_sp<SkTestTypeface>(std::move(font), style); 70} 71 72sk_sp<SkTypeface> emoji_typeface() { 73#if defined(SK_BUILD_FOR_WIN) 74 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 75 const char *colorEmojiFontName = "Segoe UI Emoji"; 76 sk_sp<SkTypeface> typeface(fm->matchFamilyStyle(colorEmojiFontName, SkFontStyle())); 77 if (typeface) { 78 return typeface; 79 } 80 sk_sp<SkTypeface> fallback(fm->matchFamilyStyleCharacter( 81 colorEmojiFontName, SkFontStyle(), nullptr /* bcp47 */, 0 /* bcp47Count */, 82 0x1f4b0 /* character: */)); 83 if (fallback) { 84 return fallback; 85 } 86 // If we don't have Segoe UI Emoji and can't find a fallback, try Segoe UI Symbol. 87 // Windows 7 does not have Segoe UI Emoji; Segoe UI Symbol has the (non - color) emoji. 88 return SkTypeface::MakeFromName("Segoe UI Symbol", SkFontStyle()); 89 90#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 91 return SkTypeface::MakeFromName("Apple Color Emoji", SkFontStyle()); 92 93#else 94 return MakeResourceAsTypeface("fonts/Funkster.ttf"); 95 96#endif 97} 98 99const char* emoji_sample_text() { 100#if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 101 return "\xF0\x9F\x92\xB0" "\xF0\x9F\x8F\xA1" "\xF0\x9F\x8E\x85" // 102 "\xF0\x9F\x8D\xAA" "\xF0\x9F\x8D\x95" "\xF0\x9F\x9A\x80" // 103 "\xF0\x9F\x9A\xBB" "\xF0\x9F\x92\xA9" "\xF0\x9F\x93\xB7" // 104 "\xF0\x9F\x93\xA6" // 105 "\xF0\x9F\x87\xBA" "\xF0\x9F\x87\xB8" "\xF0\x9F\x87\xA6"; // 106#else 107 return "Hamburgefons"; 108#endif 109} 110 111static const char* platform_os_name() { 112 for (int index = 0; index < FLAGS_key.count(); index += 2) { 113 if (!strcmp("os", FLAGS_key[index])) { 114 return FLAGS_key[index + 1]; 115 } 116 } 117 return ""; 118} 119 120static bool extra_config_contains(const char* substring) { 121 for (int index = 0; index < FLAGS_key.count(); index += 2) { 122 if (0 == strcmp("extra_config", FLAGS_key[index]) 123 && strstr(FLAGS_key[index + 1], substring)) { 124 return true; 125 } 126 } 127 return false; 128} 129 130const char* platform_font_manager() { 131 if (extra_config_contains("GDI")) { 132 return "GDI"; 133 } 134 if (extra_config_contains("NativeFonts")){ 135 return platform_os_name(); 136 } 137 return ""; 138} 139 140sk_sp<SkTypeface> create_portable_typeface(const char* name, SkFontStyle style) { 141 return create_font(name, style); 142} 143 144void set_portable_typeface(SkPaint* paint, const char* name, SkFontStyle style) { 145 paint->setTypeface(create_font(name, style)); 146} 147 148} 149