Bug 1533797 - Let freetype backend fall back to MS_SYMBOL if no UNICODE charmap is available. r=lsalzman
authorJonathan Kew <jkew@mozilla.com>
Fri, 10 May 2019 16:27:49 +0000
changeset 473432 ad447cf869e224bc25d024bff668abcd2b949b5a
parent 473431 633722f0bc3d0444d3b5f2227b7d14680897c88b
child 473433 ecf6843307fa68c647f15eca2344d9d34f079ce7
push id35996
push userdvarga@mozilla.com
push dateFri, 10 May 2019 21:46:48 +0000
treeherdermozilla-central@362df4629f8f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1533797
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1533797 - Let freetype backend fall back to MS_SYMBOL if no UNICODE charmap is available. r=lsalzman Differential Revision: https://phabricator.services.mozilla.com/D30625
gfx/2d/NativeFontResourceFreeType.cpp
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFT2Fonts.cpp
gfx/thebes/gfxFT2Utils.cpp
gfx/thebes/gfxFcPlatformFontList.cpp
--- a/gfx/2d/NativeFontResourceFreeType.cpp
+++ b/gfx/2d/NativeFontResourceFreeType.cpp
@@ -34,17 +34,18 @@ already_AddRefed<T> NativeFontResourceFr
   }
   memcpy(fontData.get(), aFontData, aDataLength);
 
   FT_Face face =
       Factory::NewFTFaceFromData(aFTLibrary, fontData.get(), aDataLength, 0);
   if (!face) {
     return nullptr;
   }
-  if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != FT_Err_Ok) {
+  if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != FT_Err_Ok &&
+      FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL) != FT_Err_Ok) {
     Factory::ReleaseFTFace(face);
     return nullptr;
   }
 
   RefPtr<T> resource = new T(std::move(fontData), aDataLength, face);
   return resource.forget();
 }
 
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -116,18 +116,19 @@ class AutoFTFace {
       }
     } else {
       mFace = Factory::NewFTFace(nullptr, aFontEntry->mFilename.get(),
                                  aFontEntry->mFTFontIndex);
       if (!mFace) {
         NS_WARNING("failed to create freetype face");
       }
     }
-    if (FT_Err_Ok != FT_Select_Charmap(mFace, FT_ENCODING_UNICODE)) {
-      NS_WARNING("failed to select Unicode charmap");
+    if (FT_Err_Ok != FT_Select_Charmap(mFace, FT_ENCODING_UNICODE) &&
+        FT_Err_Ok != FT_Select_Charmap(mFace, FT_ENCODING_MS_SYMBOL)) {
+      NS_WARNING("failed to select Unicode or symbol charmap");
     }
     mOwnsFace = true;
   }
 
   ~AutoFTFace() {
     if (mFace && mOwnsFace) {
       Factory::ReleaseFTFace(mFace);
       if (mFontDataBuf) {
@@ -263,17 +264,18 @@ FT2FontEntry* FT2FontEntry::CreateFontEn
   // Ownership of aFontData is passed in here; the fontEntry must
   // retain it as long as the FT_Face needs it, and ensure it is
   // eventually deleted.
   FT_Face face = Factory::NewFTFaceFromData(nullptr, aFontData, aLength, 0);
   if (!face) {
     free((void*)aFontData);
     return nullptr;
   }
-  if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE)) {
+  if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE) &&
+      FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL)) {
     Factory::ReleaseFTFace(face);
     free((void*)aFontData);
     return nullptr;
   }
   // Create our FT2FontEntry, which inherits the name of the userfont entry
   // as it's not guaranteed that the face has valid names (bug 737315)
   FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(face, nullptr, 0, aFontName,
                                                    aFontData, aLength);
@@ -1110,18 +1112,19 @@ void gfxFT2FontList::FindFontsInOmnijar(
   }
 }
 
 // Given the freetype face corresponding to an entryName and face index,
 // add the face to the available font list and to the faceList string
 void gfxFT2FontList::AddFaceToList(const nsCString& aEntryName, uint32_t aIndex,
                                    StandardFile aStdFile, FT_Face aFace,
                                    nsCString& aFaceList) {
-  if (FT_Err_Ok != FT_Select_Charmap(aFace, FT_ENCODING_UNICODE)) {
-    // ignore faces that don't support a Unicode charmap
+  if (FT_Err_Ok != FT_Select_Charmap(aFace, FT_ENCODING_UNICODE) &&
+      FT_Err_Ok != FT_Select_Charmap(aFace, FT_ENCODING_MS_SYMBOL)) {
+    // ignore faces that don't support a Unicode or symbol charmap
     return;
   }
 
   // build the font entry name and create an FT2FontEntry,
   // but do -not- keep a reference to the FT_Face
   RefPtr<FT2FontEntry> fe =
       CreateNamedFontEntry(aFace, aEntryName.get(), aIndex);
 
--- a/gfx/thebes/gfxFT2Fonts.cpp
+++ b/gfx/thebes/gfxFT2Fonts.cpp
@@ -178,18 +178,22 @@ already_AddRefed<ScaledFont> gfxFT2Font:
   }
 
   RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
   return scaledFont.forget();
 }
 
 void gfxFT2Font::FillGlyphDataForChar(FT_Face face, uint32_t ch,
                                       CachedGlyphData* gd) {
-  if (!face->charmap || face->charmap->encoding != FT_ENCODING_UNICODE) {
-    FT_Select_Charmap(face, FT_ENCODING_UNICODE);
+  if (!face->charmap || (face->charmap->encoding != FT_ENCODING_UNICODE &&
+                         face->charmap->encoding != FT_ENCODING_MS_SYMBOL)) {
+    if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE) &&
+        FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL)) {
+      NS_WARNING("failed to select Unicode or symbol charmap!");
+    }
   }
   FT_UInt gid = FT_Get_Char_Index(face, ch);
 
   if (gid == 0) {
     // this font doesn't support this char!
     NS_ASSERTION(gid != 0,
                  "We don't have a glyph, but font indicated that it supported "
                  "this char in tables?");
--- a/gfx/thebes/gfxFT2Utils.cpp
+++ b/gfx/thebes/gfxFT2Utils.cpp
@@ -19,21 +19,26 @@
 uint32_t gfxFT2LockedFace::GetGlyph(uint32_t aCharCode) {
   if (MOZ_UNLIKELY(!mFace)) return 0;
 
 #ifdef HAVE_FONTCONFIG_FCFREETYPE_H
   // FcFreeTypeCharIndex will search starting from the most recently
   // selected charmap.  This can cause non-determistic behavior when more
   // than one charmap supports a character but with different glyphs, as
   // with older versions of MS Gothic, for example.  Always prefer a Unicode
-  // charmap, if there is one.  (FcFreeTypeCharIndex usually does the
-  // appropriate Unicode conversion, but some fonts have non-Roman glyphs
-  // for FT_ENCODING_APPLE_ROMAN characters.)
-  if (!mFace->charmap || mFace->charmap->encoding != FT_ENCODING_UNICODE) {
-    FT_Select_Charmap(mFace, FT_ENCODING_UNICODE);
+  // charmap, if there is one; failing that, try MS_SYMBOL.
+  // (FcFreeTypeCharIndex usually does the appropriate Unicode conversion,
+  // but some fonts have non-Roman glyphs for FT_ENCODING_APPLE_ROMAN
+  // characters.)
+  if (!mFace->charmap || (mFace->charmap->encoding != FT_ENCODING_UNICODE &&
+                          mFace->charmap->encoding != FT_ENCODING_MS_SYMBOL)) {
+    if (FT_Err_Ok != FT_Select_Charmap(mFace, FT_ENCODING_UNICODE) &&
+        FT_Err_Ok != FT_Select_Charmap(mFace, FT_ENCODING_MS_SYMBOL)) {
+      NS_WARNING("failed to select Unicode or symbol charmap");
+    }
   }
 
   return FcFreeTypeCharIndex(mFace, aCharCode);
 #else
   return FT_Get_Char_Index(mFace, aCharCode);
 #endif
 }
 
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -1983,17 +1983,18 @@ gfxFontEntry* gfxFcPlatformFontList::Mak
     const nsACString& aFontName, WeightRange aWeightForEntry,
     StretchRange aStretchForEntry, SlantStyleRange aStyleForEntry,
     const uint8_t* aFontData, uint32_t aLength) {
   FT_Face face = Factory::NewFTFaceFromData(nullptr, aFontData, aLength, 0);
   if (!face) {
     free((void*)aFontData);
     return nullptr;
   }
-  if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE)) {
+  if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE) &&
+      FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL)) {
     Factory::ReleaseFTFace(face);
     free((void*)aFontData);
     return nullptr;
   }
 
   return new gfxFontconfigFontEntry(aFontName, aWeightForEntry,
                                     aStretchForEntry, aStyleForEntry, aFontData,
                                     aLength, face);