Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/ports/SkFontConfigInterface_android.cpp

Issue 14731025: Add a fontConfig interface for android. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebasing Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/ports/SkTypeface_android.h ('k') | src/ports/SkFontConfigParser_android.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 /*
3 * Copyright 2013 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "SkFontConfigInterface.h"
10 #include "SkTypeface_android.h"
11
12 #include "SkFontConfigParser_android.h"
13 #include "SkFontConfigTypeface.h"
14 #include "SkFontMgr.h"
15 #include "SkGlyphCache.h"
16 #include "SkPaint.h"
17 #include "SkPaintOptionsAndroid.h"
18 #include "SkString.h"
19 #include "SkStream.h"
20 #include "SkThread.h"
21 #include "SkTypefaceCache.h"
22 #include "SkTArray.h"
23 #include "SkTDict.h"
24 #include "SkTSearch.h"
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #ifndef SK_DEBUG_FONTS
30 #define SK_DEBUG_FONTS 0
31 #endif
32
33 #if SK_DEBUG_FONTS
34 #define DEBUG_FONT(args) SkDebugf args
35 #else
36 #define DEBUG_FONT(args)
37 #endif
38
39 ///////////////////////////////////////////////////////////////////////////////
40
41 // For test only.
42 static const char* gTestMainConfigFile = NULL;
43 static const char* gTestFallbackConfigFile = NULL;
44 static const char* gTestFontFilePrefix = NULL;
45
46 ///////////////////////////////////////////////////////////////////////////////
47
48 // used to record our notion of the pre-existing fonts
49 struct FontRec {
50 SkRefPtr<SkTypeface> fTypeface;
51 SkString fFileName;
52 SkTypeface::Style fStyle;
53 SkPaintOptionsAndroid fPaintOptions;
54 bool fIsFallbackFont;
55 bool fIsValid;
56 };
57
58 typedef int32_t FontRecID;
59 #define INVALID_FONT_REC_ID -1
60
61 struct FamilyRec {
62 FamilyRec() {
63 memset(fFontRecID, INVALID_FONT_REC_ID, sizeof(fFontRecID));
64 }
65
66 static const int FONT_STYLE_COUNT = 4;
67 FontRecID fFontRecID[FONT_STYLE_COUNT];
68 };
69
70 typedef int32_t FamilyRecID;
71 #define INVALID_FAMILY_REC_ID -1
72
73 typedef SkTDArray<FontRecID> FallbackFontList;
74
75 class SkFontConfigInterfaceAndroid : public SkFontConfigInterface {
76 public:
77 SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*>& fontFamilies);
78 virtual ~SkFontConfigInterfaceAndroid();
79
80 virtual bool matchFamilyName(const char familyName[],
81 SkTypeface::Style requested,
82 FontIdentity* outFontIdentifier,
83 SkString* outFamilyName,
84 SkTypeface::Style* outStyle) SK_OVERRIDE;
85 virtual SkStream* openStream(const FontIdentity&) SK_OVERRIDE;
86
87 // new APIs
88 virtual SkDataTable* getFamilyNames() SK_OVERRIDE;
89 virtual bool matchFamilySet(const char inFamilyName[],
90 SkString* outFamilyName,
91 SkTArray<FontIdentity>*) SK_OVERRIDE;
92
93 /**
94 * Get the family name of the font in the default fallback font list that
95 * contains the specified chararacter. if no font is found, returns false.
96 */
97 bool getFallbackFamilyNameForChar(SkUnichar uni, SkString* name);
98 /**
99 *
100 */
101 SkTypeface* getTypefaceForChar(SkUnichar uni, SkTypeface::Style style,
102 SkPaintOptionsAndroid::FontVariant fontVarian t);
103 SkTypeface* nextLogicalTypeface(SkFontID currFontID, SkFontID origFontID,
104 const SkPaintOptionsAndroid& options);
105
106 private:
107 void addFallbackFont(FontRecID fontRecID);
108 FallbackFontList* findFallbackFontList(const SkLanguage& lang);
109
110 SkTArray<FontRec> fFonts;
111 SkTArray<FamilyRec> fFontFamilies;
112 SkTDict<FamilyRecID> fFamilyNameDict;
113 FamilyRecID fDefaultFamilyRecID;
114
115 // (SkLanguage)<->(fallback chain index) translation
116 SkTDict<FallbackFontList*> fFallbackFontDict;
117 FallbackFontList fDefaultFallbackList;
118 };
119
120 ///////////////////////////////////////////////////////////////////////////////
121
122 static SkFontConfigInterfaceAndroid* getSingletonInterface() {
123 SK_DECLARE_STATIC_MUTEX(gMutex);
124 static SkFontConfigInterfaceAndroid* gFontConfigInterface;
125
126 SkAutoMutexAcquire ac(gMutex);
127 if (NULL == gFontConfigInterface) {
128 // load info from a configuration file that we can use to populate the
129 // system/fallback font structures
130 SkTDArray<FontFamily*> fontFamilies;
131 if (!gTestMainConfigFile) {
132 SkFontConfigParser::GetFontFamilies(fontFamilies);
133 } else {
134 SkFontConfigParser::GetTestFontFamilies(fontFamilies, gTestMainConfi gFile,
135 gTestFallbackConfigFile);
136 }
137
138 gFontConfigInterface = new SkFontConfigInterfaceAndroid(fontFamilies);
139
140 // cleanup the data we received from the parser
141 fontFamilies.deleteAll();
142 }
143 return gFontConfigInterface;
144 }
145
146 SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface() {
147 return getSingletonInterface();
148 }
149
150 ///////////////////////////////////////////////////////////////////////////////
151
152 static bool has_font(const SkTArray<FontRec>& array, const SkString& filename) {
153 for (int i = 0; i < array.count(); i++) {
154 if (array[i].fFileName == filename) {
155 return true;
156 }
157 }
158 return false;
159 }
160
161 #ifndef SK_FONT_FILE_PREFIX
162 #define SK_FONT_FILE_PREFIX "/fonts/"
163 #endif
164
165 static void get_path_for_sys_fonts(SkString* full, const char name[]) {
166 if (gTestFontFilePrefix) {
167 full->set(gTestFontFilePrefix);
168 } else {
169 full->set(getenv("ANDROID_ROOT"));
170 full->append(SK_FONT_FILE_PREFIX);
171 }
172 full->append(name);
173 }
174
175 static void insert_into_name_dict(SkTDict<FamilyRecID>& familyNameDict,
176 const char* name, FamilyRecID familyRecID) {
177 SkAutoAsciiToLC tolc(name);
178 familyNameDict.set(tolc.lc(), familyRecID);
179 }
180
181 // Defined in SkFontHost_FreeType.cpp
182 bool find_name_and_attributes(SkStream* stream, SkString* name,
183 SkTypeface::Style* style, bool* isFixedWidth);
184
185 ///////////////////////////////////////////////////////////////////////////////
186
187 SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily* >& fontFamilies) :
188 fFonts(fontFamilies.count()),
189 fFontFamilies(fontFamilies.count() / FamilyRec::FONT_STYLE_COUNT),
190 fFamilyNameDict(1024),
191 fDefaultFamilyRecID(INVALID_FAMILY_REC_ID),
192 fFallbackFontDict(128) {
193
194 for (int i = 0; i < fontFamilies.count(); ++i) {
195 FontFamily* family = fontFamilies[i];
196
197 // defer initializing the familyRec until we can be sure that at least
198 // one of it's children contains a valid font file
199 FamilyRec* familyRec = NULL;
200 FamilyRecID familyRecID = INVALID_FAMILY_REC_ID;
201
202 for (int j = 0; j < family->fFontFiles.count(); ++j) {
203 SkString filename;
204 get_path_for_sys_fonts(&filename, family->fFontFiles[j]->fFileName);
205
206 if (has_font(fFonts, filename)) {
207 SkDebugf("---- system font and fallback font files specify a dup licate "
208 "font %s, skipping the second occurrence", filename.c_st r());
209 continue;
210 }
211
212 FontRec& fontRec = fFonts.push_back();
213 fontRec.fFileName = filename;
214 fontRec.fStyle = SkTypeface::kNormal;
215 fontRec.fPaintOptions = family->fFontFiles[j]->fPaintOptions;
216 fontRec.fIsFallbackFont = family->fIsFallbackFont;
217 fontRec.fIsValid = false;
218
219 const FontRecID fontRecID = fFonts.count() - 1;
220
221 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(filename.c_str() ));
222 if (stream.get() != NULL) {
223 bool isFixedWidth;
224 SkString name;
225 fontRec.fIsValid = find_name_and_attributes(stream.get(), &name,
226 &fontRec.fStyle, &is FixedWidth);
227 } else {
228 if (!fontRec.fIsFallbackFont) {
229 SkDebugf("---- failed to open <%s> as a font\n", filename.c_ str());
230 }
231 }
232
233 if (fontRec.fIsValid) {
234 DEBUG_FONT(("---- SystemFonts[%d][%d] fallback=%d file=%s",
235 i, fFonts.count() - 1, fontRec.fIsFallbackFont, filen ame.c_str()));
236 } else {
237 DEBUG_FONT(("---- SystemFonts[%d][%d] fallback=%d file=%s (INVAL ID)",
238 i, fFonts.count() - 1, fontRec.fIsFallbackFont, filen ame.c_str()));
239 continue;
240 }
241
242 // create a familyRec now that we know that at least one font in
243 // the family is valid
244 if (familyRec == NULL) {
245 familyRec = &fFontFamilies.push_back();
246 familyRecID = fFontFamilies.count() - 1;
247 }
248
249 // add this font to the current familyRec
250 if (INVALID_FONT_REC_ID != familyRec->fFontRecID[fontRec.fStyle]) {
251 DEBUG_FONT(("Overwriting familyRec for style[%d] old,new:(%d,%d) ",
252 fontRec.fStyle, familyRec->fFontRecID[fontRec.fStyle ],
253 fontRecID));
254 }
255 familyRec->fFontRecID[fontRec.fStyle] = fontRecID;
256
257 // if this is a fallback font then add it to the appropriate fallbac k chains
258 if (fontRec.fIsFallbackFont) {
259 addFallbackFont(fontRecID);
260 }
261
262 // add the fallback file name to the name dictionary. This is neede d
263 // by getFallbackFamilyNameForChar() so that fallback families can b e
264 // requested by the filenames of the fonts they contain.
265 if (family->fIsFallbackFont && familyRec) {
266 insert_into_name_dict(fFamilyNameDict, fontRec.fFileName.c_str() , familyRecID);
267 }
268 }
269
270 // add the names that map to this family to the dictionary for easy look up
271 if (familyRec && !family->fIsFallbackFont) {
272 SkTDArray<const char*> names = family->fNames;
273 if (names.isEmpty()) {
274 SkDEBUGFAIL("ERROR: non-fallback font with no name");
275 continue;
276 }
277
278 for (int i = 0; i < names.count(); i++) {
279 insert_into_name_dict(fFamilyNameDict, names[i], familyRecID);
280 }
281 }
282
283 }
284
285 DEBUG_FONT(("---- We have %d system fonts", fFonts.count()));
286
287 if (fFontFamilies.count() > 0) {
288 fDefaultFamilyRecID = 0;
289 }
290
291 // scans the default fallback font chain, adding every entry to every other
292 // fallback font chain to which it does not belong. this results in every
293 // language-specific fallback font chain having all of its fallback fonts at
294 // the front of the chain, and everything else at the end.
295 FallbackFontList* fallbackList;
296 SkTDict<FallbackFontList*>::Iter iter(fFallbackFontDict);
297 const char* fallbackLang = iter.next(&fallbackList);
298 while(fallbackLang != NULL) {
299 for (int i = 0; i < fDefaultFallbackList.count(); i++) {
300 FontRecID fontRecID = fDefaultFallbackList[i];
301 const SkString& fontLang = fFonts[fontRecID].fPaintOptions.getLangua ge().getTag();
302 if (strcmp(fallbackLang, fontLang.c_str()) != 0) {
303 fallbackList->push(fontRecID);
304 }
305 }
306 // move to the next fallback list in the dictionary
307 fallbackLang = iter.next(&fallbackList);
308 }
309 }
310
311 SkFontConfigInterfaceAndroid::~SkFontConfigInterfaceAndroid() {
312 // iterate through and cleanup fFallbackFontDict
313 SkTDict<FallbackFontList*>::Iter iter(fFallbackFontDict);
314 FallbackFontList* fallbackList;
315 while(iter.next(&fallbackList) != NULL) {
316 SkDELETE(fallbackList);
317 }
318 }
319
320 void SkFontConfigInterfaceAndroid::addFallbackFont(FontRecID fontRecID) {
321 SkASSERT(fontRecID < fFonts.count());
322 const FontRec& fontRec = fFonts[fontRecID];
323 SkASSERT(fontRec.fIsFallbackFont);
324
325 // add to the default fallback list
326 fDefaultFallbackList.push(fontRecID);
327
328 // stop here if it is the default language tag
329 const SkString& languageTag = fontRec.fPaintOptions.getLanguage().getTag();
330 if (languageTag.isEmpty()) {
331 return;
332 }
333
334 // add to the appropriate language's custom fallback list
335 FallbackFontList* customList = NULL;
336 if (!fFallbackFontDict.find(languageTag.c_str(), &customList)) {
337 DEBUG_FONT(("---- Created fallback list for \"%s\"", languageTag.c_str( )));
338 customList = SkNEW(FallbackFontList);
339 fFallbackFontDict.set(languageTag.c_str(), customList);
340 }
341 SkASSERT(customList != NULL);
342 customList->push(fontRecID);
343 }
344
345
346 static FontRecID find_best_style(const FamilyRec& family, SkTypeface::Style styl e) {
347
348 const FontRecID* fontRecIDs = family.fFontRecID;
349
350 if (fontRecIDs[style] != INVALID_FONT_REC_ID) { // exact match
351 return fontRecIDs[style];
352 }
353 // look for a matching bold
354 style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
355 if (fontRecIDs[style] != INVALID_FONT_REC_ID) {
356 return fontRecIDs[style];
357 }
358 // look for the plain
359 if (fontRecIDs[SkTypeface::kNormal] != INVALID_FONT_REC_ID) {
360 return fontRecIDs[SkTypeface::kNormal];
361 }
362 // look for anything
363 for (int i = 0; i < FamilyRec::FONT_STYLE_COUNT; i++) {
364 if (fontRecIDs[i] != INVALID_FONT_REC_ID) {
365 return fontRecIDs[i];
366 }
367 }
368 // should never get here, since the fontRecID list should not be empty
369 SkDEBUGFAIL("No valid fonts exist for this family");
370 return -1;
371 }
372
373 bool SkFontConfigInterfaceAndroid::matchFamilyName(const char familyName[],
374 SkTypeface::Style style,
375 FontIdentity* outFontIdentifi er,
376 SkString* outFamilyName,
377 SkTypeface::Style* outStyle) SK_OVERRIDE {
378 // clip to legal style bits
379 style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
380
381 bool exactNameMatch = false;
382
383 FamilyRecID familyRecID = INVALID_FAMILY_REC_ID;
384 if (NULL != familyName) {
385 if (fFamilyNameDict.find(familyName, &familyRecID)) {
386 exactNameMatch = true;
387 }
388 } else {
389 familyRecID = fDefaultFamilyRecID;
390
391 }
392
393 if (INVALID_FAMILY_REC_ID == familyRecID) {
394 //TODO this ensures that we always return something
395 familyRecID = fDefaultFamilyRecID;
396 //return false;
397 }
398
399 FontRecID fontRecID = find_best_style(fFontFamilies[familyRecID], style);
400 FontRec& fontRec = fFonts[fontRecID];
401
402 if (NULL != outFontIdentifier) {
403 outFontIdentifier->fID = fontRecID;
404 outFontIdentifier->fTTCIndex = 0;
405 outFontIdentifier->fString.set(fontRec.fFileName);
406 // outFontIdentifier->fStyle = fontRec.fStyle;
407 }
408
409 if (NULL != outFamilyName) {
410 if (exactNameMatch) {
411 outFamilyName->set(familyName);
412 } else {
413 // find familyName from list of names
414 const char* familyName = NULL;
415 bool found = fFamilyNameDict.findKey(familyRecID, &familyName);
416 SkASSERT(found && familyName);
417 outFamilyName->set(familyName);
418 }
419 }
420
421 if (NULL != outStyle) {
422 *outStyle = fontRec.fStyle;
423 }
424
425 return true;
426 }
427
428 SkStream* SkFontConfigInterfaceAndroid::openStream(const FontIdentity& identity) SK_OVERRIDE {
429 return SkStream::NewFromFile(identity.fString.c_str());
430 }
431
432 SkDataTable* SkFontConfigInterfaceAndroid::getFamilyNames() SK_OVERRIDE {
433 SkTDArray<const char*> names;
434 SkTDArray<size_t> sizes;
435
436 SkTDict<FamilyRecID>::Iter iter(fFamilyNameDict);
437 const char* familyName = iter.next(NULL);
438 while(familyName != NULL) {
439 *names.append() = familyName;
440 *sizes.append() = strlen(familyName) + 1;
441
442 // move to the next familyName in the dictionary
443 familyName = iter.next(NULL);
444 }
445
446 return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
447 sizes.begin(), names.count());
448 }
449
450 bool SkFontConfigInterfaceAndroid::matchFamilySet(const char inFamilyName[],
451 SkString* outFamilyName,
452 SkTArray<FontIdentity>*) SK_OV ERRIDE {
453 return false;
454 }
455
456 static SkTypeface* get_typeface_for_rec(FontRec& fontRec) {
457 SkTypeface* face = fontRec.fTypeface.get();
458 if (!face) {
459 // TODO look for it in the typeface cache
460
461 // if it is not in the cache then create it
462 face = SkTypeface::CreateFromFile(fontRec.fFileName.c_str());
463
464 // store the result for subsequent lookups
465 fontRec.fTypeface = face;
466 }
467 SkASSERT(face);
468 return face;
469 }
470
471 bool SkFontConfigInterfaceAndroid::getFallbackFamilyNameForChar(SkUnichar uni, S kString* name) {
472 for (int i = 0; i < fDefaultFallbackList.count(); i++) {
473 FontRecID fontRecID = fDefaultFallbackList[i];
474 SkTypeface* face = get_typeface_for_rec(fFonts[fontRecID]);
475
476 SkPaint paint;
477 paint.setTypeface(face);
478 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
479
480 uint16_t glyphID;
481 paint.textToGlyphs(&uni, sizeof(uni), &glyphID);
482 if (glyphID != 0) {
483 name->set(fFonts[fontRecID].fFileName);
484 return true;
485 }
486 }
487 return false;
488 }
489
490 SkTypeface* SkFontConfigInterfaceAndroid::getTypefaceForChar(SkUnichar uni,
491 SkTypeface::Style s tyle,
492 SkPaintOptionsAndro id::FontVariant fontVariant) {
493 FontRecID fontRecID = find_best_style(fFontFamilies[fDefaultFamilyRecID], st yle);
494 SkTypeface* face = get_typeface_for_rec(fFonts[fontRecID]);
495
496 SkPaintOptionsAndroid paintOptions;
497 paintOptions.setFontVariant(fontVariant);
498 paintOptions.setUseFontFallbacks(true);
499
500 SkPaint paint;
501 paint.setTypeface(face);
502 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
503 paint.setPaintOptionsAndroid(paintOptions);
504
505 SkAutoGlyphCache autoCache(paint, NULL, NULL);
506 SkGlyphCache* cache = autoCache.getCache();
507
508 SkScalerContext* ctx = cache->getScalerContext();
509 if (ctx) {
510 SkFontID fontID = ctx->findTypefaceIdForChar(uni);
511 return SkTypefaceCache::FindByID(fontID);
512 }
513 return NULL;
514 }
515
516 FallbackFontList* SkFontConfigInterfaceAndroid::findFallbackFontList(const SkLan guage& lang) {
517 const SkString& langTag = lang.getTag();
518 if (langTag.isEmpty()) {
519 return &fDefaultFallbackList;
520 }
521
522 FallbackFontList* fallbackFontList;
523 if (fFallbackFontDict.find(langTag.c_str(), langTag.size(), &fallbackFontLis t)) {
524 return fallbackFontList;
525 }
526
527 // attempt a recursive fuzzy match
528 // TODO we could cache the intermediate parent so that we don't have to do
529 // the recursion again.
530 SkLanguage parent = lang.getParent();
531 return findFallbackFontList(parent);
532 }
533
534 SkTypeface* SkFontConfigInterfaceAndroid::nextLogicalTypeface(SkFontID currFontI D,
535 SkFontID origFontI D,
536 const SkPaintOptio nsAndroid& opts) {
537 // Skia does not support font fallback by default. This enables clients such
538 // as WebKit to customize their font selection. In any case, clients can use
539 // GetFallbackFamilyNameForChar() to get the fallback font for individual
540 // characters.
541 if (!opts.isUsingFontFallbacks()) {
542 return NULL;
543 }
544
545 const SkTypeface* origTypeface = SkTypefaceCache::FindByID(origFontID);
546 const SkTypeface* currTypeface = SkTypefaceCache::FindByID(currFontID);
547
548 FallbackFontList* currentFallbackList = findFallbackFontList(opts.getLanguag e());
549 SkASSERT(currentFallbackList);
550
551 SkASSERT(origTypeface != 0);
552 SkASSERT(currTypeface != 0);
553
554 // we must convert currTypeface into a FontRecID
555 FontRecID currFontRecID = ((FontConfigTypeface*)currTypeface)->getIdentity() .fID;
556
557 // TODO lookup the index next font in the chain
558 int currFallbackFontIndex = currentFallbackList->find(currFontRecID);
559 int nextFallbackFontIndex = currFallbackFontIndex + 1;
560 SkASSERT(-1 == nextFallbackFontIndex);
561
562 if(nextFallbackFontIndex >= currentFallbackList->count() && -1 == currFallba ckFontIndex) {
563 return NULL;
564 }
565
566 // If a rec object is set to prefer "kDefault_Variant" it means they have no preference
567 // In this case, we set the value to "kCompact_Variant"
568 SkPaintOptionsAndroid::FontVariant variant = opts.getFontVariant();
569 if (variant == SkPaintOptionsAndroid::kDefault_Variant) {
570 variant = SkPaintOptionsAndroid::kCompact_Variant;
571 }
572
573 int32_t acceptedVariants = SkPaintOptionsAndroid::kDefault_Variant | variant ;
574
575 SkTypeface* nextLogicalTypeface = 0;
576 while (nextFallbackFontIndex < currentFallbackList->count()) {
577 FontRecID fontRecID = currentFallbackList->getAt(nextFallbackFontIndex);
578 if (fFonts[fontRecID].fPaintOptions.getFontVariant() & acceptedVariants) {
579 nextLogicalTypeface = get_typeface_for_rec(fFonts[fontRecID]);
580 break;
581 }
582 nextFallbackFontIndex++;
583 }
584
585 DEBUG_FONT(("---- nextLogicalFont: currFontID=%d, origFontID=%d, currRecID=% d, "
586 "lang=%s, variant=%d, nextFallbackIndex=%d => nextLogicalTypefac e=%d",
587 currFontID, origFontID, currFontRecID, opts.getLanguage().getTag ().c_str(),
588 variant, nextFallbackFontIndex,
589 (nextLogicalTypeface) ? nextLogicalTypeface->uniqueID() : 0));
590 return SkSafeRef(nextLogicalTypeface);
591 }
592
593 ///////////////////////////////////////////////////////////////////////////////
594
595 bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name) {
596 SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
597 return fontConfig->getFallbackFamilyNameForChar(uni, name);
598 }
599
600 void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf,
601 const char* fontsdir) {
602 gTestMainConfigFile = mainconf;
603 gTestFallbackConfigFile = fallbackconf;
604 gTestFontFilePrefix = fontsdir;
605 SkASSERT(gTestMainConfigFile);
606 SkASSERT(gTestFallbackConfigFile);
607 SkASSERT(gTestFontFilePrefix);
608 SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s",
609 gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix) );
610 }
611
612 SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, SkFontID origFontI D,
613 const SkPaintOptionsAndroid& options) {
614 SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
615 return fontConfig->nextLogicalTypeface(currFontID, origFontID, options);
616
617 }
618
619 ///////////////////////////////////////////////////////////////////////////////
620
621 SkFontMgr* SkFontMgr::Factory() {
622 return NULL;
623 }
OLDNEW
« no previous file with comments | « include/ports/SkTypeface_android.h ('k') | src/ports/SkFontConfigParser_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698