1096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger/*
2096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Copyright 2009 Google Inc.
3096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger *
4096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
5096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * found in the LICENSE file.
6096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */
7096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
8096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger/* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */
9096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
10096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <string>
11096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <unistd.h>
12096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <fcntl.h>
13096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
14096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <fontconfig/fontconfig.h>
15096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkBuffer.h"
17096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkFontConfigInterface.h"
18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkStream.h"
19096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergersize_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const {
217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    size_t size = sizeof(fID) + sizeof(fTTCIndex);
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    size += sizeof(int32_t) + sizeof(int32_t) + sizeof(uint8_t); // weight, width, italic
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    size += sizeof(int32_t) + fString.size();    // store length+data
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (addr) {
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkWBuffer buffer(addr, size);
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.write32(fID);
287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.write32(fTTCIndex);
297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.write32(fString.size());
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.write32(fStyle.weight());
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.write32(fStyle.width());
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.write8(fStyle.slant());
337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.write(fString.c_str(), fString.size());
347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        buffer.padToAlign4();
357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkASSERT(buffer.pos() == size);
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return size;
397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergersize_t SkFontConfigInterface::FontIdentity::readFromMemory(const void* addr,
427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                           size_t size) {
437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkRBuffer buffer(addr, size);
447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fID = buffer.readU32();
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fTTCIndex = buffer.readU32();
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    size_t strLen = buffer.readU32();
487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int weight = buffer.readU32();
497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int width = buffer.readU32();
507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkFontStyle::Slant slant = (SkFontStyle::Slant)buffer.readU8();
517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fStyle = SkFontStyle(weight, width, slant);
527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fString.resize(strLen);
537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.read(fString.writable_str(), strLen);
547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.skipToAlign4();
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return buffer.pos();    // the actual number of bytes read
577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifdef SK_DEBUG
607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void make_iden(SkFontConfigInterface::FontIdentity* iden) {
617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    iden->fID = 10;
627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    iden->fTTCIndex = 2;
637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    iden->fString.set("Hello world");
647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    iden->fStyle = SkFontStyle(300, 6, SkFontStyle::kItalic_Slant);
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void test_writeToMemory(const SkFontConfigInterface::FontIdentity& iden0,
687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               int initValue) {
697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkFontConfigInterface::FontIdentity iden1;
707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    size_t size0 = iden0.writeToMemory(NULL);
727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkAutoMalloc storage(size0);
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    memset(storage.get(), initValue, size0);
757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    size_t size1 = iden0.writeToMemory(storage.get());
777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(size0 == size1);
787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(iden0 != iden1);
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    size_t size2 = iden1.readFromMemory(storage.get(), size1);
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(size2 == size1);
827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(iden0 == iden1);
837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void fontconfiginterface_unittest() {
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkFontConfigInterface::FontIdentity iden0, iden1;
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(iden0 == iden1);
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    make_iden(&iden0);
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(iden0 != iden1);
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    make_iden(&iden1);
947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(iden0 == iden1);
957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    test_writeToMemory(iden0, 0);
977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    test_writeToMemory(iden0, 0);
987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
101096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerclass SkFontConfigInterfaceDirect : public SkFontConfigInterface {
102096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerpublic:
103096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            SkFontConfigInterfaceDirect();
104096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    virtual ~SkFontConfigInterfaceDirect();
105096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
106096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    virtual bool matchFamilyName(const char familyName[],
107096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                 SkTypeface::Style requested,
108096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                 FontIdentity* outFontIdentifier,
109096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                 SkString* outFamilyName,
110096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                 SkTypeface::Style* outStyle) SK_OVERRIDE;
111096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    virtual SkStream* openStream(const FontIdentity&) SK_OVERRIDE;
112096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // new APIs
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual SkDataTable* getFamilyNames() SK_OVERRIDE;
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual bool matchFamilySet(const char inFamilyName[],
1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                SkString* outFamilyName,
1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                SkTArray<FontIdentity>*) SK_OVERRIDE;
1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
119096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerprivate:
120096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkMutex mutex_;
121096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger};
122096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
123096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface() {
124096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    static SkFontConfigInterface* gDirect;
125096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (NULL == gDirect) {
1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static SkMutex gMutex;
1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkAutoMutexAcquire ac(gMutex);
1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (NULL == gDirect) {
1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            gDirect = new SkFontConfigInterfaceDirect;
1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
132096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
133096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    return gDirect;
134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
135096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// Returns the string from the pattern, or NULL
1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const char* get_name(FcPattern* pattern, const char field[],
1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                            int index = 0) {
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* name;
1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (FcPatternGetString(pattern, field, index,
1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                           (FcChar8**)&name) != FcResultMatch) {
1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        name = NULL;
1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return name;
1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
151096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergernamespace {
152096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
153096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// Equivalence classes, used to match the Liberation and other fonts
154096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// with their metric-compatible replacements.  See the discussion in
155096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// GetFontEquivClass().
156096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerenum FontEquivClass
157096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger{
158096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    OTHER,
159096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SANS,
160096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SERIF,
161096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    MONO,
162096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SYMBOL,
163096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    PGOTHIC,
164096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GOTHIC,
165096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    PMINCHO,
166096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    MINCHO,
167096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SIMSUN,
168096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    NSIMSUN,
169096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SIMHEI,
170096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    PMINGLIU,
171096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    MINGLIU,
172096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    PMINGLIUHK,
173096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    MINGLIUHK,
174096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    CAMBRIA,
175096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger};
176096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
177096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// Match the font name against a whilelist of fonts, returning the equivalence
178096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// class.
179096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerFontEquivClass GetFontEquivClass(const char* fontname)
180096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger{
181096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // It would be nice for fontconfig to tell us whether a given suggested
182096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // replacement is a "strong" match (that is, an equivalent font) or
183096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // a "weak" match (that is, fontconfig's next-best attempt at finding a
184096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // substitute).  However, I played around with the fontconfig API for
185096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // a good few hours and could not make it reveal this information.
186096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //
187096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // So instead, we hardcode.  Initially this function emulated
188096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //   /etc/fonts/conf.d/30-metric-aliases.conf
189096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // from my Ubuntu system, but we're better off being very conservative.
190096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
191096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // Arimo, Tinos and Cousine are a set of fonts metric-compatible with
192096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // Arial, Times New Roman and Courier New  with a character repertoire
193096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // much larger than Liberation. Note that Cousine is metrically
194096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // compatible with Courier New, but the former is sans-serif while
195096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // the latter is serif.
196096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
197096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
198096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    struct FontEquivMap {
199096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FontEquivClass clazz;
200096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        const char name[40];
201096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    };
202096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
203096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    static const FontEquivMap kFontEquivMap[] = {
204096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SANS, "Arial" },
205096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SANS, "Arimo" },
206096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SANS, "Liberation Sans" },
207096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
208096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SERIF, "Times New Roman" },
209096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SERIF, "Tinos" },
210096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SERIF, "Liberation Serif" },
211096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
212096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MONO, "Courier New" },
213096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MONO, "Cousine" },
214096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MONO, "Liberation Mono" },
215096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
216096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SYMBOL, "Symbol" },
217096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SYMBOL, "Symbol Neu" },
218096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
219096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // MS Pゴシック
220096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PGOTHIC, "MS PGothic" },
221096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PGOTHIC, "\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0"
222096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                   "\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf" },
223096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PGOTHIC, "IPAPGothic" },
224096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PGOTHIC, "MotoyaG04Gothic" },
225096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
226096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // MS ゴシック
227096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { GOTHIC, "MS Gothic" },
228096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { GOTHIC, "\xef\xbc\xad\xef\xbc\xb3 "
229096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                  "\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf" },
230096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { GOTHIC, "IPAGothic" },
231096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { GOTHIC, "MotoyaG04GothicMono" },
232096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
233096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // MS P明朝
234096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINCHO, "MS PMincho" },
235096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINCHO, "\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0"
236096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                   "\xe6\x98\x8e\xe6\x9c\x9d"},
237096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINCHO, "IPAPMincho" },
238096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINCHO, "MotoyaG04Mincho" },
239096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
240096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // MS 明朝
241096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINCHO, "MS Mincho" },
242096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINCHO, "\xef\xbc\xad\xef\xbc\xb3 \xe6\x98\x8e\xe6\x9c\x9d" },
243096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINCHO, "IPAMincho" },
244096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINCHO, "MotoyaG04MinchoMono" },
245096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
246096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // 宋体
247096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMSUN, "Simsun" },
248096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMSUN, "\xe5\xae\x8b\xe4\xbd\x93" },
249096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMSUN, "MSung GB18030" },
250096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMSUN, "Song ASC" },
251096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
252096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // 新宋体
253096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { NSIMSUN, "NSimsun" },
254096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { NSIMSUN, "\xe6\x96\xb0\xe5\xae\x8b\xe4\xbd\x93" },
255096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { NSIMSUN, "MSung GB18030" },
256096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { NSIMSUN, "N Song ASC" },
257096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
258096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // 黑体
259096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMHEI, "Simhei" },
260096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMHEI, "\xe9\xbb\x91\xe4\xbd\x93" },
261096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMHEI, "MYingHeiGB18030" },
262096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { SIMHEI, "MYingHeiB5HK" },
263096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
264096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // 新細明體
265096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINGLIU, "PMingLiU"},
266096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINGLIU, "\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94" },
267096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINGLIU, "MSung B5HK"},
268096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
269096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // 細明體
270096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINGLIU, "MingLiU"},
271096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINGLIU, "\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94" },
272096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINGLIU, "MSung B5HK"},
273096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
274096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // 新細明體
275096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINGLIUHK, "PMingLiU_HKSCS"},
276096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINGLIUHK, "\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94_HKSCS" },
277096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { PMINGLIUHK, "MSung B5HK"},
278096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
279096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // 細明體
280096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINGLIUHK, "MingLiU_HKSCS"},
281096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINGLIUHK, "\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94_HKSCS" },
282096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { MINGLIUHK, "MSung B5HK"},
283096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
284096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // Cambria
285096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { CAMBRIA, "Cambria" },
286096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        { CAMBRIA, "Caladea" },
287096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    };
288096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
289096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    static const size_t kFontCount =
290096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        sizeof(kFontEquivMap)/sizeof(kFontEquivMap[0]);
291096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
292096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // TODO(jungshik): If this loop turns out to be hot, turn
293096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // the array to a static (hash)map to speed it up.
294096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    for (size_t i = 0; i < kFontCount; ++i) {
295096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (strcasecmp(kFontEquivMap[i].name, fontname) == 0)
296096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            return kFontEquivMap[i].clazz;
297096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
298096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    return OTHER;
299096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
300096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
301096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
302096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// Return true if |font_a| and |font_b| are visually and at the metrics
303096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// level interchangeable.
304096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool IsMetricCompatibleReplacement(const char* font_a, const char* font_b)
305096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger{
306096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FontEquivClass class_a = GetFontEquivClass(font_a);
307096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FontEquivClass class_b = GetFontEquivClass(font_b);
308096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
309096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    return class_a != OTHER && class_a == class_b;
310096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
311096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
312096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// Normally we only return exactly the font asked for. In last-resort
313096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// cases, the request either doesn't specify a font or is one of the
314096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// basic font names like "Sans", "Serif" or "Monospace". This function
315096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// tells you whether a given request is for such a fallback.
316096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool IsFallbackFontAllowed(const std::string& family) {
317096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  const char* family_cstr = family.c_str();
318096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  return family.empty() ||
319096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger         strcasecmp(family_cstr, "sans") == 0 ||
320096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger         strcasecmp(family_cstr, "serif") == 0 ||
321096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger         strcasecmp(family_cstr, "monospace") == 0;
322096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
323096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
3247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic bool valid_pattern(FcPattern* pattern) {
3257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcBool is_scalable;
3267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch
3277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        || !is_scalable) {
3287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
3297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // fontconfig can also return fonts which are unreadable
3327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* c_filename = get_name(pattern, FC_FILE);
3337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!c_filename) {
3347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
3357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (access(c_filename, R_OK) != 0) {
3377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
3387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return true;
3407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
342096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// Find matching font from |font_set| for the given font family.
343096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerFcPattern* MatchFont(FcFontSet* font_set,
3447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     const char* post_config_family,
345096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                     const std::string& family) {
346096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  // Older versions of fontconfig have a bug where they cannot select
347096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  // only scalable fonts so we have to manually filter the results.
348096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  FcPattern* match = NULL;
349096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  for (int i = 0; i < font_set->nfont; ++i) {
350096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcPattern* current = font_set->fonts[i];
3517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (valid_pattern(current)) {
3527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      match = current;
3537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      break;
354096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
355096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  }
356096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
357096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  if (match && !IsFallbackFontAllowed(family)) {
358096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    bool acceptable_substitute = false;
359096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    for (int id = 0; id < 255; ++id) {
3607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      const char* post_match_family = get_name(match, FC_FAMILY, id);
3617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      if (!post_match_family)
362096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        break;
363096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger      acceptable_substitute =
3647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger          (strcasecmp(post_config_family, post_match_family) == 0 ||
365096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger           // Workaround for Issue 12530:
366096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger           //   requested family: "Bitstream Vera Sans"
367096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger           //   post_config_family: "Arial"
368096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger           //   post_match_family: "Bitstream Vera Sans"
369096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger           // -> We should treat this case as a good match.
3707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger           strcasecmp(family.c_str(), post_match_family) == 0) ||
3717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger           IsMetricCompatibleReplacement(family.c_str(), post_match_family);
372096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger      if (acceptable_substitute)
373096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        break;
374096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
375096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (!acceptable_substitute)
376096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger      return NULL;
377096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  }
378096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
379096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  return match;
380096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
381096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
382096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|.
383096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkTypeface::Style GetFontStyle(FcPattern* font) {
384096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    int resulting_bold;
385096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold))
386096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        resulting_bold = FC_WEIGHT_NORMAL;
387096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
388096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    int resulting_italic;
389096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (FcPatternGetInteger(font, FC_SLANT, 0, &resulting_italic))
390096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        resulting_italic = FC_SLANT_ROMAN;
391096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
392096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // If we ask for an italic font, fontconfig might take a roman font and set
393096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // the undocumented property FC_MATRIX to a skew matrix. It'll then say
394096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // that the font is italic or oblique. So, if we see a matrix, we don't
395096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // believe that it's italic.
396096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcValue matrix;
397096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const bool have_matrix = FcPatternGet(font, FC_MATRIX, 0, &matrix) == 0;
398096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
399096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // If we ask for an italic font, fontconfig might take a roman font and set
400096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // FC_EMBOLDEN.
401096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcValue embolden;
402096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const bool have_embolden = FcPatternGet(font, FC_EMBOLDEN, 0, &embolden) == 0;
403096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
404096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    int styleBits = 0;
405096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (resulting_bold > FC_WEIGHT_MEDIUM && !have_embolden) {
406096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        styleBits |= SkTypeface::kBold;
407096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
408096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (resulting_italic > FC_SLANT_ROMAN && !have_matrix) {
409096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        styleBits |= SkTypeface::kItalic;
410096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
411096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
412096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    return (SkTypeface::Style)styleBits;
413096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
414096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
415096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}  // anonymous namespace
416096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
417096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
418096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
419096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#define kMaxFontFamilyLength    2048
420096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
421096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() {
4227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkAutoMutexAcquire ac(mutex_);
4237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
424096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcInit();
4257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkDEBUGCODE(fontconfiginterface_unittest();)
427096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
428096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
429096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() {
430096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
431096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
432096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
433096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                  SkTypeface::Style style,
434096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                  FontIdentity* outIdentity,
435096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                  SkString* outFamilyName,
436096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                  SkTypeface::Style* outStyle) {
437096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    std::string familyStr(familyName ? familyName : "");
438096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (familyStr.length() > kMaxFontFamilyLength) {
439096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return false;
440096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
441096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
442096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkAutoMutexAcquire ac(mutex_);
443096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
444096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcPattern* pattern = FcPatternCreate();
445096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
446096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (familyName) {
447096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
448096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
449096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcPatternAddInteger(pattern, FC_WEIGHT,
450096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                        (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD
451096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                    : FC_WEIGHT_NORMAL);
452096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcPatternAddInteger(pattern, FC_SLANT,
453096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                        (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC
454096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                      : FC_SLANT_ROMAN);
455096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
456096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
457096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
458096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcDefaultSubstitute(pattern);
459096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
460096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // Font matching:
461096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // CSS often specifies a fallback list of families:
462096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //    font-family: a, b, c, serif;
463096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // However, fontconfig will always do its best to find *a* font when asked
464096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // for something so we need a way to tell if the match which it has found is
465096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // "good enough" for us. Otherwise, we can return NULL which gets piped up
466096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // and lets WebKit know to try the next CSS family name. However, fontconfig
467096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we
468096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // wish to support that.
469096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //
470096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // Thus, if a specific family is requested we set @family_requested. Then we
471096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // record two strings: the family name after config processing and the
472096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // family name after resolving. If the two are equal, it's a good match.
473096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //
474096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // So consider the case where a user has mapped Arial to Helvetica in their
475096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // config.
476096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //    requested family: "Arial"
477096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //    post_config_family: "Helvetica"
478096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //    post_match_family: "Helvetica"
479096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //      -> good match
480096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //
481096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // and for a missing font:
482096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //    requested family: "Monaco"
483096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //    post_config_family: "Monaco"
484096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //    post_match_family: "Times New Roman"
485096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //      -> BAD match
486096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    //
487096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // However, we special-case fallback fonts; see IsFallbackFontAllowed().
4887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* post_config_family = get_name(pattern, FC_FAMILY);
4907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!post_config_family) {
4917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // we can just continue with an empty name, e.g. default font
4927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        post_config_family = "";
4937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcResult result;
4967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
4977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!font_set) {
4987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcPatternDestroy(pattern);
4997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
5007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcPattern* match = MatchFont(font_set, post_config_family, familyStr);
5037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!match) {
5047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcPatternDestroy(pattern);
5057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcFontSetDestroy(font_set);
5067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
5077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcPatternDestroy(pattern);
5107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // From here out we just extract our results from 'match'
5127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    post_config_family = get_name(match, FC_FAMILY);
5147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!post_config_family) {
5157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcFontSetDestroy(font_set);
5167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
5177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* c_filename = get_name(match, FC_FILE);
5207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!c_filename) {
5217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcFontSetDestroy(font_set);
5227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
5237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int face_index;
5267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) {
5277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcFontSetDestroy(font_set);
5287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
5297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcFontSetDestroy(font_set);
5327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (outIdentity) {
5347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        outIdentity->fTTCIndex = face_index;
5357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        outIdentity->fString.set(c_filename);
5367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (outFamilyName) {
5387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        outFamilyName->set(post_config_family);
5397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (outStyle) {
5417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        *outStyle = GetFontStyle(match);
5427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return true;
5447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
5457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkStream* SkFontConfigInterfaceDirect::openStream(const FontIdentity& identity) {
5477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkStream::NewFromFile(identity.fString.c_str());
5487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
5497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
5517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic bool find_name(const SkTDArray<const char*>& list, const char* str) {
5537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int count = list.count();
5547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < count; ++i) {
5557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!strcmp(list[i], str)) {
5567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return true;
5577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
5587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return false;
5607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
5617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() {
5637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkAutoMutexAcquire ac(mutex_);
5647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcPattern* pat = FcPatternCreate();
56658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat);
56758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (NULL == pat) {
56858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
56958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
57058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
57158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, (char *)0);
57258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkAutoTCallVProc<FcObjectSet, FcObjectSetDestroy> autoDestroyOs(os);
5737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL == os) {
5747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return NULL;
5757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
57658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcFontSet* fs = FcFontList(NULL, pat, os);
57858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs);
5797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL == fs) {
5807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return NULL;
5817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkTDArray<const char*> names;
5847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkTDArray<size_t> sizes;
5857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < fs->nfont; ++i) {
5867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcPattern* match = fs->fonts[i];
5877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const char* famName = get_name(match, FC_FAMILY);
5887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (famName && !find_name(names, famName)) {
5897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            *names.append() = famName;
5907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            *sizes.append() = strlen(famName) + 1;
5917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
5927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
5957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                      sizes.begin(), names.count());
5967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
5977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[],
5997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                 SkString* outFamilyName,
6007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                 SkTArray<FontIdentity>* ids) {
6017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkAutoMutexAcquire ac(mutex_);
6027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if 0
6047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    std::string familyStr(familyName ? familyName : "");
6057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (familyStr.length() > kMaxFontFamilyLength) {
6067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
6077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkAutoMutexAcquire ac(mutex_);
6107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcPattern* pattern = FcPatternCreate();
6127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (familyName) {
6147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
6157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
6177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
6197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    FcDefaultSubstitute(pattern);
6207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Font matching:
6227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // CSS often specifies a fallback list of families:
6237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //    font-family: a, b, c, serif;
6247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // However, fontconfig will always do its best to find *a* font when asked
6257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // for something so we need a way to tell if the match which it has found is
6267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // "good enough" for us. Otherwise, we can return NULL which gets piped up
6277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // and lets WebKit know to try the next CSS family name. However, fontconfig
6287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we
6297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // wish to support that.
6307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //
6317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Thus, if a specific family is requested we set @family_requested. Then we
6327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // record two strings: the family name after config processing and the
6337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // family name after resolving. If the two are equal, it's a good match.
6347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //
6357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // So consider the case where a user has mapped Arial to Helvetica in their
6367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // config.
6377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //    requested family: "Arial"
6387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //    post_config_family: "Helvetica"
6397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //    post_match_family: "Helvetica"
6407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //      -> good match
6417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //
6427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // and for a missing font:
6437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //    requested family: "Monaco"
6447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //    post_config_family: "Monaco"
6457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //    post_match_family: "Times New Roman"
6467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //      -> BAD match
6477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    //
6487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // However, we special-case fallback fonts; see IsFallbackFontAllowed().
6497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* post_config_family = get_name(pattern, FC_FAMILY);
651096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
652096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcResult result;
653096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
654096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (!font_set) {
655096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FcPatternDestroy(pattern);
656096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return false;
657096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
658096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
659096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcPattern* match = MatchFont(font_set, post_config_family, familyStr);
660096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (!match) {
661096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FcPatternDestroy(pattern);
662096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FcFontSetDestroy(font_set);
663096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return false;
664096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
665096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
666096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcPatternDestroy(pattern);
667096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
668096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // From here out we just extract our results from 'match'
669096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
670096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (FcPatternGetString(match, FC_FAMILY, 0, &post_config_family) != FcResultMatch) {
671096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FcFontSetDestroy(font_set);
672096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return false;
673096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
674096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
675096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcChar8* c_filename;
676096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (FcPatternGetString(match, FC_FILE, 0, &c_filename) != FcResultMatch) {
677096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FcFontSetDestroy(font_set);
678096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return false;
679096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
680096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
681096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    int face_index;
682096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) {
683096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        FcFontSetDestroy(font_set);
684096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return false;
685096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
686096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
687096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    FcFontSetDestroy(font_set);
688096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
689096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (outIdentity) {
690096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        outIdentity->fTTCIndex = face_index;
691096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        outIdentity->fString.set((const char*)c_filename);
692096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
693096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (outFamilyName) {
694096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        outFamilyName->set((const char*)post_config_family);
695096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
696096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (outStyle) {
697096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        *outStyle = GetFontStyle(match);
698096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
699096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    return true;
700096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
7017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger////////////////////
7027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int count;
7047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcPattern** match = MatchFont(font_set, post_config_family, &count);
7057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!match) {
7067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            FcPatternDestroy(pattern);
7077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            FcFontSetDestroy(font_set);
7087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return NULL;
7097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
7107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        FcPatternDestroy(pattern);
7127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkTDArray<FcPattern*> trimmedMatches;
7147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int i = 0; i < count; ++i) {
7157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            const char* justName = find_just_name(get_name(match[i], FC_FILE));
7167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            if (!is_lower(*justName)) {
7177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                *trimmedMatches.append() = match[i];
7187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
7197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
7207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkFontStyleSet_FC* sset = SkNEW_ARGS(SkFontStyleSet_FC,
7227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             (trimmedMatches.begin(),
7237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                              trimmedMatches.count()));
7247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
7257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return false;
726096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
727