Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / ports / SkFontMgr_fontconfig.cpp
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 "SkDataTable.h"
9 #include "SkFontDescriptor.h"
10 #include "SkFontHost_FreeType_common.h"
11 #include "SkFontMgr.h"
12 #include "SkFontStyle.h"
13 #include "SkMath.h"
14 #include "SkString.h"
15 #include "SkStream.h"
16 #include "SkTDArray.h"
17 #include "SkThread.h"
18 #include "SkTypefaceCache.h"
19 #include "SkOSFile.h"
20
21 #include <fontconfig/fontconfig.h>
22
23 // FC_POSTSCRIPT_NAME was added with b561ff20 which ended up in 2.10.92
24 // Ubuntu 12.04 is on 2.8.0, 13.10 is on 2.10.93
25 // Debian 7 is on 2.9.0, 8 is on 2.11
26 // OpenSUSE 12.2 is on 2.9.0, 12.3 is on 2.10.2, 13.1 2.11.0
27 // Fedora 19 is on 2.10.93
28 #ifndef FC_POSTSCRIPT_NAME
29 #    define FC_POSTSCRIPT_NAME  "postscriptname"
30 #endif
31
32 #ifdef SK_DEBUG
33 #    include "SkTLS.h"
34 #endif
35
36 /** Since FontConfig is poorly documented, this gives a high level overview:
37  *
38  *  FcConfig is a handle to a FontConfig configuration instance. Each 'configuration' is independent
39  *  from any others which may exist. There exists a default global configuration which is created
40  *  and destroyed by FcInit and FcFini, but this default should not normally be used.
41  *  Instead, one should use FcConfigCreate and FcInit* to have a named local state.
42  *
43  *  FcPatterns are {objectName -> [element]} (maps from object names to a list of elements).
44  *  Each element is some internal data plus an FcValue which is a variant (a union with a type tag).
45  *  Lists of elements are not typed, except by convention. Any collection of FcValues must be
46  *  assumed to be heterogeneous by the code, but the code need not do anything particularly
47  *  interesting if the values go against convention.
48  *
49  *  Somewhat like DirectWrite, FontConfig supports synthetics through FC_EMBOLDEN and FC_MATRIX.
50  *  Like all synthetic information, such information must be passed with the font data.
51  */
52
53 namespace {
54
55 // Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex.
56 // See http://skbug.com/1497 for background.
57 SK_DECLARE_STATIC_MUTEX(gFCMutex);
58
59 #ifdef SK_DEBUG
60     void *CreateThreadFcLocked() { return SkNEW_ARGS(bool, (false)); }
61     void DeleteThreadFcLocked(void* v) { SkDELETE(static_cast<bool*>(v)); }
62 #   define THREAD_FC_LOCKED \
63         static_cast<bool*>(SkTLS::Get(CreateThreadFcLocked, DeleteThreadFcLocked))
64 #endif
65
66 struct FCLocker {
67     // Assume FcGetVersion() has always been thread safe.
68
69     FCLocker() {
70         if (FcGetVersion() < 21091) {
71             gFCMutex.acquire();
72         } else {
73             SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED);
74             SkASSERT(false == *threadLocked);
75             SkDEBUGCODE(*threadLocked = true);
76         }
77     }
78
79     ~FCLocker() {
80         AssertHeld();
81         if (FcGetVersion() < 21091) {
82             gFCMutex.release();
83         } else {
84             SkDEBUGCODE(*THREAD_FC_LOCKED = false);
85         }
86     }
87
88     static void AssertHeld() { SkDEBUGCODE(
89         if (FcGetVersion() < 21091) {
90             gFCMutex.assertHeld();
91         } else {
92             SkASSERT(true == *THREAD_FC_LOCKED);
93         }
94     ) }
95 };
96
97 } // namespace
98
99 template<typename T, void (*D)(T*)> void FcTDestroy(T* t) {
100     FCLocker::AssertHeld();
101     D(t);
102 }
103 template <typename T, T* (*C)(), void (*D)(T*)> class SkAutoFc
104     : public SkAutoTCallVProc<T, FcTDestroy<T, D> > {
105 public:
106     SkAutoFc() : SkAutoTCallVProc<T, FcTDestroy<T, D> >(C()) {
107         T* obj = this->operator T*();
108         SK_ALWAYSBREAK(NULL != obj);
109     }
110     explicit SkAutoFc(T* obj) : SkAutoTCallVProc<T, FcTDestroy<T, D> >(obj) {}
111 };
112
113 typedef SkAutoFc<FcCharSet, FcCharSetCreate, FcCharSetDestroy> SkAutoFcCharSet;
114 typedef SkAutoFc<FcConfig, FcConfigCreate, FcConfigDestroy> SkAutoFcConfig;
115 typedef SkAutoFc<FcFontSet, FcFontSetCreate, FcFontSetDestroy> SkAutoFcFontSet;
116 typedef SkAutoFc<FcLangSet, FcLangSetCreate, FcLangSetDestroy> SkAutoFcLangSet;
117 typedef SkAutoFc<FcObjectSet, FcObjectSetCreate, FcObjectSetDestroy> SkAutoFcObjectSet;
118 typedef SkAutoFc<FcPattern, FcPatternCreate, FcPatternDestroy> SkAutoFcPattern;
119
120 static int get_int(FcPattern* pattern, const char object[], int missing) {
121     int value;
122     if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) {
123         return missing;
124     }
125     return value;
126 }
127
128 static const char* get_string(FcPattern* pattern, const char object[], const char* missing = "") {
129     FcChar8* value;
130     if (FcPatternGetString(pattern, object, 0, &value) != FcResultMatch) {
131         return missing;
132     }
133     return (const char*)value;
134 }
135
136 enum SkWeakReturn {
137     kIsWeak_WeakReturn,
138     kIsStrong_WeakReturn,
139     kNoId_WeakReturn
140 };
141 /** Ideally there  would exist a call like
142  *  FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak);
143  *
144  *  However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit.
145  *  Currently, the only reliable way of finding the weak bit is by its effect on matching.
146  *  The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values.
147  *  A element with the weak bit is scored after FC_LANG, without the weak bit is scored before.
148  *  Note that the weak bit is stored on the element, not on the value it holds.
149  */
150 static SkWeakReturn is_weak(FcPattern* pattern, const char object[], int id) {
151     FCLocker::AssertHeld();
152
153     FcResult result;
154
155     // Create a copy of the pattern with only the value 'pattern'['object'['id']] in it.
156     // Internally, FontConfig pattern objects are linked lists, so faster to remove from head.
157     SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, NULL));
158     SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
159     FcBool hasId = true;
160     for (int i = 0; hasId && i < id; ++i) {
161         hasId = FcPatternRemove(minimal, object, 0);
162     }
163     if (!hasId) {
164         return kNoId_WeakReturn;
165     }
166     FcValue value;
167     result = FcPatternGet(minimal, object, 0, &value);
168     if (result != FcResultMatch) {
169         return kNoId_WeakReturn;
170     }
171     while (hasId) {
172         hasId = FcPatternRemove(minimal, object, 1);
173     }
174
175     // Create a font set with two patterns.
176     // 1. the same 'object' as minimal and a lang object with only 'nomatchlang'.
177     // 2. a different 'object' from minimal and a lang object with only 'matchlang'.
178     SkAutoFcFontSet fontSet;
179
180     SkAutoFcLangSet strongLangSet;
181     FcLangSetAdd(strongLangSet, (const FcChar8*)"nomatchlang");
182     SkAutoFcPattern strong(FcPatternDuplicate(minimal));
183     FcPatternAddLangSet(strong, FC_LANG, strongLangSet);
184
185     SkAutoFcLangSet weakLangSet;
186     FcLangSetAdd(weakLangSet, (const FcChar8*)"matchlang");
187     SkAutoFcPattern weak;
188     FcPatternAddString(weak, object, (const FcChar8*)"nomatchstring");
189     FcPatternAddLangSet(weak, FC_LANG, weakLangSet);
190
191     FcFontSetAdd(fontSet, strong.detach());
192     FcFontSetAdd(fontSet, weak.detach());
193
194     // Add 'matchlang' to the copy of the pattern.
195     FcPatternAddLangSet(minimal, FC_LANG, weakLangSet);
196
197     // Run a match against the copy of the pattern.
198     // If the 'id' was weak, then we should match the pattern with 'matchlang'.
199     // If the 'id' was strong, then we should match the pattern with 'nomatchlang'.
200
201     // Note that this config is only used for FcFontRenderPrepare, which we don't even want.
202     // However, there appears to be no way to match/sort without it.
203     SkAutoFcConfig config;
204     FcFontSet* fontSets[1] = { fontSet };
205     SkAutoFcPattern match(FcFontSetMatch(config, fontSets, SK_ARRAY_COUNT(fontSets),
206                                          minimal, &result));
207
208     FcLangSet* matchLangSet;
209     FcPatternGetLangSet(match, FC_LANG, 0, &matchLangSet);
210     return FcLangEqual == FcLangSetHasLang(matchLangSet, (const FcChar8*)"matchlang")
211                         ? kIsWeak_WeakReturn : kIsStrong_WeakReturn;
212 }
213
214 /** Removes weak elements from either FC_FAMILY or FC_POSTSCRIPT_NAME objects in the property.
215  *  This can be quite expensive, and should not be used more than once per font lookup.
216  *  This removes all of the weak elements after the last strong element.
217  */
218 static void remove_weak(FcPattern* pattern, const char object[]) {
219     FCLocker::AssertHeld();
220
221     SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, NULL));
222     SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
223
224     int lastStrongId = -1;
225     int numIds;
226     SkWeakReturn result;
227     for (int id = 0; ; ++id) {
228         result = is_weak(minimal, object, 0);
229         if (kNoId_WeakReturn == result) {
230             numIds = id;
231             break;
232         }
233         if (kIsStrong_WeakReturn == result) {
234             lastStrongId = id;
235         }
236         SkAssertResult(FcPatternRemove(minimal, object, 0));
237     }
238
239     // If they were all weak, then leave the pattern alone.
240     if (lastStrongId < 0) {
241         return;
242     }
243
244     // Remove everything after the last strong.
245     for (int id = lastStrongId + 1; id < numIds; ++id) {
246         SkAssertResult(FcPatternRemove(pattern, object, lastStrongId + 1));
247     }
248 }
249
250 static int map_range(SkFixed value,
251                      SkFixed old_min, SkFixed old_max,
252                      SkFixed new_min, SkFixed new_max)
253 {
254     SkASSERT(old_min < old_max);
255     SkASSERT(new_min <= new_max);
256     return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_min);
257 }
258
259 static int ave(SkFixed a, SkFixed b) {
260     return SkFixedAve(a, b);
261 }
262
263 struct MapRanges {
264     SkFixed old_val;
265     SkFixed new_val;
266 };
267
268 static SkFixed map_ranges_fixed(SkFixed val, MapRanges const ranges[], int rangesCount) {
269     // -Inf to [0]
270     if (val < ranges[0].old_val) {
271         return ranges[0].new_val;
272     }
273
274     // Linear from [i] to ave([i], [i+1]), then from ave([i], [i+1]) to [i+1]
275     for (int i = 0; i < rangesCount - 1; ++i) {
276         if (val < ave(ranges[i].old_val, ranges[i+1].old_val)) {
277             return map_range(val, ranges[i].old_val, ave(ranges[i].old_val, ranges[i+1].old_val),
278                                   ranges[i].new_val, ave(ranges[i].new_val, ranges[i+1].new_val));
279         }
280         if (val < ranges[i+1].old_val) {
281             return map_range(val, ave(ranges[i].old_val, ranges[i+1].old_val), ranges[i+1].old_val,
282                                   ave(ranges[i].new_val, ranges[i+1].new_val), ranges[i+1].new_val);
283         }
284     }
285
286     // From [n] to +Inf
287     // if (fcweight < Inf)
288     return ranges[rangesCount-1].new_val;
289 }
290
291 static int map_ranges(int val, MapRanges const ranges[], int rangesCount) {
292     return SkFixedRoundToInt(map_ranges_fixed(SkIntToFixed(val), ranges, rangesCount));
293 }
294
295 template<int n> struct SkTFixed {
296     SK_COMPILE_ASSERT(-32768 <= n && n <= 32767, SkTFixed_n_not_in_range);
297     static const SkFixed value = static_cast<SkFixed>(n << 16);
298 };
299
300 static SkFontStyle skfontstyle_from_fcpattern(FcPattern* pattern) {
301     typedef SkFontStyle SkFS;
302
303     static const MapRanges weightRanges[] = {
304         { SkTFixed<FC_WEIGHT_THIN>::value,       SkTFixed<SkFS::kThin_Weight>::value },
305         { SkTFixed<FC_WEIGHT_EXTRALIGHT>::value, SkTFixed<SkFS::kExtraLight_Weight>::value },
306         { SkTFixed<FC_WEIGHT_LIGHT>::value,      SkTFixed<SkFS::kLight_Weight>::value },
307         { SkTFixed<FC_WEIGHT_REGULAR>::value,    SkTFixed<SkFS::kNormal_Weight>::value },
308         { SkTFixed<FC_WEIGHT_MEDIUM>::value,     SkTFixed<SkFS::kMedium_Weight>::value },
309         { SkTFixed<FC_WEIGHT_DEMIBOLD>::value,   SkTFixed<SkFS::kSemiBold_Weight>::value },
310         { SkTFixed<FC_WEIGHT_BOLD>::value,       SkTFixed<SkFS::kBold_Weight>::value },
311         { SkTFixed<FC_WEIGHT_EXTRABOLD>::value,  SkTFixed<SkFS::kExtraBold_Weight>::value },
312         { SkTFixed<FC_WEIGHT_BLACK>::value,      SkTFixed<SkFS::kBlack_Weight>::value },
313         { SkTFixed<FC_WEIGHT_EXTRABLACK>::value, SkTFixed<1000>::value },
314     };
315     int weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR),
316                             weightRanges, SK_ARRAY_COUNT(weightRanges));
317
318     static const MapRanges widthRanges[] = {
319         { SkTFixed<FC_WIDTH_ULTRACONDENSED>::value, SkTFixed<SkFS::kUltraCondensed_Width>::value },
320         { SkTFixed<FC_WIDTH_EXTRACONDENSED>::value, SkTFixed<SkFS::kExtraCondensed_Width>::value },
321         { SkTFixed<FC_WIDTH_CONDENSED>::value,      SkTFixed<SkFS::kCondensed_Width>::value },
322         { SkTFixed<FC_WIDTH_SEMICONDENSED>::value,  SkTFixed<SkFS::kSemiCondensed_Width>::value },
323         { SkTFixed<FC_WIDTH_NORMAL>::value,         SkTFixed<SkFS::kNormal_Width>::value },
324         { SkTFixed<FC_WIDTH_SEMIEXPANDED>::value,   SkTFixed<SkFS::kSemiExpanded_Width>::value },
325         { SkTFixed<FC_WIDTH_EXPANDED>::value,       SkTFixed<SkFS::kExpanded_Width>::value },
326         { SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value,  SkTFixed<SkFS::kExtraExpanded_Width>::value },
327         { SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value,  SkTFixed<SkFS::kUltaExpanded_Width>::value },
328     };
329     int width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL),
330                            widthRanges, SK_ARRAY_COUNT(widthRanges));
331
332     SkFS::Slant slant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN) > 0
333                              ? SkFS::kItalic_Slant
334                              : SkFS::kUpright_Slant;
335
336     return SkFontStyle(weight, width, slant);
337 }
338
339 static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
340     FCLocker::AssertHeld();
341
342     typedef SkFontStyle SkFS;
343
344     static const MapRanges weightRanges[] = {
345         { SkTFixed<SkFS::kThin_Weight>::value,       SkTFixed<FC_WEIGHT_THIN>::value },
346         { SkTFixed<SkFS::kExtraLight_Weight>::value, SkTFixed<FC_WEIGHT_EXTRALIGHT>::value },
347         { SkTFixed<SkFS::kLight_Weight>::value,      SkTFixed<FC_WEIGHT_LIGHT>::value },
348         { SkTFixed<SkFS::kNormal_Weight>::value,     SkTFixed<FC_WEIGHT_REGULAR>::value },
349         { SkTFixed<SkFS::kMedium_Weight>::value,     SkTFixed<FC_WEIGHT_MEDIUM>::value },
350         { SkTFixed<SkFS::kSemiBold_Weight>::value,   SkTFixed<FC_WEIGHT_DEMIBOLD>::value },
351         { SkTFixed<SkFS::kBold_Weight>::value,       SkTFixed<FC_WEIGHT_BOLD>::value },
352         { SkTFixed<SkFS::kExtraBold_Weight>::value,  SkTFixed<FC_WEIGHT_EXTRABOLD>::value },
353         { SkTFixed<SkFS::kBlack_Weight>::value,      SkTFixed<FC_WEIGHT_BLACK>::value },
354         { SkTFixed<1000>::value,                     SkTFixed<FC_WEIGHT_EXTRABLACK>::value },
355     };
356     int weight = map_ranges(style.weight(), weightRanges, SK_ARRAY_COUNT(weightRanges));
357
358     static const MapRanges widthRanges[] = {
359         { SkTFixed<SkFS::kUltraCondensed_Width>::value, SkTFixed<FC_WIDTH_ULTRACONDENSED>::value },
360         { SkTFixed<SkFS::kExtraCondensed_Width>::value, SkTFixed<FC_WIDTH_EXTRACONDENSED>::value },
361         { SkTFixed<SkFS::kCondensed_Width>::value,      SkTFixed<FC_WIDTH_CONDENSED>::value },
362         { SkTFixed<SkFS::kSemiCondensed_Width>::value,  SkTFixed<FC_WIDTH_SEMICONDENSED>::value },
363         { SkTFixed<SkFS::kNormal_Width>::value,         SkTFixed<FC_WIDTH_NORMAL>::value },
364         { SkTFixed<SkFS::kSemiExpanded_Width>::value,   SkTFixed<FC_WIDTH_SEMIEXPANDED>::value },
365         { SkTFixed<SkFS::kExpanded_Width>::value,       SkTFixed<FC_WIDTH_EXPANDED>::value },
366         { SkTFixed<SkFS::kExtraExpanded_Width>::value,  SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value },
367         { SkTFixed<SkFS::kUltaExpanded_Width>::value,   SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value },
368     };
369     int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges));
370
371     FcPatternAddInteger(pattern, FC_WEIGHT, weight);
372     FcPatternAddInteger(pattern, FC_WIDTH, width);
373     FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
374 }
375
376 class SkTypeface_stream : public SkTypeface_FreeType {
377 public:
378     /** @param stream does not take ownership of the reference, does take ownership of the stream.*/
379     SkTypeface_stream(const SkFontStyle& style, bool fixedWidth, int index, SkStreamAsset* stream)
380         : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth)
381         , fStream(SkRef(stream))
382         , fIndex(index)
383     { };
384
385     virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
386         familyName->reset();
387     }
388
389     virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const SK_OVERRIDE {
390         desc->setFontIndex(fIndex);
391         *serialize = true;
392     }
393
394     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
395         *ttcIndex = fIndex;
396         return fStream->duplicate();
397     }
398
399 private:
400     SkAutoTUnref<SkStreamAsset> fStream;
401     int fIndex;
402
403     typedef SkTypeface_FreeType INHERITED;
404 };
405
406 class SkTypeface_fontconfig : public SkTypeface_FreeType {
407 public:
408     /** @param pattern takes ownership of the reference. */
409     static SkTypeface_fontconfig* Create(FcPattern* pattern) {
410         return SkNEW_ARGS(SkTypeface_fontconfig, (pattern));
411     }
412     mutable SkAutoFcPattern fPattern;
413
414     virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
415         *familyName = get_string(fPattern, FC_FAMILY);
416     }
417
418     virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const SK_OVERRIDE {
419         FCLocker lock;
420         desc->setFamilyName(get_string(fPattern, FC_FAMILY));
421         desc->setFullName(get_string(fPattern, FC_FULLNAME));
422         desc->setPostscriptName(get_string(fPattern, FC_POSTSCRIPT_NAME));
423         desc->setFontFileName(get_string(fPattern, FC_FILE));
424         desc->setFontIndex(get_int(fPattern, FC_INDEX, 0));
425         *serialize = false;
426     }
427
428     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
429         FCLocker lock;
430         *ttcIndex = get_int(fPattern, FC_INDEX, 0);
431         return SkStream::NewFromFile(get_string(fPattern, FC_FILE));
432     }
433
434     virtual ~SkTypeface_fontconfig() {
435         // Hold the lock while unrefing the pattern.
436         FCLocker lock;
437         fPattern.reset();
438     }
439
440 private:
441     /** @param pattern takes ownership of the reference. */
442     SkTypeface_fontconfig(FcPattern* pattern)
443         : INHERITED(skfontstyle_from_fcpattern(pattern),
444                     SkTypefaceCache::NewFontID(),
445                     FC_PROPORTIONAL != get_int(pattern, FC_SPACING, FC_PROPORTIONAL))
446         , fPattern(pattern)
447     { };
448
449     typedef SkTypeface_FreeType INHERITED;
450 };
451
452 class SkFontMgr_fontconfig : public SkFontMgr {
453     mutable SkAutoFcConfig fFC;
454     SkAutoTUnref<SkDataTable> fFamilyNames;
455     SkTypeface_FreeType::Scanner fScanner;
456
457     class StyleSet : public SkFontStyleSet {
458     public:
459         /** @param parent does not take ownership of the reference.
460          *  @param fontSet takes ownership of the reference.
461          */
462         StyleSet(const SkFontMgr_fontconfig* parent, FcFontSet* fontSet)
463             : fFontMgr(SkRef(parent)), fFontSet(fontSet)
464         { }
465
466         virtual ~StyleSet() {
467             // Hold the lock while unrefing the font set.
468             FCLocker lock;
469             fFontSet.reset();
470         }
471
472         virtual int count() SK_OVERRIDE { return fFontSet->nfont; }
473
474         virtual void getStyle(int index, SkFontStyle* style, SkString* styleName) SK_OVERRIDE {
475             if (index < 0 || fFontSet->nfont <= index) {
476                 return;
477             }
478
479             FCLocker lock;
480             if (style) {
481                 *style = skfontstyle_from_fcpattern(fFontSet->fonts[index]);
482             }
483             if (styleName) {
484                 *styleName = get_string(fFontSet->fonts[index], FC_STYLE);
485             }
486         }
487
488         virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
489             FCLocker lock;
490
491             FcPattern* match = fFontSet->fonts[index];
492             return fFontMgr->createTypefaceFromFcPattern(match);
493         }
494
495         virtual SkTypeface* matchStyle(const SkFontStyle& style) SK_OVERRIDE {
496             FCLocker lock;
497
498             SkAutoFcPattern pattern;
499             fcpattern_from_skfontstyle(style, pattern);
500             FcConfigSubstitute(fFontMgr->fFC, pattern, FcMatchPattern);
501             FcDefaultSubstitute(pattern);
502
503             FcResult result;
504             FcFontSet* fontSets[1] = { fFontSet };
505             SkAutoFcPattern match(FcFontSetMatch(fFontMgr->fFC,
506                                                  fontSets, SK_ARRAY_COUNT(fontSets),
507                                                  pattern, &result));
508             if (NULL == match) {
509                 return NULL;
510             }
511
512             return fFontMgr->createTypefaceFromFcPattern(match);
513         }
514
515     private:
516         SkAutoTUnref<const SkFontMgr_fontconfig> fFontMgr;
517         SkAutoFcFontSet fFontSet;
518     };
519
520     static bool FindName(const SkTDArray<const char*>& list, const char* str) {
521         int count = list.count();
522         for (int i = 0; i < count; ++i) {
523             if (!strcmp(list[i], str)) {
524                 return true;
525             }
526         }
527         return false;
528     }
529
530     static SkDataTable* GetFamilyNames(FcConfig* fcconfig) {
531         FCLocker lock;
532
533         SkTDArray<const char*> names;
534         SkTDArray<size_t> sizes;
535
536         static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
537         for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
538             // Return value of FcConfigGetFonts must not be destroyed.
539             FcFontSet* allFonts(FcConfigGetFonts(fcconfig, fcNameSet[setIndex]));
540             if (NULL == allFonts) {
541                 continue;
542             }
543
544             for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
545                 FcPattern* current = allFonts->fonts[fontIndex];
546                 for (int id = 0; ; ++id) {
547                     FcChar8* fcFamilyName;
548                     FcResult result = FcPatternGetString(current, FC_FAMILY, id, &fcFamilyName);
549                     if (FcResultNoId == result) {
550                         break;
551                     }
552                     if (FcResultMatch != result) {
553                         continue;
554                     }
555                     const char* familyName = reinterpret_cast<const char*>(fcFamilyName);
556                     if (familyName && !FindName(names, familyName)) {
557                         *names.append() = familyName;
558                         *sizes.append() = strlen(familyName) + 1;
559                     }
560                 }
561             }
562         }
563
564         return SkDataTable::NewCopyArrays((void const *const *)names.begin(),
565                                           sizes.begin(), names.count());
566     }
567
568     static bool FindByFcPattern(SkTypeface* cached, const SkFontStyle&, void* ctx) {
569         SkTypeface_fontconfig* cshFace = static_cast<SkTypeface_fontconfig*>(cached);
570         FcPattern* ctxPattern = static_cast<FcPattern*>(ctx);
571         return FcTrue == FcPatternEqual(cshFace->fPattern, ctxPattern);
572     }
573
574     mutable SkMutex fTFCacheMutex;
575     mutable SkTypefaceCache fTFCache;
576     /** Creates a typeface using a typeface cache.
577      *  @param pattern a complete pattern from FcFontRenderPrepare.
578      */
579     SkTypeface* createTypefaceFromFcPattern(FcPattern* pattern) const {
580         FCLocker::AssertHeld();
581         SkAutoMutexAcquire ama(fTFCacheMutex);
582         SkTypeface* face = fTFCache.findByProcAndRef(FindByFcPattern, pattern);
583         if (NULL == face) {
584             FcPatternReference(pattern);
585             face = SkTypeface_fontconfig::Create(pattern);
586             if (face) {
587                 fTFCache.add(face, SkFontStyle());
588             }
589         }
590         return face;
591     }
592
593 public:
594     SkFontMgr_fontconfig()
595         : fFC(FcInitLoadConfigAndFonts())
596         , fFamilyNames(GetFamilyNames(fFC)) { }
597
598     /** Takes control of the reference to 'config'. */
599     explicit SkFontMgr_fontconfig(FcConfig* config)
600         : fFC(config)
601         , fFamilyNames(GetFamilyNames(fFC)) { }
602
603     virtual ~SkFontMgr_fontconfig() {
604         // Hold the lock while unrefing the config.
605         FCLocker lock;
606         fFC.reset();
607     }
608
609 protected:
610     virtual int onCountFamilies() const SK_OVERRIDE {
611         return fFamilyNames->count();
612     }
613
614     virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
615         familyName->set(fFamilyNames->atStr(index));
616     }
617
618     virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE {
619         return this->onMatchFamily(fFamilyNames->atStr(index));
620     }
621
622     /** True if any string object value in the font is the same
623      *         as a string object value in the pattern.
624      */
625     static bool AnyMatching(FcPattern* font, FcPattern* pattern, const char* object) {
626         FcChar8* fontString;
627         FcChar8* patternString;
628         FcResult result;
629         // Set an arbitrary limit on the number of pattern object values to consider.
630         // TODO: re-write this to avoid N*M
631         static const int maxId = 16;
632         for (int patternId = 0; patternId < maxId; ++patternId) {
633             result = FcPatternGetString(pattern, object, patternId, &patternString);
634             if (FcResultNoId == result) {
635                 break;
636             }
637             if (FcResultMatch != result) {
638                 continue;
639             }
640             for (int fontId = 0; fontId < maxId; ++fontId) {
641                 result = FcPatternGetString(font, object, fontId, &fontString);
642                 if (FcResultNoId == result) {
643                     break;
644                 }
645                 if (FcResultMatch != result) {
646                     continue;
647                 }
648                 if (0 == FcStrCmpIgnoreCase(patternString, fontString)) {
649                     return true;
650                 }
651             }
652         }
653         return false;
654     }
655
656     static bool FontAccessible(FcPattern* font) {
657         // FontConfig can return fonts which are unreadable.
658         const char* filename = get_string(font, FC_FILE, NULL);
659         if (NULL == filename) {
660             return false;
661         }
662         return sk_exists(filename, kRead_SkFILE_Flag);
663     }
664
665     static bool FontFamilyNameMatches(FcPattern* font, FcPattern* pattern) {
666         return AnyMatching(font, pattern, FC_FAMILY);
667     }
668
669     static bool FontContainsCharacter(FcPattern* font, uint32_t character) {
670         FcResult result;
671         FcCharSet* matchCharSet;
672         for (int charSetId = 0; ; ++charSetId) {
673             result = FcPatternGetCharSet(font, FC_CHARSET, charSetId, &matchCharSet);
674             if (FcResultNoId == result) {
675                 break;
676             }
677             if (FcResultMatch != result) {
678                 continue;
679             }
680             if (FcCharSetHasChar(matchCharSet, character)) {
681                 return true;
682             }
683         }
684         return false;
685     }
686
687     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
688         FCLocker lock;
689
690         SkAutoFcPattern pattern;
691         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
692         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
693         FcDefaultSubstitute(pattern);
694
695         FcPattern* matchPattern;
696         SkAutoFcPattern strongPattern(NULL);
697         if (familyName) {
698             strongPattern.reset(FcPatternDuplicate(pattern));
699             remove_weak(strongPattern, FC_FAMILY);
700             matchPattern = strongPattern;
701         } else {
702             matchPattern = pattern;
703         }
704
705         SkAutoFcFontSet matches;
706         // TODO: Some families have 'duplicates' due to symbolic links.
707         // The patterns are exactly the same except for the FC_FILE.
708         // It should be possible to collapse these patterns by normalizing.
709         static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
710         for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
711             // Return value of FcConfigGetFonts must not be destroyed.
712             FcFontSet* allFonts(FcConfigGetFonts(fFC, fcNameSet[setIndex]));
713             if (NULL == allFonts) {
714                 continue;
715             }
716
717             for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
718                 FcPattern* font = allFonts->fonts[fontIndex];
719                 if (FontAccessible(font) && FontFamilyNameMatches(font, matchPattern)) {
720                     FcFontSetAdd(matches, FcFontRenderPrepare(fFC, pattern, font));
721                 }
722             }
723         }
724
725         return SkNEW_ARGS(StyleSet, (this, matches.detach()));
726     }
727
728     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
729                                            const SkFontStyle& style) const SK_OVERRIDE
730     {
731         FCLocker lock;
732
733         SkAutoFcPattern pattern;
734         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
735         fcpattern_from_skfontstyle(style, pattern);
736         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
737         FcDefaultSubstitute(pattern);
738
739         // We really want to match strong (prefered) and same (acceptable) only here.
740         // If a family name was specified, assume that any weak matches after the last strong match
741         // are weak (default) and ignore them.
742         // The reason for is that after substitution the pattern for 'sans-serif' looks like
743         // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, followed by defaults.
744         // So it is possible to have weakly matching but preferred names.
745         // In aliases, bindings are weak by default, so this is easy and common.
746         // If no family name was specified, we'll probably only get weak matches, but that's ok.
747         FcPattern* matchPattern;
748         SkAutoFcPattern strongPattern(NULL);
749         if (familyName) {
750             strongPattern.reset(FcPatternDuplicate(pattern));
751             remove_weak(strongPattern, FC_FAMILY);
752             matchPattern = strongPattern;
753         } else {
754             matchPattern = pattern;
755         }
756
757         FcResult result;
758         SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
759         if (NULL == font || !FontAccessible(font) || !FontFamilyNameMatches(font, matchPattern)) {
760             return NULL;
761         }
762
763         return createTypefaceFromFcPattern(font);
764     }
765
766 #ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
767     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
768                                                     const SkFontStyle& style,
769                                                     const char* bcp47[],
770                                                     int bcp47Count,
771                                                     SkUnichar character) const SK_OVERRIDE
772     {
773 #else
774     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
775                                                     const SkFontStyle& style,
776                                                     const char bcp47_val[],
777                                                     SkUnichar character) const SK_OVERRIDE
778     {
779         const char** bcp47 = &bcp47_val;
780         int bcp47Count = bcp47_val ? 1 : 0;
781 #endif
782         FCLocker lock;
783
784         SkAutoFcPattern pattern;
785         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
786         fcpattern_from_skfontstyle(style, pattern);
787
788         SkAutoFcCharSet charSet;
789         FcCharSetAddChar(charSet, character);
790         FcPatternAddCharSet(pattern, FC_CHARSET, charSet);
791
792         if (bcp47Count > 0) {
793             SkASSERT(bcp47);
794             SkAutoFcLangSet langSet;
795             for (int i = bcp47Count; i --> 0;) {
796                 FcLangSetAdd(langSet, (const FcChar8*)bcp47[i]);
797             }
798             FcPatternAddLangSet(pattern, FC_LANG, langSet);
799         }
800
801         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
802         FcDefaultSubstitute(pattern);
803
804         FcResult result;
805         SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
806         if (NULL == font || !FontAccessible(font) || !FontContainsCharacter(font, character)) {
807             return NULL;
808         }
809
810         return createTypefaceFromFcPattern(font);
811     }
812
813     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
814                                          const SkFontStyle& style) const SK_OVERRIDE
815     {
816         //TODO: should the SkTypeface_fontconfig know its family?
817         const SkTypeface_fontconfig* fcTypeface =
818                 static_cast<const SkTypeface_fontconfig*>(typeface);
819         return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY), style);
820     }
821
822     /** @param stream does not take ownership of the reference. */
823     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
824         const size_t length = stream->getLength();
825         if (length <= 0 || (1u << 30) < length) {
826             return NULL;
827         }
828
829         SkFontStyle style;
830         bool isFixedWidth = false;
831         if (!fScanner.scanFont(stream, ttcIndex, NULL, &style, &isFixedWidth)) {
832             return NULL;
833         }
834
835         return SkNEW_ARGS(SkTypeface_stream, (style, isFixedWidth, ttcIndex,
836                                               static_cast<SkStreamAsset*>(stream)));
837     }
838
839     virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
840         SkAutoTUnref<SkStreamAsset> stream(SkNEW_ARGS(SkMemoryStream, (data)));
841         return this->createFromStream(stream, ttcIndex);
842     }
843
844     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
845         SkAutoTUnref<SkStreamAsset> stream(SkStream::NewFromFile(path));
846         return this->createFromStream(stream, ttcIndex);
847     }
848
849     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
850                                                unsigned styleBits) const SK_OVERRIDE {
851         bool bold = styleBits & SkTypeface::kBold;
852         bool italic = styleBits & SkTypeface::kItalic;
853         SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight
854                                              : SkFontStyle::kNormal_Weight,
855                                         SkFontStyle::kNormal_Width,
856                                         italic ? SkFontStyle::kItalic_Slant
857                                                : SkFontStyle::kUpright_Slant);
858         SkAutoTUnref<SkTypeface> typeface(this->matchFamilyStyle(familyName, style));
859         if (typeface.get()) {
860             return typeface.detach();
861         }
862
863         return this->matchFamilyStyle(NULL, style);
864     }
865 };
866
867 SkFontMgr* SkFontMgr::Factory() {
868     return SkNEW(SkFontMgr_fontconfig);
869 }