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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 for (int i = 0; i < fFontStyleSets.count(); ++i) { | 337 for (int i = 0; i < fFontStyleSets.count(); ++i) { |
338 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { | 338 for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) { |
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 static SkTypeface_AndroidSystem* find_family_style_character( |
| 348 const SkTDArray<NameToFamily>& fallbackNameToFamilyMap, |
| 349 const SkFontStyle& style, bool elegant, |
| 350 const SkString& langTag, SkUnichar character) |
| 351 { |
| 352 for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) { |
| 353 SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet; |
| 354 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style)); |
| 355 |
| 356 if (!langTag.isEmpty() && langTag != face->fLang.getTag()) { |
| 357 continue; |
| 358 } |
| 359 |
| 360 if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) { |
| 361 continue; |
| 362 } |
| 363 |
| 364 SkPaint paint; |
| 365 paint.setTypeface(face); |
| 366 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); |
| 367 |
| 368 uint16_t glyphID; |
| 369 paint.textToGlyphs(&character, sizeof(character), &glyphID); |
| 370 if (glyphID != 0) { |
| 371 return face.detach(); |
| 372 } |
| 373 } |
| 374 return NULL; |
| 375 } |
| 376 #ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER |
347 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], | 377 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
348 const SkFontStyle& style, | 378 const SkFontStyle& style, |
349 const char bpc47[], | 379 const char* bcp47[], |
350 uint32_t character) const SK
_OVERRIDE | 380 int bcp47Count, |
| 381 SkUnichar character) const S
K_OVERRIDE |
351 { | 382 { |
| 383 #else |
| 384 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
| 385 const SkFontStyle& style, |
| 386 const char bcp47_val[], |
| 387 SkUnichar character) const S
K_OVERRIDE |
| 388 { |
| 389 const char** bcp47 = &bcp47_val; |
| 390 int bcp47Count = bcp47_val ? 1 : 0; |
| 391 #endif |
352 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascen
t/descent'. | 392 // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascen
t/descent'. |
353 // The variant 'default' means 'compact and elegant'. | 393 // The variant 'default' means 'compact and elegant'. |
354 // As a result, it is not possible to know the variant context from the
font alone. | 394 // 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. | 395 // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request. |
356 | 396 |
357 // For compatibility, try 'elegant' fonts first in fallback. | 397 // The first time match anything elegant, second time anything not elega
nt. |
358 uint32_t variantMask = kElegant_FontVariant; | 398 for (int elegant = 2; elegant --> 0;) { |
359 | 399 for (int bcp47Index = bcp47Count; bcp47Index --> 0;) { |
360 // The first time match anything in the mask, second time anything not i
n the mask. | 400 SkLanguage lang(bcp47[bcp47Index]); |
361 for (bool maskMatches = true; maskMatches != false; maskMatches = false)
{ | 401 while (!lang.getTag().isEmpty()) { |
362 SkLanguage lang(bpc47); | 402 SkTypeface_AndroidSystem* matchingTypeface = |
363 // Match against the language, removing a segment each time. | 403 find_family_style_character(fFallbackNameToFamilyMap, |
364 // The last time through the loop, the language will be empty. | 404 style, SkToBool(elegant), |
365 // The empty language is special, and matches all languages. | 405 lang.getTag(), character); |
366 do { | 406 if (matchingTypeface) { |
367 const SkString& langTag = lang.getTag(); | 407 return matchingTypeface; |
368 for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { | |
369 SkFontStyleSet_Android* family = fFallbackNameToFamilyMap[i]
.styleSet; | |
370 SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchSty
le(style)); | |
371 | |
372 if (!langTag.isEmpty() && langTag != face->fLang.getTag()) { | |
373 continue; | |
374 } | 408 } |
375 | 409 |
376 if (SkToBool(face->fVariantStyle & variantMask) != maskMatch
es) { | 410 lang = lang.getParent(); |
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 } | 411 } |
390 } while (!lang.getTag().isEmpty() && (lang = lang.getParent(), true)
); | 412 } |
| 413 SkTypeface_AndroidSystem* matchingTypeface = |
| 414 find_family_style_character(fFallbackNameToFamilyMap, |
| 415 style, SkToBool(elegant), |
| 416 SkString(), character); |
| 417 if (matchingTypeface) { |
| 418 return matchingTypeface; |
| 419 } |
391 } | 420 } |
392 return NULL; | 421 return NULL; |
393 } | 422 } |
394 | 423 |
395 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV
ERRIDE { | 424 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV
ERRIDE { |
396 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); | 425 SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); |
397 return this->createFromStream(stream, ttcIndex); | 426 return this->createFromStream(stream, ttcIndex); |
398 } | 427 } |
399 | 428 |
400 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const
SK_OVERRIDE { | 429 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const
SK_OVERRIDE { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s", | 552 SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s", |
524 gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix)
); | 553 gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix)
); |
525 } | 554 } |
526 | 555 |
527 void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf
, | 556 void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf
, |
528 const char** fontsdir) { | 557 const char** fontsdir) { |
529 *mainconf = gTestMainConfigFile; | 558 *mainconf = gTestMainConfigFile; |
530 *fallbackconf = gTestFallbackConfigFile; | 559 *fallbackconf = gTestFallbackConfigFile; |
531 *fontsdir = gTestFontFilePrefix; | 560 *fontsdir = gTestFontFilePrefix; |
532 } | 561 } |
OLD | NEW |