OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkFontConfigParser_android.h" | 8 #include "SkFontConfigParser_android.h" |
9 #include "SkFontDescriptor.h" | 9 #include "SkFontDescriptor.h" |
10 #include "SkFontHost_FreeType_common.h" | 10 #include "SkFontHost_FreeType_common.h" |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 if (fFontStyleSets[i]->fStyles[j] == typeface) { | 339 if (fFontStyleSets[i]->fStyles[j] == typeface) { |
340 return fFontStyleSets[i]->matchStyle(style); | 340 return fFontStyleSets[i]->matchStyle(style); |
341 } | 341 } |
342 } | 342 } |
343 } | 343 } |
344 return NULL; | 344 return NULL; |
345 } | 345 } |
346 | 346 |
347 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], | 347 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
348 const SkFontStyle& style, | 348 const SkFontStyle& style, |
349 const char bpc47[], | 349 const char* bcp47[], |
350 uint32_t character) const SK
_OVERRIDE | 350 int bcpLength, |
| 351 SkUnichar character) const S
K_OVERRIDE |
351 { | 352 { |
352 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascen
t/descent'. | 353 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascen
t/descent'. |
353 // The variant 'default' means 'compact and elegant'. | 354 // 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 // 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 // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request. |
356 | 357 |
357 // For compatibility, try 'elegant' fonts first in fallback. | 358 // For compatibility, try 'elegant' fonts first in fallback. |
358 uint32_t variantMask = kElegant_FontVariant; | 359 uint32_t variantMask = kElegant_FontVariant; |
359 | 360 |
360 // The first time match anything in the mask, second time anything not i
n the mask. | 361 // The first time match anything in the mask, second time anything not i
n the mask. |
361 for (bool maskMatches = true; maskMatches != false; maskMatches = false)
{ | 362 for (bool maskMatches = true; maskMatches != false; maskMatches = false)
{ |
362 SkLanguage lang(bpc47); | 363 int bcpNext = 1; |
| 364 SkLanguage lang((bcpLength > 0) ? bcp47[0] : NULL); |
363 // Match against the language, removing a segment each time. | 365 // Match against the language, removing a segment each time. |
364 // The last time through the loop, the language will be empty. | 366 // The last time through the loop, the language will be empty. |
365 // The empty language is special, and matches all languages. | 367 // The empty language is special, and matches all languages. |
366 do { | 368 bool searchComplete = false; |
| 369 while (!searchComplete) { |
367 const SkString& langTag = lang.getTag(); | 370 const SkString& langTag = lang.getTag(); |
368 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { | 371 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { |
369 SkFontStyleSet_Android* family = fFallbackNameToFamilyMap[i]
.styleSet; | 372 SkFontStyleSet_Android* family = fFallbackNameToFamilyMap[i]
.styleSet; |
370 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchSty
le(style)); | 373 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchSty
le(style)); |
371 | 374 |
372 if (!langTag.isEmpty() && langTag != face->fLang.getTag()) { | 375 if (!langTag.isEmpty() && langTag != face->fLang.getTag()) { |
373 continue; | 376 continue; |
374 } | 377 } |
375 | 378 |
376 if (SkToBool(face->fVariantStyle & variantMask) != maskMatch
es) { | 379 if (SkToBool(face->fVariantStyle & variantMask) != maskMatch
es) { |
377 continue; | 380 continue; |
378 } | 381 } |
379 | 382 |
380 SkPaint paint; | 383 SkPaint paint; |
381 paint.setTypeface(face); | 384 paint.setTypeface(face); |
382 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); | 385 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); |
383 | 386 |
384 uint16_t glyphID; | 387 uint16_t glyphID; |
385 paint.textToGlyphs(&character, sizeof(character), &glyphID); | 388 paint.textToGlyphs(&character, sizeof(character), &glyphID); |
386 if (glyphID != 0) { | 389 if (glyphID != 0) { |
387 return face.detach(); | 390 return face.detach(); |
388 } | 391 } |
389 } | 392 } |
390 } while (!lang.getTag().isEmpty() && (lang = lang.getParent(), true)
); | 393 |
| 394 if (!langTag.isEmpty()) { |
| 395 lang = lang.getParent(); |
| 396 // move onto the next language tag until we exhaust them and |
| 397 // only then fall through to the default case (i.e. empty la
ng). |
| 398 if (lang.getTag().isEmpty() && bcpNext < bcpLength) { |
| 399 lang.set(bcp47[bcpNext++]); |
| 400 } |
| 401 } else { |
| 402 searchComplete = true; |
| 403 } |
| 404 } |
391 } | 405 } |
392 return NULL; | 406 return NULL; |
393 } | 407 } |
394 | 408 |
395 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV
ERRIDE { | 409 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV
ERRIDE { |
396 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); | 410 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); |
397 return this->createFromStream(stream, ttcIndex); | 411 return this->createFromStream(stream, ttcIndex); |
398 } | 412 } |
399 | 413 |
400 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const
SK_OVERRIDE { | 414 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const
SK_OVERRIDE { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s", | 544 SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s", |
531 gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix)
); | 545 gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix)
); |
532 } | 546 } |
533 | 547 |
534 void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf
, | 548 void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf
, |
535 const char** fontsdir) { | 549 const char** fontsdir) { |
536 *mainconf = gTestMainConfigFile; | 550 *mainconf = gTestMainConfigFile; |
537 *fallbackconf = gTestFallbackConfigFile; | 551 *fallbackconf = gTestFallbackConfigFile; |
538 *fontsdir = gTestFontFilePrefix; | 552 *fontsdir = gTestFontFilePrefix; |
539 } | 553 } |
OLD | NEW |