| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2013 The Android Open Source Project | 3 * Copyright 2013 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "SkFontConfigInterface.h" | 9 #include "SkFontConfigInterface.h" |
| 10 #include "SkTypeface_android.h" | 10 #include "SkTypeface_android.h" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 virtual SkDataTable* getFamilyNames() SK_OVERRIDE; | 91 virtual SkDataTable* getFamilyNames() SK_OVERRIDE; |
| 92 virtual bool matchFamilySet(const char inFamilyName[], | 92 virtual bool matchFamilySet(const char inFamilyName[], |
| 93 SkString* outFamilyName, | 93 SkString* outFamilyName, |
| 94 SkTArray<FontIdentity>*) SK_OVERRIDE; | 94 SkTArray<FontIdentity>*) SK_OVERRIDE; |
| 95 | 95 |
| 96 /** | 96 /** |
| 97 * Get the family name of the font in the default fallback font list that | 97 * Get the family name of the font in the default fallback font list that |
| 98 * contains the specified chararacter. if no font is found, returns false. | 98 * contains the specified chararacter. if no font is found, returns false. |
| 99 */ | 99 */ |
| 100 bool getFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString*
name); | 100 bool getFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString*
name); |
| 101 /** | |
| 102 * | |
| 103 */ | |
| 104 SkTypeface* nextLogicalTypeface(SkFontID currFontID, SkFontID origFontID, | |
| 105 const SkPaintOptionsAndroid& options); | |
| 106 SkTypeface* getTypefaceForGlyphID(uint16_t glyphID, const SkTypeface* origTy
peface, | |
| 107 const SkPaintOptionsAndroid& options, | |
| 108 int* lowerBounds, int* upperBounds); | |
| 109 | 101 |
| 110 private: | 102 private: |
| 111 void addFallbackFamily(FamilyRecID fontRecID); | 103 void addFallbackFamily(FamilyRecID fontRecID); |
| 112 SkTypeface* getTypefaceForFontRec(FontRecID fontRecID); | 104 SkTypeface* getTypefaceForFontRec(FontRecID fontRecID); |
| 113 FallbackFontList* getCurrentLocaleFallbackFontList(); | 105 FallbackFontList* getCurrentLocaleFallbackFontList(); |
| 114 FallbackFontList* findFallbackFontList(const SkLanguage& lang, bool isOrigin
al = true); | 106 FallbackFontList* findFallbackFontList(const SkLanguage& lang, bool isOrigin
al = true); |
| 115 | 107 |
| 116 SkTArray<FontRec, true> fFonts; | 108 SkTArray<FontRec, true> fFonts; |
| 117 SkTArray<FamilyRec, true> fFontFamilies; | 109 SkTArray<FamilyRec, true> fFontFamilies; |
| 118 SkTDict<FamilyRecID> fFamilyNameDict; | 110 SkTDict<FamilyRecID> fFamilyNameDict; |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 fallbackFontList = findFallbackFontList(parent, false); | 564 fallbackFontList = findFallbackFontList(parent, false); |
| 573 | 565 |
| 574 // cache the original lang so we don't have to do the recursion again. | 566 // cache the original lang so we don't have to do the recursion again. |
| 575 if (isOriginal) { | 567 if (isOriginal) { |
| 576 DEBUG_FONT(("---- Created fallback list alias for \"%s\"", langTag.c_st
r())); | 568 DEBUG_FONT(("---- Created fallback list alias for \"%s\"", langTag.c_st
r())); |
| 577 fFallbackFontAliasDict.set(langTag.c_str(), fallbackFontList); | 569 fFallbackFontAliasDict.set(langTag.c_str(), fallbackFontList); |
| 578 } | 570 } |
| 579 return fallbackFontList; | 571 return fallbackFontList; |
| 580 } | 572 } |
| 581 | 573 |
| 582 SkTypeface* SkFontConfigInterfaceAndroid::nextLogicalTypeface(SkFontID currFontI
D, | |
| 583 SkFontID origFontI
D, | |
| 584 const SkPaintOptio
nsAndroid& opts) { | |
| 585 // Skia does not support font fallback by default. This enables clients such | |
| 586 // as WebKit to customize their font selection. In any case, clients can use | |
| 587 // GetFallbackFamilyNameForChar() to get the fallback font for individual | |
| 588 // characters. | |
| 589 if (!opts.isUsingFontFallbacks()) { | |
| 590 return NULL; | |
| 591 } | |
| 592 | |
| 593 FallbackFontList* currentFallbackList = findFallbackFontList(opts.getLanguag
e()); | |
| 594 SkASSERT(currentFallbackList); | |
| 595 | |
| 596 SkTypeface::Style origStyle = SkTypeface::kNormal; | |
| 597 const SkTypeface* origTypeface = SkTypefaceCache::FindByID(origFontID); | |
| 598 if (NULL != origTypeface) { | |
| 599 origStyle = origTypeface->style(); | |
| 600 } | |
| 601 | |
| 602 // we must convert currTypeface into a FontRecID | |
| 603 FontRecID currFontRecID = INVALID_FONT_REC_ID; | |
| 604 const SkTypeface* currTypeface = SkTypefaceCache::FindByID(currFontID); | |
| 605 // non-system fonts are not in the font cache so if we are asked to fallback | |
| 606 // for a non-system font we will start at the front of the chain. | |
| 607 if (NULL != currTypeface) { | |
| 608 currFontRecID = ((FontConfigTypeface*)currTypeface)->getIdentity().fID; | |
| 609 SkASSERT(INVALID_FONT_REC_ID != currFontRecID); | |
| 610 } | |
| 611 | |
| 612 FamilyRecID currFamilyRecID = INVALID_FAMILY_REC_ID; | |
| 613 if (INVALID_FONT_REC_ID != currFontRecID) { | |
| 614 currFamilyRecID = fFonts[currFontRecID].fFamilyRecID; | |
| 615 } | |
| 616 | |
| 617 // lookup the index next font in the chain | |
| 618 int currFallbackFontIndex = currentFallbackList->find(currFamilyRecID); | |
| 619 // We add 1 to the returned index for 2 reasons: (1) if find succeeds it mov
es | |
| 620 // our index to the next entry in the list; (2) if find() fails it returns | |
| 621 // -1 and incrementing it will set our starting index to 0 (the head of the
list) | |
| 622 int nextFallbackFontIndex = currFallbackFontIndex + 1; | |
| 623 | |
| 624 if(nextFallbackFontIndex >= currentFallbackList->count()) { | |
| 625 return NULL; | |
| 626 } | |
| 627 | |
| 628 // If a rec object is set to prefer "kDefault_Variant" it means they have no
preference | |
| 629 // In this case, we set the value to "kCompact_Variant" | |
| 630 SkPaintOptionsAndroid::FontVariant variant = opts.getFontVariant(); | |
| 631 if (variant == SkPaintOptionsAndroid::kDefault_Variant) { | |
| 632 variant = SkPaintOptionsAndroid::kCompact_Variant; | |
| 633 } | |
| 634 | |
| 635 int32_t acceptedVariants = SkPaintOptionsAndroid::kDefault_Variant | variant
; | |
| 636 | |
| 637 SkTypeface* nextLogicalTypeface = 0; | |
| 638 while (nextFallbackFontIndex < currentFallbackList->count()) { | |
| 639 FamilyRecID familyRecID = currentFallbackList->getAt(nextFallbackFontInd
ex); | |
| 640 if ((fFontFamilies[familyRecID].fPaintOptions.getFontVariant() & accepte
dVariants) != 0) { | |
| 641 FontRecID matchedFont = find_best_style(fFontFamilies[familyRecID],
origStyle); | |
| 642 nextLogicalTypeface = this->getTypefaceForFontRec(matchedFont); | |
| 643 break; | |
| 644 } | |
| 645 nextFallbackFontIndex++; | |
| 646 } | |
| 647 | |
| 648 DEBUG_FONT(("---- nextLogicalFont: currFontID=%d, origFontID=%d, currRecID=%
d, " | |
| 649 "lang=%s, variant=%d, nextFallbackIndex[%d,%d] => nextLogicalTyp
eface=%d", | |
| 650 currFontID, origFontID, currFontRecID, opts.getLanguage().getTag
().c_str(), | |
| 651 variant, nextFallbackFontIndex, currentFallbackList->getAt(nextF
allbackFontIndex), | |
| 652 (nextLogicalTypeface) ? nextLogicalTypeface->uniqueID() : 0)); | |
| 653 return SkSafeRef(nextLogicalTypeface); | |
| 654 } | |
| 655 | |
| 656 SkTypeface* SkFontConfigInterfaceAndroid::getTypefaceForGlyphID(uint16_t glyphID
, | |
| 657 const SkTypeface
* origTypeface, | |
| 658 const SkPaintOpt
ionsAndroid& opts, | |
| 659 int* lBounds, in
t* uBounds) { | |
| 660 // If we aren't using fallbacks then we shouldn't be calling this | |
| 661 SkASSERT(opts.isUsingFontFallbacks()); | |
| 662 SkASSERT(origTypeface); | |
| 663 | |
| 664 SkTypeface* currentTypeface = NULL; | |
| 665 int lowerBounds = 0; //inclusive | |
| 666 int upperBounds = origTypeface->countGlyphs(); //exclusive | |
| 667 | |
| 668 // check to see if the glyph is in the bounds of the origTypeface | |
| 669 if (glyphID < upperBounds) { | |
| 670 currentTypeface = const_cast<SkTypeface*>(origTypeface); | |
| 671 } else { | |
| 672 FallbackFontList* currentFallbackList = findFallbackFontList(opts.getLan
guage()); | |
| 673 SkASSERT(currentFallbackList); | |
| 674 | |
| 675 // If an object is set to prefer "kDefault_Variant" it means they have n
o preference | |
| 676 // In this case, we set the value to "kCompact_Variant" | |
| 677 SkPaintOptionsAndroid::FontVariant variant = opts.getFontVariant(); | |
| 678 if (variant == SkPaintOptionsAndroid::kDefault_Variant) { | |
| 679 variant = SkPaintOptionsAndroid::kCompact_Variant; | |
| 680 } | |
| 681 | |
| 682 int32_t acceptedVariants = SkPaintOptionsAndroid::kDefault_Variant | var
iant; | |
| 683 SkTypeface::Style origStyle = origTypeface->style(); | |
| 684 | |
| 685 for (int x = 0; x < currentFallbackList->count(); ++x) { | |
| 686 const FamilyRecID familyRecID = currentFallbackList->getAt(x); | |
| 687 const SkPaintOptionsAndroid& familyOptions = fFontFamilies[familyRec
ID].fPaintOptions; | |
| 688 if ((familyOptions.getFontVariant() & acceptedVariants) != 0) { | |
| 689 FontRecID matchedFont = find_best_style(fFontFamilies[familyRecI
D], origStyle); | |
| 690 currentTypeface = this->getTypefaceForFontRec(matchedFont); | |
| 691 lowerBounds = upperBounds; | |
| 692 upperBounds += currentTypeface->countGlyphs(); | |
| 693 if (glyphID < upperBounds) { | |
| 694 break; | |
| 695 } | |
| 696 } | |
| 697 } | |
| 698 } | |
| 699 | |
| 700 if (NULL != currentTypeface) { | |
| 701 if (lBounds) { | |
| 702 *lBounds = lowerBounds; | |
| 703 } | |
| 704 if (uBounds) { | |
| 705 *uBounds = upperBounds; | |
| 706 } | |
| 707 } | |
| 708 return currentTypeface; | |
| 709 } | |
| 710 | |
| 711 /////////////////////////////////////////////////////////////////////////////// | 574 /////////////////////////////////////////////////////////////////////////////// |
| 712 | 575 |
| 713 bool SkGetFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString* n
ame) { | 576 bool SkGetFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString* n
ame) { |
| 714 SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface(); | 577 SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface(); |
| 715 return fontConfig->getFallbackFamilyNameForChar(uni, lang, name); | 578 return fontConfig->getFallbackFamilyNameForChar(uni, lang, name); |
| 716 } | 579 } |
| 717 | 580 |
| 718 void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf, | 581 void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf, |
| 719 const char* fontsdir) { | 582 const char* fontsdir) { |
| 720 gTestMainConfigFile = mainconf; | 583 gTestMainConfigFile = mainconf; |
| 721 gTestFallbackConfigFile = fallbackconf; | 584 gTestFallbackConfigFile = fallbackconf; |
| 722 gTestFontFilePrefix = fontsdir; | 585 gTestFontFilePrefix = fontsdir; |
| 723 SkASSERT(gTestMainConfigFile); | 586 SkASSERT(gTestMainConfigFile); |
| 724 SkASSERT(gTestFallbackConfigFile); | 587 SkASSERT(gTestFallbackConfigFile); |
| 725 SkASSERT(gTestFontFilePrefix); | 588 SkASSERT(gTestFontFilePrefix); |
| 726 SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s", | 589 SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s", |
| 727 gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix)
); | 590 gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix)
); |
| 728 } | 591 } |
| 729 | |
| 730 SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, SkFontID origFontI
D, | |
| 731 const SkPaintOptionsAndroid& options) { | |
| 732 SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface(); | |
| 733 return fontConfig->nextLogicalTypeface(currFontID, origFontID, options); | |
| 734 | |
| 735 } | |
| 736 | |
| 737 SkTypeface* SkGetTypefaceForGlyphID(uint16_t glyphID, const SkTypeface* origType
face, | |
| 738 const SkPaintOptionsAndroid& options, | |
| 739 int* lowerBounds, int* upperBounds) { | |
| 740 SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface(); | |
| 741 return fontConfig->getTypefaceForGlyphID(glyphID, origTypeface, options, | |
| 742 lowerBounds, upperBounds); | |
| 743 } | |
| OLD | NEW |