Upstream version 10.39.225.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 static SkTypeface::Style sktypefacestyle_from_fcpattern(FcPattern* pattern) {
377     int fcweight = get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR);
378     int fcslant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN);
379     return (SkTypeface::Style)((fcweight >= FC_WEIGHT_BOLD ? SkTypeface::kBold : 0) |
380                                 (fcslant > FC_SLANT_ROMAN ? SkTypeface::kItalic : 0));
381 }
382
383 class SkTypeface_stream : public SkTypeface_FreeType {
384 public:
385     /** @param stream does not take ownership of the reference, does take ownership of the stream.*/
386     SkTypeface_stream(SkTypeface::Style style, bool fixedWidth, int ttcIndex, SkStreamAsset* stream)
387         : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth)
388         , fStream(SkRef(stream))
389         , fIndex(ttcIndex)
390     { };
391
392     virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
393         familyName->reset();
394     }
395
396     virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const SK_OVERRIDE {
397         desc->setFontIndex(fIndex);
398         *serialize = true;
399     }
400
401     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
402         *ttcIndex = fIndex;
403         return fStream->duplicate();
404     }
405
406 private:
407     SkAutoTUnref<SkStreamAsset> fStream;
408     int fIndex;
409
410     typedef SkTypeface_FreeType INHERITED;
411 };
412
413 class SkTypeface_fontconfig : public SkTypeface_FreeType {
414 public:
415     /** @param pattern takes ownership of the reference. */
416     static SkTypeface_fontconfig* Create(FcPattern* pattern) {
417         return SkNEW_ARGS(SkTypeface_fontconfig, (pattern));
418     }
419     mutable SkAutoFcPattern fPattern;
420
421     virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
422         *familyName = get_string(fPattern, FC_FAMILY);
423     }
424
425     virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const SK_OVERRIDE {
426         FCLocker lock;
427         desc->setFamilyName(get_string(fPattern, FC_FAMILY));
428         desc->setFullName(get_string(fPattern, FC_FULLNAME));
429         desc->setPostscriptName(get_string(fPattern, FC_POSTSCRIPT_NAME));
430         desc->setFontFileName(get_string(fPattern, FC_FILE));
431         desc->setFontIndex(get_int(fPattern, FC_INDEX, 0));
432         *serialize = false;
433     }
434
435     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
436         FCLocker lock;
437         *ttcIndex = get_int(fPattern, FC_INDEX, 0);
438         return SkStream::NewFromFile(get_string(fPattern, FC_FILE));
439     }
440
441     virtual ~SkTypeface_fontconfig() {
442         // Hold the lock while unrefing the pattern.
443         FCLocker lock;
444         fPattern.reset();
445     }
446
447 private:
448     /** @param pattern takes ownership of the reference. */
449     SkTypeface_fontconfig(FcPattern* pattern)
450         : INHERITED(sktypefacestyle_from_fcpattern(pattern),
451                     SkTypefaceCache::NewFontID(),
452                     FC_PROPORTIONAL != get_int(pattern, FC_SPACING, FC_PROPORTIONAL))
453         , fPattern(pattern)
454     { };
455
456     typedef SkTypeface_FreeType INHERITED;
457 };
458
459 class SkFontMgr_fontconfig : public SkFontMgr {
460     mutable SkAutoFcConfig fFC;
461     SkAutoTUnref<SkDataTable> fFamilyNames;
462
463     class StyleSet : public SkFontStyleSet {
464     public:
465         /** @param parent does not take ownership of the reference.
466          *  @param fontSet takes ownership of the reference.
467          */
468         StyleSet(const SkFontMgr_fontconfig* parent, FcFontSet* fontSet)
469             : fFontMgr(SkRef(parent)), fFontSet(fontSet)
470         { }
471
472         virtual ~StyleSet() {
473             // Hold the lock while unrefing the font set.
474             FCLocker lock;
475             fFontSet.reset();
476         }
477
478         virtual int count() SK_OVERRIDE { return fFontSet->nfont; }
479
480         virtual void getStyle(int index, SkFontStyle* style, SkString* styleName) SK_OVERRIDE {
481             if (index < 0 || fFontSet->nfont <= index) {
482                 return;
483             }
484
485             FCLocker lock;
486             if (style) {
487                 *style = skfontstyle_from_fcpattern(fFontSet->fonts[index]);
488             }
489             if (styleName) {
490                 *styleName = get_string(fFontSet->fonts[index], FC_STYLE);
491             }
492         }
493
494         virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
495             FCLocker lock;
496
497             FcPattern* match = fFontSet->fonts[index];
498             return fFontMgr->createTypefaceFromFcPattern(match);
499         }
500
501         virtual SkTypeface* matchStyle(const SkFontStyle& style) SK_OVERRIDE {
502             FCLocker lock;
503
504             SkAutoFcPattern pattern;
505             fcpattern_from_skfontstyle(style, pattern);
506             FcConfigSubstitute(fFontMgr->fFC, pattern, FcMatchPattern);
507             FcDefaultSubstitute(pattern);
508
509             FcResult result;
510             FcFontSet* fontSets[1] = { fFontSet };
511             SkAutoFcPattern match(FcFontSetMatch(fFontMgr->fFC,
512                                                  fontSets, SK_ARRAY_COUNT(fontSets),
513                                                  pattern, &result));
514             if (NULL == match) {
515                 return NULL;
516             }
517
518             return fFontMgr->createTypefaceFromFcPattern(match);
519         }
520
521     private:
522         SkAutoTUnref<const SkFontMgr_fontconfig> fFontMgr;
523         SkAutoFcFontSet fFontSet;
524     };
525
526     static bool FindName(const SkTDArray<const char*>& list, const char* str) {
527         int count = list.count();
528         for (int i = 0; i < count; ++i) {
529             if (!strcmp(list[i], str)) {
530                 return true;
531             }
532         }
533         return false;
534     }
535
536     static SkDataTable* GetFamilyNames(FcConfig* fcconfig) {
537         FCLocker lock;
538
539         SkTDArray<const char*> names;
540         SkTDArray<size_t> sizes;
541
542         static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
543         for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
544             // Return value of FcConfigGetFonts must not be destroyed.
545             FcFontSet* allFonts(FcConfigGetFonts(fcconfig, fcNameSet[setIndex]));
546             if (NULL == allFonts) {
547                 continue;
548             }
549
550             for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
551                 FcPattern* current = allFonts->fonts[fontIndex];
552                 for (int id = 0; ; ++id) {
553                     FcChar8* fcFamilyName;
554                     FcResult result = FcPatternGetString(current, FC_FAMILY, id, &fcFamilyName);
555                     if (FcResultNoId == result) {
556                         break;
557                     }
558                     if (FcResultMatch != result) {
559                         continue;
560                     }
561                     const char* familyName = reinterpret_cast<const char*>(fcFamilyName);
562                     if (familyName && !FindName(names, familyName)) {
563                         *names.append() = familyName;
564                         *sizes.append() = strlen(familyName) + 1;
565                     }
566                 }
567             }
568         }
569
570         return SkDataTable::NewCopyArrays((void const *const *)names.begin(),
571                                           sizes.begin(), names.count());
572     }
573
574     static bool FindByFcPattern(SkTypeface* cached, SkTypeface::Style, void* ctx) {
575         SkTypeface_fontconfig* cshFace = static_cast<SkTypeface_fontconfig*>(cached);
576         FcPattern* ctxPattern = static_cast<FcPattern*>(ctx);
577         return FcTrue == FcPatternEqual(cshFace->fPattern, ctxPattern);
578     }
579
580     mutable SkMutex fTFCacheMutex;
581     mutable SkTypefaceCache fTFCache;
582     /** Creates a typeface using a typeface cache.
583      *  @param pattern a complete pattern from FcFontRenderPrepare.
584      */
585     SkTypeface* createTypefaceFromFcPattern(FcPattern* pattern) const {
586         FCLocker::AssertHeld();
587         SkAutoMutexAcquire ama(fTFCacheMutex);
588         SkTypeface* face = fTFCache.findByProcAndRef(FindByFcPattern, pattern);
589         if (NULL == face) {
590             FcPatternReference(pattern);
591             face = SkTypeface_fontconfig::Create(pattern);
592             if (face) {
593                 fTFCache.add(face, SkTypeface::kNormal, true);
594             }
595         }
596         return face;
597     }
598
599 public:
600     SkFontMgr_fontconfig()
601         : fFC(FcInitLoadConfigAndFonts())
602         , fFamilyNames(GetFamilyNames(fFC)) { }
603
604     /** Takes control of the reference to 'config'. */
605     explicit SkFontMgr_fontconfig(FcConfig* config)
606         : fFC(config)
607         , fFamilyNames(GetFamilyNames(fFC)) { }
608
609     virtual ~SkFontMgr_fontconfig() {
610         // Hold the lock while unrefing the config.
611         FCLocker lock;
612         fFC.reset();
613     }
614
615 protected:
616     virtual int onCountFamilies() const SK_OVERRIDE {
617         return fFamilyNames->count();
618     }
619
620     virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
621         familyName->set(fFamilyNames->atStr(index));
622     }
623
624     virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE {
625         return this->onMatchFamily(fFamilyNames->atStr(index));
626     }
627
628     /** True if any string object value in the font is the same
629      *         as a string object value in the pattern.
630      */
631     static bool AnyMatching(FcPattern* font, FcPattern* pattern, const char* object) {
632         FcChar8* fontString;
633         FcChar8* patternString;
634         FcResult result;
635         // Set an arbitrary limit on the number of pattern object values to consider.
636         // TODO: re-write this to avoid N*M
637         static const int maxId = 16;
638         for (int patternId = 0; patternId < maxId; ++patternId) {
639             result = FcPatternGetString(pattern, object, patternId, &patternString);
640             if (FcResultNoId == result) {
641                 break;
642             }
643             if (FcResultMatch != result) {
644                 continue;
645             }
646             for (int fontId = 0; fontId < maxId; ++fontId) {
647                 result = FcPatternGetString(font, object, fontId, &fontString);
648                 if (FcResultNoId == result) {
649                     break;
650                 }
651                 if (FcResultMatch != result) {
652                     continue;
653                 }
654                 if (0 == FcStrCmpIgnoreCase(patternString, fontString)) {
655                     return true;
656                 }
657             }
658         }
659         return false;
660     }
661
662     static bool FontAccessible(FcPattern* font) {
663         // FontConfig can return fonts which are unreadable.
664         const char* filename = get_string(font, FC_FILE, NULL);
665         if (NULL == filename) {
666             return false;
667         }
668         return sk_exists(filename, kRead_SkFILE_Flag);
669     }
670
671     static bool FontFamilyNameMatches(FcPattern* font, FcPattern* pattern) {
672         return AnyMatching(font, pattern, FC_FAMILY);
673     }
674
675     static bool FontContainsCharacter(FcPattern* font, uint32_t character) {
676         FcResult result;
677         FcCharSet* matchCharSet;
678         for (int charSetId = 0; ; ++charSetId) {
679             result = FcPatternGetCharSet(font, FC_CHARSET, charSetId, &matchCharSet);
680             if (FcResultNoId == result) {
681                 break;
682             }
683             if (FcResultMatch != result) {
684                 continue;
685             }
686             if (FcCharSetHasChar(matchCharSet, character)) {
687                 return true;
688             }
689         }
690         return false;
691     }
692
693     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
694         FCLocker lock;
695
696         SkAutoFcPattern pattern;
697         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
698         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
699         FcDefaultSubstitute(pattern);
700
701         FcPattern* matchPattern;
702         SkAutoFcPattern strongPattern(NULL);
703         if (familyName) {
704             strongPattern.reset(FcPatternDuplicate(pattern));
705             remove_weak(strongPattern, FC_FAMILY);
706             matchPattern = strongPattern;
707         } else {
708             matchPattern = pattern;
709         }
710
711         SkAutoFcFontSet matches;
712         // TODO: Some families have 'duplicates' due to symbolic links.
713         // The patterns are exactly the same except for the FC_FILE.
714         // It should be possible to collapse these patterns by normalizing.
715         static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
716         for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
717             // Return value of FcConfigGetFonts must not be destroyed.
718             FcFontSet* allFonts(FcConfigGetFonts(fFC, fcNameSet[setIndex]));
719             if (NULL == allFonts) {
720                 continue;
721             }
722
723             for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
724                 FcPattern* font = allFonts->fonts[fontIndex];
725                 if (FontAccessible(font) && FontFamilyNameMatches(font, matchPattern)) {
726                     FcFontSetAdd(matches, FcFontRenderPrepare(fFC, pattern, font));
727                 }
728             }
729         }
730
731         return SkNEW_ARGS(StyleSet, (this, matches.detach()));
732     }
733
734     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
735                                            const SkFontStyle& style) const SK_OVERRIDE
736     {
737         FCLocker lock;
738
739         SkAutoFcPattern pattern;
740         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
741         fcpattern_from_skfontstyle(style, pattern);
742         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
743         FcDefaultSubstitute(pattern);
744
745         // We really want to match strong (prefered) and same (acceptable) only here.
746         // If a family name was specified, assume that any weak matches after the last strong match
747         // are weak (default) and ignore them.
748         // The reason for is that after substitution the pattern for 'sans-serif' looks like
749         // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, followed by defaults.
750         // So it is possible to have weakly matching but preferred names.
751         // In aliases, bindings are weak by default, so this is easy and common.
752         // If no family name was specified, we'll probably only get weak matches, but that's ok.
753         FcPattern* matchPattern;
754         SkAutoFcPattern strongPattern(NULL);
755         if (familyName) {
756             strongPattern.reset(FcPatternDuplicate(pattern));
757             remove_weak(strongPattern, FC_FAMILY);
758             matchPattern = strongPattern;
759         } else {
760             matchPattern = pattern;
761         }
762
763         FcResult result;
764         SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
765         if (NULL == font || !FontAccessible(font) || !FontFamilyNameMatches(font, matchPattern)) {
766             return NULL;
767         }
768
769         return createTypefaceFromFcPattern(font);
770     }
771
772     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
773                                                     const SkFontStyle& style,
774                                                     const char bpc47[],
775                                                     uint32_t character) const SK_OVERRIDE
776     {
777         FCLocker lock;
778
779         SkAutoFcPattern pattern;
780         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
781         fcpattern_from_skfontstyle(style, pattern);
782
783         SkAutoFcCharSet charSet;
784         FcCharSetAddChar(charSet, character);
785         FcPatternAddCharSet(pattern, FC_CHARSET, charSet);
786
787         if (bpc47) {
788             SkAutoFcLangSet langSet;
789             FcLangSetAdd(langSet, (const FcChar8*)bpc47);
790             FcPatternAddLangSet(pattern, FC_LANG, langSet);
791         }
792
793         FcConfigSubstitute(fFC, pattern, FcMatchPattern);
794         FcDefaultSubstitute(pattern);
795
796         FcResult result;
797         SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
798         if (NULL == font || !FontAccessible(font) || !FontContainsCharacter(font, character)) {
799             return NULL;
800         }
801
802         return createTypefaceFromFcPattern(font);
803     }
804
805     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
806                                          const SkFontStyle& style) const SK_OVERRIDE
807     {
808         //TODO: should the SkTypeface_fontconfig know its family?
809         const SkTypeface_fontconfig* fcTypeface =
810                 static_cast<const SkTypeface_fontconfig*>(typeface);
811         return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY), style);
812     }
813
814     /** @param stream does not take ownership of the reference. */
815     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
816         const size_t length = stream->getLength();
817         if (length <= 0 || (1u << 30) < length) {
818             return NULL;
819         }
820
821         SkTypeface::Style style = SkTypeface::kNormal;
822         bool isFixedWidth = false;
823         if (!SkTypeface_FreeType::ScanFont(stream, ttcIndex, NULL, &style, &isFixedWidth)) {
824             return NULL;
825         }
826
827         return SkNEW_ARGS(SkTypeface_stream, (style, isFixedWidth, ttcIndex,
828                                               static_cast<SkStreamAsset*>(stream)));
829     }
830
831     virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
832         SkAutoTUnref<SkStreamAsset> stream(SkNEW_ARGS(SkMemoryStream, (data)));
833         return this->createFromStream(stream, ttcIndex);
834     }
835
836     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
837         SkAutoTUnref<SkStreamAsset> stream(SkStream::NewFromFile(path));
838         return this->createFromStream(stream, ttcIndex);
839     }
840
841     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
842                                                unsigned styleBits) const SK_OVERRIDE {
843         bool bold = styleBits & SkTypeface::kBold;
844         bool italic = styleBits & SkTypeface::kItalic;
845         SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight
846                                              : SkFontStyle::kNormal_Weight,
847                                         SkFontStyle::kNormal_Width,
848                                         italic ? SkFontStyle::kItalic_Slant
849                                                : SkFontStyle::kUpright_Slant);
850         SkAutoTUnref<SkTypeface> typeface(this->matchFamilyStyle(familyName, style));
851         if (typeface.get()) {
852             return typeface.detach();
853         }
854
855         return this->matchFamilyStyle(NULL, style);
856     }
857 };
858
859 SkFontMgr* SkFontMgr::Factory() {
860     return SkNEW(SkFontMgr_fontconfig);
861 }