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 |