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