Bug 1500356 - Update gfxFont/gfxFontEntry to use new harfbuzz API in place of deprecated functions. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Sat, 08 Dec 2018 08:44:55 -0500
changeset 509302 27730939a1386619acfe4feb31e205977bde878a
parent 509301 2d077b8e0b5b7ecc9187e5e3cba1022955363d84
child 509303 51fa00bbe97e6553e67d8d85ae12e5cf98b4ba8b
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1500356
milestone66.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 1500356 - Update gfxFont/gfxFontEntry to use new harfbuzz API in place of deprecated functions. r=jrmuizel
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFontEntry.cpp
gfx/thebes/gfxFontEntry.h
gfx/thebes/gfxMacPlatformFontList.mm
gfx/thebes/gfxPlatformFontList.cpp
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -513,17 +513,17 @@ nsresult FT2FontEntry::ReadCMAP(FontInfo
     // for layout support, check for the presence of opentype layout tables
     bool hasGSUB = HasFontTable(TRUETYPE_TAG('G', 'S', 'U', 'B'));
 
     for (const ScriptRange* sr = gfxPlatformFontList::sComplexScriptRanges;
          sr->rangeStart; sr++) {
       // check to see if the cmap includes complex script codepoints
       if (charmap->TestRange(sr->rangeStart, sr->rangeEnd)) {
         // We check for GSUB here, as GPOS alone would not be ok.
-        if (hasGSUB && SupportsScriptInGSUB(sr->tags)) {
+        if (hasGSUB && SupportsScriptInGSUB(sr->tags, sr->numTags)) {
           continue;
         }
         charmap->ClearRange(sr->rangeStart, sr->rangeEnd);
       }
     }
   }
 
 #ifdef MOZ_WIDGET_ANDROID
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1138,22 +1138,24 @@ void gfxFont::CheckForFeaturesInvolvingS
       // Ensure that we don't try to look at script codes beyond what the
       // current version of ICU (at runtime -- in case of system ICU)
       // knows about.
       Script scriptCount =
           Script(std::min<int>(u_getIntPropertyMaxValue(UCHAR_SCRIPT) + 1,
                                int(Script::NUM_SCRIPT_CODES)));
       for (Script s = Script::ARABIC; s < scriptCount;
            s = Script(static_cast<int>(s) + 1)) {
-        hb_script_t scriptTag = hb_script_t(GetScriptTagForCode(s));
-        hb_tag_t s1, s2;
-        hb_ot_tags_from_script(scriptTag, &s1, &s2);
-        sScriptTagToCode->Put(s1, s);
-        if (s2 != HB_OT_TAG_DEFAULT_SCRIPT) {
-          sScriptTagToCode->Put(s2, s);
+        hb_script_t script = hb_script_t(GetScriptTagForCode(s));
+        unsigned int scriptCount = 4;
+        hb_tag_t scriptTags[4];
+        hb_ot_tags_from_script_and_language(script, HB_LANGUAGE_INVALID,
+                                            &scriptCount, scriptTags, nullptr,
+                                            nullptr);
+        for (unsigned int i = 0; i < scriptCount; i++) {
+          sScriptTagToCode->Put(scriptTags[i], s);
         }
       }
 
       uint32_t numDefaultFeatures = ArrayLength(defaultFeatures);
       sDefaultFeatures = new nsTHashtable<nsUint32HashKey>(numDefaultFeatures);
       for (uint32_t i = 0; i < numDefaultFeatures; i++) {
         sDefaultFeatures->PutEntry(defaultFeatures[i]);
       }
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -196,27 +196,28 @@ uint16_t gfxFontEntry::GetUVSGlyph(uint3
 
   if (mUVSData) {
     return gfxFontUtils::MapUVSToGlyphFormat14(mUVSData.get(), aCh, aVS);
   }
 
   return 0;
 }
 
-bool gfxFontEntry::SupportsScriptInGSUB(const hb_tag_t* aScriptTags) {
+bool gfxFontEntry::SupportsScriptInGSUB(const hb_tag_t* aScriptTags,
+                                        uint32_t aNumTags) {
   hb_face_t* face = GetHBFace();
   if (!face) {
     return false;
   }
 
   unsigned int index;
   hb_tag_t chosenScript;
-  bool found =
-      hb_ot_layout_table_choose_script(face, TRUETYPE_TAG('G', 'S', 'U', 'B'),
-                                       aScriptTags, &index, &chosenScript);
+  bool found = hb_ot_layout_table_select_script(
+      face, TRUETYPE_TAG('G', 'S', 'U', 'B'), aNumTags, aScriptTags, &index,
+      &chosenScript);
   hb_face_destroy(face);
 
   return found && chosenScript != TRUETYPE_TAG('D', 'F', 'L', 'T');
 }
 
 nsresult gfxFontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
   NS_ASSERTION(false, "using default no-op implementation of ReadCMAP");
   mCharacterMap = new gfxCharacterMap();
@@ -702,42 +703,40 @@ bool gfxFontEntry::SupportsOpenTypeFeatu
 
   hb_face_t* face = GetHBFace();
 
   if (hb_ot_layout_has_substitution(face)) {
     hb_script_t hbScript =
         gfxHarfBuzzShaper::GetHBScriptUsedForShaping(aScript);
 
     // Get the OpenType tag(s) that match this script code
-    hb_tag_t scriptTags[4] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE,
-                              HB_TAG_NONE};
-    hb_ot_tags_from_script(hbScript, &scriptTags[0], &scriptTags[1]);
+    unsigned int scriptCount = 4;
+    hb_tag_t scriptTags[4];
+    hb_ot_tags_from_script_and_language(hbScript, HB_LANGUAGE_INVALID,
+                                        &scriptCount, scriptTags, nullptr,
+                                        nullptr);
 
-    // Replace the first remaining NONE with DEFAULT
-    hb_tag_t* scriptTag = &scriptTags[0];
-    while (*scriptTag != HB_TAG_NONE) {
-      ++scriptTag;
+    // Append DEFAULT to the returned tags, if room
+    if (scriptCount < 4) {
+      scriptTags[scriptCount++] = HB_OT_TAG_DEFAULT_SCRIPT;
     }
-    *scriptTag = HB_OT_TAG_DEFAULT_SCRIPT;
 
     // Now check for 'smcp' under the first of those scripts that is present
     const hb_tag_t kGSUB = HB_TAG('G', 'S', 'U', 'B');
-    scriptTag = &scriptTags[0];
-    while (*scriptTag != HB_TAG_NONE) {
+    for (unsigned int i = 0; i < scriptCount; i++) {
       unsigned int scriptIndex;
-      if (hb_ot_layout_table_find_script(face, kGSUB, *scriptTag,
+      if (hb_ot_layout_table_find_script(face, kGSUB, scriptTags[i],
                                          &scriptIndex)) {
         if (hb_ot_layout_language_find_feature(
                 face, kGSUB, scriptIndex, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
                 aFeatureTag, nullptr)) {
           result = true;
         }
         break;
       }
-      ++scriptTag;
     }
   }
 
   hb_face_destroy(face);
 
   mSupportedFeatures->Put(scriptFeature, result);
 
   return result;
@@ -764,26 +763,27 @@ const hb_set_t* gfxFontEntry::InputsForO
 
   hb_face_t* face = GetHBFace();
 
   if (hb_ot_layout_has_substitution(face)) {
     hb_script_t hbScript =
         gfxHarfBuzzShaper::GetHBScriptUsedForShaping(aScript);
 
     // Get the OpenType tag(s) that match this script code
-    hb_tag_t scriptTags[4] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE,
-                              HB_TAG_NONE};
-    hb_ot_tags_from_script(hbScript, &scriptTags[0], &scriptTags[1]);
+    unsigned int scriptCount = 4;
+    hb_tag_t scriptTags[5];  // space for null terminator
+    hb_ot_tags_from_script_and_language(hbScript, HB_LANGUAGE_INVALID,
+                                        &scriptCount, scriptTags, nullptr,
+                                        nullptr);
 
-    // Replace the first remaining NONE with DEFAULT
-    hb_tag_t* scriptTag = &scriptTags[0];
-    while (*scriptTag != HB_TAG_NONE) {
-      ++scriptTag;
+    // Append DEFAULT to the returned tags, if room
+    if (scriptCount < 4) {
+      scriptTags[scriptCount++] = HB_OT_TAG_DEFAULT_SCRIPT;
     }
-    *scriptTag = HB_OT_TAG_DEFAULT_SCRIPT;
+    scriptTags[scriptCount++] = 0;
 
     const hb_tag_t kGSUB = HB_TAG('G', 'S', 'U', 'B');
     hb_tag_t features[2] = {aFeatureTag, HB_TAG_NONE};
     hb_set_t* featurelookups = hb_set_create();
     hb_ot_layout_collect_lookups(face, kGSUB, scriptTags, nullptr, features,
                                  featurelookups);
     hb_codepoint_t index = -1;
     while (hb_set_next(featurelookups, &index)) {
--- a/gfx/thebes/gfxFontEntry.h
+++ b/gfx/thebes/gfxFontEntry.h
@@ -351,21 +351,21 @@ class gfxFontEntry {
   // Used for reporting on individual font entries in the user font cache,
   // which are not present in the platform font list.
   size_t ComputedSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   // Used when checking for complex script support, to mask off cmap ranges
   struct ScriptRange {
     uint32_t rangeStart;
     uint32_t rangeEnd;
-    hb_tag_t tags[3];  // one or two OpenType script tags to check,
-                       // plus a NULL terminator
+    uint32_t numTags;  // number of entries in the tags[] array
+    hb_tag_t tags[3];  // up to three OpenType script tags to check
   };
 
-  bool SupportsScriptInGSUB(const hb_tag_t* aScriptTags);
+  bool SupportsScriptInGSUB(const hb_tag_t* aScriptTags, uint32_t aNumTags);
 
   /**
    * Font-variation query methods.
    *
    * Font backends that don't support variations should provide empty
    * implementations.
    */
   virtual bool HasVariations() = 0;
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -209,17 +209,17 @@ MacOSFontEntry::ReadCMAP(FontInfoData *a
                     // (e.g. Geeza Pro Bold on 10.6; see bug 614903)
                     mRequiresAAT = true;
                     // and don't mask off complex-script ranges, we assume
                     // the AAT tables will provide the necessary shaping
                     continue;
                 }
 
                 // We check for GSUB here, as GPOS alone would not be ok.
-                if (hasGSUB && SupportsScriptInGSUB(sr->tags)) {
+                if (hasGSUB && SupportsScriptInGSUB(sr->tags, sr->numTags)) {
                     continue;
                 }
 
                 charmap->ClearRange(sr->rangeStart, sr->rangeEnd);
             }
         }
 
         // Bug 1360309, 1393624: several of Apple's Chinese fonts have spurious
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -54,60 +54,71 @@ gfxPlatformFontList* gfxPlatformFontList
 // Currently used by the Mac and FT2 implementations only, but probably should
 // be supported on Windows as well.
 const gfxFontEntry::ScriptRange gfxPlatformFontList::sComplexScriptRanges[] = {
     // Actually, now that harfbuzz supports presentation-forms shaping for
     // Arabic, we can render it without layout tables. So maybe we don't
     // want to mask the basic Arabic block here?
     // This affects the arabic-fallback-*.html reftests, which rely on
     // loading a font that *doesn't* have any GSUB table.
-    {0x0600, 0x06FF, {TRUETYPE_TAG('a', 'r', 'a', 'b'), 0, 0}},
-    {0x0700, 0x074F, {TRUETYPE_TAG('s', 'y', 'r', 'c'), 0, 0}},
-    {0x0750, 0x077F, {TRUETYPE_TAG('a', 'r', 'a', 'b'), 0, 0}},
-    {0x08A0, 0x08FF, {TRUETYPE_TAG('a', 'r', 'a', 'b'), 0, 0}},
+    {0x0600, 0x06FF, 1, {TRUETYPE_TAG('a', 'r', 'a', 'b'), 0, 0}},
+    {0x0700, 0x074F, 1, {TRUETYPE_TAG('s', 'y', 'r', 'c'), 0, 0}},
+    {0x0750, 0x077F, 1, {TRUETYPE_TAG('a', 'r', 'a', 'b'), 0, 0}},
+    {0x08A0, 0x08FF, 1, {TRUETYPE_TAG('a', 'r', 'a', 'b'), 0, 0}},
     {0x0900,
      0x097F,
+     2,
      {TRUETYPE_TAG('d', 'e', 'v', '2'), TRUETYPE_TAG('d', 'e', 'v', 'a'), 0}},
     {0x0980,
      0x09FF,
+     2,
      {TRUETYPE_TAG('b', 'n', 'g', '2'), TRUETYPE_TAG('b', 'e', 'n', 'g'), 0}},
     {0x0A00,
      0x0A7F,
+     2,
      {TRUETYPE_TAG('g', 'u', 'r', '2'), TRUETYPE_TAG('g', 'u', 'r', 'u'), 0}},
     {0x0A80,
      0x0AFF,
+     2,
      {TRUETYPE_TAG('g', 'j', 'r', '2'), TRUETYPE_TAG('g', 'u', 'j', 'r'), 0}},
     {0x0B00,
      0x0B7F,
+     2,
      {TRUETYPE_TAG('o', 'r', 'y', '2'), TRUETYPE_TAG('o', 'r', 'y', 'a'), 0}},
     {0x0B80,
      0x0BFF,
+     2,
      {TRUETYPE_TAG('t', 'm', 'l', '2'), TRUETYPE_TAG('t', 'a', 'm', 'l'), 0}},
     {0x0C00,
      0x0C7F,
+     2,
      {TRUETYPE_TAG('t', 'e', 'l', '2'), TRUETYPE_TAG('t', 'e', 'l', 'u'), 0}},
     {0x0C80,
      0x0CFF,
+     2,
      {TRUETYPE_TAG('k', 'n', 'd', '2'), TRUETYPE_TAG('k', 'n', 'd', 'a'), 0}},
     {0x0D00,
      0x0D7F,
+     2,
      {TRUETYPE_TAG('m', 'l', 'm', '2'), TRUETYPE_TAG('m', 'l', 'y', 'm'), 0}},
-    {0x0D80, 0x0DFF, {TRUETYPE_TAG('s', 'i', 'n', 'h'), 0, 0}},
-    {0x0E80, 0x0EFF, {TRUETYPE_TAG('l', 'a', 'o', ' '), 0, 0}},
-    {0x0F00, 0x0FFF, {TRUETYPE_TAG('t', 'i', 'b', 't'), 0, 0}},
+    {0x0D80, 0x0DFF, 1, {TRUETYPE_TAG('s', 'i', 'n', 'h'), 0, 0}},
+    {0x0E80, 0x0EFF, 1, {TRUETYPE_TAG('l', 'a', 'o', ' '), 0, 0}},
+    {0x0F00, 0x0FFF, 1, {TRUETYPE_TAG('t', 'i', 'b', 't'), 0, 0}},
     {0x1000,
      0x109f,
+     2,
      {TRUETYPE_TAG('m', 'y', 'm', 'r'), TRUETYPE_TAG('m', 'y', 'm', '2'), 0}},
-    {0x1780, 0x17ff, {TRUETYPE_TAG('k', 'h', 'm', 'r'), 0, 0}},
+    {0x1780, 0x17ff, 1, {TRUETYPE_TAG('k', 'h', 'm', 'r'), 0, 0}},
     // Khmer Symbols (19e0..19ff) don't seem to need any special shaping
     {0xaa60,
      0xaa7f,
+     2,
      {TRUETYPE_TAG('m', 'y', 'm', 'r'), TRUETYPE_TAG('m', 'y', 'm', '2'), 0}},
     // Thai seems to be "renderable" without AAT morphing tables
-    {0, 0, {0, 0, 0}}  // terminator
+    {0, 0, 0, {0, 0, 0}}  // terminator
 };
 
 // prefs for the font info loader
 #define FONT_LOADER_DELAY_PREF "gfx.font_loader.delay"
 #define FONT_LOADER_INTERVAL_PREF "gfx.font_loader.interval"
 
 static const char* kObservedPrefs[] = {"font.", "font.name-list.",
                                        "intl.accept_languages",  // hmmmm...