@@ -739,18 +739,18 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars
739739#endif
740740}
741741
742-
743- size_t TextLayoutShaper::shapeFontRun ( const SkPaint* paint, bool isRTL) {
744- // Reset kerning
745- mShaperItem . kerning_applied = false ;
746-
747- // Update Harfbuzz Shaper
748- mShaperItem . item . bidiLevel = isRTL;
749-
750- SkTypeface* typeface = paint-> getTypeface ();
751-
742+ /* *
743+ * Return the first typeface in the logical change, starting with this typeface,
744+ * that contains the specified unichar, or NULL if none is found.
745+ *
746+ * Note that this function does _not_ increment the reference count on the typeface, as the
747+ * assumption is that its lifetime is managed elsewhere - in particular, the fallback typefaces
748+ * for the default font live in a global cache.
749+ */
750+ SkTypeface* TextLayoutShaper::typefaceForUnichar ( const SkPaint* paint, SkTypeface* typeface,
751+ SkUnichar unichar, HB_Script script) {
752752 // Set the correct Typeface depending on the script
753- switch (mShaperItem . item . script ) {
753+ switch (script) {
754754 case HB_Script_Arabic:
755755 typeface = getCachedTypeface (&mArabicTypeface , TYPEFACE_ARABIC);
756756#if DEBUG_GLYPHS
@@ -815,32 +815,31 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
815815 break ;
816816
817817 default :
818- if (!typeface) {
819- typeface = mDefaultTypeface ;
820- #if DEBUG_GLYPHS
821- ALOGD (" Using Default Typeface" );
822- #endif
823- } else {
824818#if DEBUG_GLYPHS
819+ if (typeface) {
825820 ALOGD (" Using Paint Typeface" );
826- #endif
827821 }
822+ #endif
828823 break ;
829824 }
825+ return typeface;
826+ }
830827
831- mShapingPaint .setTypeface (typeface);
832- mShaperItem .face = getCachedHBFace (typeface);
828+ size_t TextLayoutShaper::shapeFontRun (const SkPaint* paint, bool isRTL) {
829+ // Reset kerning
830+ mShaperItem .kerning_applied = false ;
833831
834- # if DEBUG_GLYPHS
835- ALOGD ( " Run typeface = %p, uniqueID = %d, hb_face = %p " ,
836- typeface, typeface-> uniqueID (), mShaperItem . face );
837- # endif
832+ // Update Harfbuzz Shaper
833+ mShaperItem . item . bidiLevel = isRTL;
834+
835+ SkTypeface* typeface = paint-> getTypeface ();
838836
839837 // Get the glyphs base count for offsetting the glyphIDs returned by Harfbuzz
840838 // This is needed as the Typeface used for shaping can be not the default one
841839 // when we are shaping any script that needs to use a fallback Font.
842840 // If we are a "common" script we dont need to shift
843841 size_t baseGlyphCount = 0 ;
842+ SkUnichar firstUnichar = 0 ;
844843 switch (mShaperItem .item .script ) {
845844 case HB_Script_Arabic:
846845 case HB_Script_Hebrew:
@@ -850,7 +849,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
850849 case HB_Script_Thai:{
851850 const uint16_t * text16 = (const uint16_t *)(mShaperItem .string + mShaperItem .item .pos );
852851 const uint16_t * text16End = text16 + mShaperItem .item .length ;
853- SkUnichar firstUnichar = SkUTF16_NextUnichar (&text16);
852+ firstUnichar = SkUTF16_NextUnichar (&text16);
854853 while (firstUnichar == ' ' && text16 < text16End) {
855854 firstUnichar = SkUTF16_NextUnichar (&text16);
856855 }
@@ -861,6 +860,25 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
861860 break ;
862861 }
863862
863+ // We test the baseGlyphCount to see if the typeface supports the requested script
864+ if (baseGlyphCount != 0 ) {
865+ typeface = typefaceForUnichar (paint, typeface, firstUnichar, mShaperItem .item .script );
866+ }
867+
868+ if (!typeface) {
869+ typeface = mDefaultTypeface ;
870+ #if DEBUG_GLYPHS
871+ ALOGD (" Using Default Typeface" );
872+ #endif
873+ }
874+ mShapingPaint .setTypeface (typeface);
875+ mShaperItem .face = getCachedHBFace (typeface);
876+
877+ #if DEBUG_GLYPHS
878+ ALOGD (" Run typeface = %p, uniqueID = %d, hb_face = %p" ,
879+ typeface, typeface->uniqueID (), mShaperItem .face );
880+ #endif
881+
864882 // Shape
865883 assert (mShaperItem .item .length > 0 ); // Harfbuzz will overwrite other memory if length is 0.
866884 ensureShaperItemGlyphArrays (mShaperItem .item .length * 3 / 2 );
0 commit comments