Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / ports / SkFontMgr_android.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 "SkFontConfigParser_android.h"
9 #include "SkFontDescriptor.h"
10 #include "SkFontHost_FreeType_common.h"
11 #include "SkFontMgr.h"
12 #include "SkFontStyle.h"
13 #include "SkStream.h"
14 #include "SkTDArray.h"
15 #include "SkTSearch.h"
16 #include "SkTypeface.h"
17 #include "SkTypeface_android.h"
18 #include "SkTypefaceCache.h"
19
20 #include <limits>
21 #include <stdlib.h>
22
23 #ifndef SK_FONT_FILE_PREFIX
24 #    define SK_FONT_FILE_PREFIX "/fonts/"
25 #endif
26
27 #ifndef SK_DEBUG_FONTS
28     #define SK_DEBUG_FONTS 0
29 #endif
30
31 #if SK_DEBUG_FONTS
32 #    define DEBUG_FONT(args) SkDebugf args
33 #else
34 #    define DEBUG_FONT(args)
35 #endif
36
37 // For test only.
38 static const char* gTestMainConfigFile = NULL;
39 static const char* gTestFallbackConfigFile = NULL;
40 static const char* gTestFontFilePrefix = NULL;
41
42 class SkTypeface_Android : public SkTypeface_FreeType {
43 public:
44     SkTypeface_Android(int index,
45                        Style style,
46                        bool isFixedPitch,
47                        const SkString familyName)
48         : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
49         , fIndex(index)
50         , fFamilyName(familyName) { }
51
52 protected:
53     virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
54         *familyName = fFamilyName;
55     }
56
57     int fIndex;
58     SkString fFamilyName;
59
60 private:
61     typedef SkTypeface_FreeType INHERITED;
62 };
63
64 class SkTypeface_AndroidSystem : public SkTypeface_Android {
65 public:
66     SkTypeface_AndroidSystem(const SkString pathName,
67                              int index,
68                              Style style,
69                              bool isFixedPitch,
70                              const SkString familyName,
71                              const SkLanguage& lang,
72                              FontVariant variantStyle)
73         : INHERITED(index, style, isFixedPitch, familyName)
74         , fPathName(pathName)
75         , fLang(lang)
76         , fVariantStyle(variantStyle) { }
77
78     virtual void onGetFontDescriptor(SkFontDescriptor* desc,
79                                      bool* serialize) const SK_OVERRIDE {
80         SkASSERT(desc);
81         SkASSERT(serialize);
82         desc->setFamilyName(fFamilyName.c_str());
83         desc->setFontFileName(fPathName.c_str());
84         desc->setFontIndex(fIndex);
85         *serialize = false;
86     }
87     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
88         *ttcIndex = fIndex;
89         return SkStream::NewFromFile(fPathName.c_str());
90     }
91
92     const SkString fPathName;
93     const SkLanguage fLang;
94     const FontVariant fVariantStyle;
95
96     typedef SkTypeface_Android INHERITED;
97 };
98
99 class SkTypeface_AndroidStream : public SkTypeface_Android {
100 public:
101     SkTypeface_AndroidStream(SkStream* stream,
102                              int index,
103                              Style style,
104                              bool isFixedPitch,
105                              const SkString familyName)
106         : INHERITED(index, style, isFixedPitch, familyName)
107         , fStream(SkRef(stream)) { }
108
109     virtual void onGetFontDescriptor(SkFontDescriptor* desc,
110                                      bool* serialize) const SK_OVERRIDE {
111         SkASSERT(desc);
112         SkASSERT(serialize);
113         desc->setFamilyName(fFamilyName.c_str());
114         desc->setFontFileName(NULL);
115         *serialize = true;
116     }
117
118     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
119         *ttcIndex = fIndex;
120         return fStream->duplicate();
121     }
122
123 private:
124     SkAutoTUnref<SkStream> fStream;
125
126     typedef SkTypeface_Android INHERITED;
127 };
128
129 void get_path_for_sys_fonts(const char* basePath, const SkString& name, SkString* full) {
130     if (basePath) {
131         full->set(basePath);
132     } else {
133         full->set(getenv("ANDROID_ROOT"));
134         full->append(SK_FONT_FILE_PREFIX);
135     }
136     full->append(name);
137 }
138
139 class SkFontStyleSet_Android : public SkFontStyleSet {
140 public:
141     explicit SkFontStyleSet_Android(const FontFamily& family, const char* basePath) {
142         const SkString* cannonicalFamilyName = NULL;
143         if (family.fNames.count() > 0) {
144             cannonicalFamilyName = &family.fNames[0];
145         }
146         // TODO? make this lazy
147         for (int i = 0; i < family.fFonts.count(); ++i) {
148             const FontFileInfo& fontFile = family.fFonts[i];
149
150             SkString pathName;
151             get_path_for_sys_fonts(basePath, fontFile.fFileName, &pathName);
152
153             SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str()));
154             if (!stream.get()) {
155                 DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, pathName.c_str()));
156                 continue;
157             }
158
159             const int ttcIndex = fontFile.fIndex;
160             SkString familyName;
161             SkTypeface::Style style;
162             bool isFixedWidth;
163             if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex,
164                                                &familyName, &style, &isFixedWidth)) {
165                 DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, pathName.c_str()));
166                 continue;
167             }
168
169             const SkLanguage& lang = family.fLanguage;
170             uint32_t variant = family.fVariant;
171             if (kDefault_FontVariant == variant) {
172                 variant = kCompact_FontVariant | kElegant_FontVariant;
173             }
174
175             // The first specified family name overrides the family name found in the font.
176             // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return
177             // all of the specified family names in addition to the names found in the font.
178             if (cannonicalFamilyName != NULL) {
179                 familyName = *cannonicalFamilyName;
180             }
181
182             fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem,
183                                                  (pathName, ttcIndex,
184                                                   style, isFixedWidth, familyName,
185                                                   lang, variant)));
186         }
187     }
188
189     virtual int count() SK_OVERRIDE {
190         return fStyles.count();
191     }
192     virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVERRIDE {
193         if (index < 0 || fStyles.count() <= index) {
194             return;
195         }
196         if (style) {
197             *style = this->style(index);
198         }
199         if (name) {
200             name->reset();
201         }
202     }
203     virtual SkTypeface_AndroidSystem* createTypeface(int index) SK_OVERRIDE {
204         if (index < 0 || fStyles.count() <= index) {
205             return NULL;
206         }
207         return SkRef(fStyles[index].get());
208     }
209
210     /** Find the typeface in this style set that most closely matches the given pattern.
211      *  TODO: consider replacing with SkStyleSet_Indirect::matchStyle();
212      *  this simpler version using match_score() passes all our tests.
213      */
214     virtual SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE {
215         if (0 == fStyles.count()) {
216             return NULL;
217         }
218         SkTypeface_AndroidSystem* closest = fStyles[0];
219         int minScore = std::numeric_limits<int>::max();
220         for (int i = 0; i < fStyles.count(); ++i) {
221             SkFontStyle style = this->style(i);
222             int score = match_score(pattern, style);
223             if (score < minScore) {
224                 closest = fStyles[i];
225                 minScore = score;
226             }
227         }
228         return SkRef(closest);
229     }
230
231 private:
232     SkFontStyle style(int index) {
233         return SkFontStyle(this->weight(index), SkFontStyle::kNormal_Width,
234                            this->slant(index));
235     }
236     SkFontStyle::Weight weight(int index) {
237         if (fStyles[index]->isBold()) return SkFontStyle::kBold_Weight;
238         return SkFontStyle::kNormal_Weight;
239     }
240     SkFontStyle::Slant slant(int index) {
241         if (fStyles[index]->isItalic()) return SkFontStyle::kItalic_Slant;
242         return SkFontStyle::kUpright_Slant;
243     }
244     static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) {
245         int score = 0;
246         score += abs((pattern.width() - candidate.width()) * 100);
247         score += abs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000);
248         score += abs(pattern.weight() - candidate.weight());
249         return score;
250     }
251
252     SkTArray<SkAutoTUnref<SkTypeface_AndroidSystem>, true> fStyles;
253
254     friend struct NameToFamily;
255     friend class SkFontMgr_Android;
256
257     typedef SkFontStyleSet INHERITED;
258 };
259
260 /** On Android a single family can have many names, but our API assumes unique names.
261  *  Map names to the back end so that all names for a given family refer to the same
262  *  (non-replicated) set of typefaces.
263  *  SkTDict<> doesn't let us do index-based lookup, so we write our own mapping.
264  */
265 struct NameToFamily {
266     SkString name;
267     SkFontStyleSet_Android* styleSet;
268 };
269
270 class SkFontMgr_Android : public SkFontMgr {
271 public:
272     SkFontMgr_Android() {
273         SkTDArray<FontFamily*> fontFamilies;
274         SkFontConfigParser::GetFontFamilies(fontFamilies);
275         this->buildNameToFamilyMap(fontFamilies, NULL);
276         this->findDefaultFont();
277     }
278     SkFontMgr_Android(const char* mainConfigFile, const char* fallbackConfigFile,
279                       const char* basePath)
280     {
281         SkTDArray<FontFamily*> fontFamilies;
282         SkFontConfigParser::GetTestFontFamilies(fontFamilies, mainConfigFile, fallbackConfigFile);
283         this->buildNameToFamilyMap(fontFamilies, basePath);
284         this->findDefaultFont();
285     }
286
287 protected:
288     /** Returns not how many families we have, but how many unique names
289      *  exist among the families.
290      */
291     virtual int onCountFamilies() const SK_OVERRIDE {
292         return fNameToFamilyMap.count();
293     }
294
295     virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
296         if (index < 0 || fNameToFamilyMap.count() <= index) {
297             familyName->reset();
298             return;
299         }
300         familyName->set(fNameToFamilyMap[index].name);
301     }
302
303     virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE {
304         if (index < 0 || fNameToFamilyMap.count() <= index) {
305             return NULL;
306         }
307         return SkRef(fNameToFamilyMap[index].styleSet);
308     }
309
310     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
311         if (!familyName) {
312             return NULL;
313         }
314         SkAutoAsciiToLC tolc(familyName);
315         for (int i = 0; i < fNameToFamilyMap.count(); ++i) {
316             if (fNameToFamilyMap[i].name.equals(tolc.lc())) {
317                 return SkRef(fNameToFamilyMap[i].styleSet);
318             }
319         }
320         // TODO: eventually we should not need to name fallback families.
321         for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) {
322             if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) {
323                 return SkRef(fFallbackNameToFamilyMap[i].styleSet);
324             }
325         }
326         return NULL;
327     }
328
329     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
330                                            const SkFontStyle& style) const SK_OVERRIDE {
331         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
332         return sset->matchStyle(style);
333     }
334
335     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
336                                          const SkFontStyle& style) const SK_OVERRIDE {
337         for (int i = 0; i < fFontStyleSets.count(); ++i) {
338             for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) {
339                 if (fFontStyleSets[i]->fStyles[j] == typeface) {
340                     return fFontStyleSets[i]->matchStyle(style);
341                 }
342             }
343         }
344         return NULL;
345     }
346
347     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
348                                                     const SkFontStyle& style,
349                                                     const char bpc47[],
350                                                     uint32_t character) const SK_OVERRIDE
351     {
352         // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'.
353         // The variant 'default' means 'compact and elegant'.
354         // As a result, it is not possible to know the variant context from the font alone.
355         // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request.
356
357         // For compatibility, try 'elegant' fonts first in fallback.
358         uint32_t variantMask = kElegant_FontVariant;
359
360         // The first time match anything in the mask, second time anything not in the mask.
361         for (bool maskMatches = true; maskMatches != false; maskMatches = false) {
362             SkLanguage lang(bpc47);
363             // Match against the language, removing a segment each time.
364             // The last time through the loop, the language will be empty.
365             // The empty language is special, and matches all languages.
366             do {
367                 const SkString& langTag = lang.getTag();
368                 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) {
369                     SkFontStyleSet_Android* family = fFallbackNameToFamilyMap[i].styleSet;
370                     SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style));
371
372                     if (!langTag.isEmpty() && langTag != face->fLang.getTag()) {
373                         continue;
374                     }
375
376                     if (SkToBool(face->fVariantStyle & variantMask) != maskMatches) {
377                         continue;
378                     }
379
380                     SkPaint paint;
381                     paint.setTypeface(face);
382                     paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
383
384                     uint16_t glyphID;
385                     paint.textToGlyphs(&character, sizeof(character), &glyphID);
386                     if (glyphID != 0) {
387                         return face.detach();
388                     }
389                 }
390             } while (!lang.getTag().isEmpty() && (lang = lang.getParent(), true));
391         }
392         return NULL;
393     }
394
395     virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
396         SkAutoTUnref<SkStream> stream(new SkMemoryStream(data));
397         return this->createFromStream(stream, ttcIndex);
398     }
399
400     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
401         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
402         return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL;
403     }
404
405     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
406         bool isFixedPitch;
407         SkTypeface::Style style;
408         SkString name;
409         if (!SkTypeface_FreeType::ScanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) {
410             return NULL;
411         }
412         return SkNEW_ARGS(SkTypeface_AndroidStream, (stream, ttcIndex,
413                                                      style, isFixedPitch, name));
414     }
415
416
417     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
418                                                unsigned styleBits) const SK_OVERRIDE {
419         SkTypeface::Style oldStyle = (SkTypeface::Style)styleBits;
420         SkFontStyle style = SkFontStyle(oldStyle & SkTypeface::kBold
421                                                  ? SkFontStyle::kBold_Weight
422                                                  : SkFontStyle::kNormal_Weight,
423                                         SkFontStyle::kNormal_Width,
424                                         oldStyle & SkTypeface::kItalic
425                                                  ? SkFontStyle::kItalic_Slant
426                                                  : SkFontStyle::kUpright_Slant);
427
428         if (familyName) {
429             // On Android, we must return NULL when we can't find the requested
430             // named typeface so that the system/app can provide their own recovery
431             // mechanism. On other platforms we'd provide a typeface from the
432             // default family instead.
433             return this->onMatchFamilyStyle(familyName, style);
434         }
435         return fDefaultFamily->matchStyle(style);
436     }
437
438
439 private:
440
441     SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets;
442     SkFontStyleSet* fDefaultFamily;
443     SkTypeface* fDefaultTypeface;
444
445     SkTDArray<NameToFamily> fNameToFamilyMap;
446     SkTDArray<NameToFamily> fFallbackNameToFamilyMap;
447
448     void buildNameToFamilyMap(SkTDArray<FontFamily*> families, const char* basePath) {
449         for (int i = 0; i < families.count(); i++) {
450             FontFamily& family = *families[i];
451
452             SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap;
453             if (family.fIsFallbackFont) {
454                 nameToFamily = &fFallbackNameToFamilyMap;
455
456                 if (0 == family.fNames.count()) {
457                     SkString& fallbackName = family.fNames.push_back();
458                     fallbackName.printf("%.2x##fallback", i);
459                 }
460             }
461
462             SkFontStyleSet_Android* newSet = SkNEW_ARGS(SkFontStyleSet_Android, (family, basePath));
463             if (0 == newSet->count()) {
464                 SkDELETE(newSet);
465                 continue;
466             }
467             fFontStyleSets.push_back().reset(newSet);
468
469             for (int j = 0; j < family.fNames.count(); j++) {
470                 NameToFamily* nextEntry = nameToFamily->append();
471                 SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (family.fNames[j]));
472                 nextEntry->styleSet = newSet;
473             }
474         }
475     }
476
477     void findDefaultFont() {
478         SkASSERT(!fFontStyleSets.empty());
479
480         static const char* gDefaultNames[] = { "sans-serif" };
481         for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) {
482             SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]);
483             if (NULL == set) {
484                 continue;
485             }
486             SkTypeface* tf = set->matchStyle(SkFontStyle());
487             if (NULL == tf) {
488                 continue;
489             }
490             fDefaultFamily = set;
491             fDefaultTypeface = tf;
492             break;
493         }
494         if (NULL == fDefaultTypeface) {
495             fDefaultFamily = fFontStyleSets[0];
496             fDefaultTypeface = fDefaultFamily->createTypeface(0);
497         }
498         SkASSERT(fDefaultFamily);
499         SkASSERT(fDefaultTypeface);
500     }
501
502     typedef SkFontMgr INHERITED;
503 };
504
505 ///////////////////////////////////////////////////////////////////////////////
506
507 SkFontMgr* SkFontMgr::Factory() {
508     // The call to SkGetTestFontConfiguration is so that Chromium can override the environment.
509     // TODO: these globals need to be removed, in favor of a constructor / separate Factory
510     // which can be used instead.
511     const char* mainConfigFile;
512     const char* fallbackConfigFile;
513     const char* basePath;
514     SkGetTestFontConfiguration(&mainConfigFile, &fallbackConfigFile, &basePath);
515     if (mainConfigFile) {
516         return SkNEW_ARGS(SkFontMgr_Android, (mainConfigFile, fallbackConfigFile, basePath));
517     }
518
519     return SkNEW(SkFontMgr_Android);
520 }
521
522 void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf,
523                              const char* fontsdir) {
524     gTestMainConfigFile = mainconf;
525     gTestFallbackConfigFile = fallbackconf;
526     gTestFontFilePrefix = fontsdir;
527     SkASSERT(gTestMainConfigFile);
528     SkASSERT(gTestFallbackConfigFile);
529     SkASSERT(gTestFontFilePrefix);
530     SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s",
531               gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix));
532 }
533
534 void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf,
535                                 const char** fontsdir) {
536     *mainconf = gTestMainConfigFile;
537     *fallbackconf = gTestFallbackConfigFile;
538     *fontsdir = gTestFontFilePrefix;
539 }