Add match type to FontCacheKey information

Fixes situations in which a locally unique font name match masks a
result for a family name match.

This cannot be tested before src: local() matching is enabled by
switching the flag. A layout test covering this situation will be added
when the flag is enabled.

Bug: 921029
Change-Id: I4123cb70aa65cb59e4a00c3a58e312ef6fa24b64
Reviewed-on: https://chromium-review.googlesource.com/c/1407069
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Reviewed-by: Koji Ishii <kojii@chromium.org>
Reviewed-by: Emil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#622167}
diff --git a/third_party/blink/renderer/core/css/css_font_face_source.cc b/third_party/blink/renderer/core/css/css_font_face_source.cc
index a924d62..331efc1e 100644
--- a/third_party/blink/renderer/core/css/css_font_face_source.cc
+++ b/third_party/blink/renderer/core/css/css_font_face_source.cc
@@ -58,7 +58,9 @@
     return CreateFontData(font_description, font_selection_capabilities);
   }
 
-  FontCacheKey key = font_description.CacheKey(FontFaceCreationParams());
+  bool is_unique_match = false;
+  FontCacheKey key =
+      font_description.CacheKey(FontFaceCreationParams(), is_unique_match);
 
   // Get or create the font data. Take care to avoid dangling references into
   // font_data_table_, because it is modified below during pruning.
diff --git a/third_party/blink/renderer/core/css/css_font_face_source_test.cc b/third_party/blink/renderer/core/css/css_font_face_source_test.cc
index 3ff7e0c..62ffbf43 100644
--- a/third_party/blink/renderer/core/css/css_font_face_source_test.cc
+++ b/third_party/blink/renderer/core/css/css_font_face_source_test.cc
@@ -42,7 +42,9 @@
   FontDescription font_description;
   font_description.SetSizeAdjust(size);
   font_description.SetAdjustedSize(size);
-  return font_description.CacheKey(FontFaceCreationParams()).GetHash();
+  bool is_unique_match = false;
+  return font_description.CacheKey(FontFaceCreationParams(), is_unique_match)
+      .GetHash();
 }
 }
 
@@ -50,9 +52,9 @@
   DummyFontFaceSource font_face_source;
   // Even if the hash value collide, fontface cache should return different
   // value for different fonts.
-  EXPECT_EQ(SimulateHashCalculation(527), SimulateHashCalculation(3099));
-  EXPECT_NE(font_face_source.GetFontDataForSize(527),
-            font_face_source.GetFontDataForSize(3099));
+  EXPECT_EQ(SimulateHashCalculation(6009), SimulateHashCalculation(8634));
+  EXPECT_NE(font_face_source.GetFontDataForSize(6009),
+            font_face_source.GetFontDataForSize(8634));
 }
 
 // Exercises the size font_data_table_ assertions in CSSFontFaceSource.
diff --git a/third_party/blink/renderer/core/css/css_segmented_font_face.cc b/third_party/blink/renderer/core/css/css_segmented_font_face.cc
index 0278f02..3a67864 100644
--- a/third_party/blink/renderer/core/css/css_segmented_font_face.cc
+++ b/third_party/blink/renderer/core/css/css_segmented_font_face.cc
@@ -98,8 +98,9 @@
 
   const FontSelectionRequest& font_selection_request =
       font_description.GetFontSelectionRequest();
-  FontCacheKey key = font_description.CacheKey(FontFaceCreationParams(),
-                                               font_selection_request);
+  bool is_unique_match = false;
+  FontCacheKey key = font_description.CacheKey(
+      FontFaceCreationParams(), is_unique_match, font_selection_request);
 
   scoped_refptr<SegmentedFontData>& font_data =
       font_data_table_.insert(key, nullptr).stored_value->value;
diff --git a/third_party/blink/renderer/platform/fonts/font_cache.cc b/third_party/blink/renderer/platform/fonts/font_cache.cc
index 012098d..92d453b 100644
--- a/third_party/blink/renderer/platform/fonts/font_cache.cc
+++ b/third_party/blink/renderer/platform/fonts/font_cache.cc
@@ -118,7 +118,10 @@
 
   float size = font_description.EffectiveFontSize();
   unsigned rounded_size = size * FontCacheKey::PrecisionMultiplier();
-  FontCacheKey key = font_description.CacheKey(creation_params);
+  bool is_unique_match =
+      alternate_font_name == AlternateFontName::kLocalUniqueFace;
+  FontCacheKey key =
+      font_description.CacheKey(creation_params, is_unique_match);
 
   // Remove the font size from the cache key, and handle the font size
   // separately in the inner HashMap. So that different size of FontPlatformData
diff --git a/third_party/blink/renderer/platform/fonts/font_cache_key.h b/third_party/blink/renderer/platform/fonts/font_cache_key.h
index a7823cb..f9d07ff 100644
--- a/third_party/blink/renderer/platform/fonts/font_cache_key.h
+++ b/third_party/blink/renderer/platform/fonts/font_cache_key.h
@@ -53,17 +53,20 @@
       : creation_params_(),
         font_size_(0),
         options_(0),
-        device_scale_factor_(0) {}
+        device_scale_factor_(0),
+        is_unique_match_(false) {}
   FontCacheKey(FontFaceCreationParams creation_params,
                float font_size,
                unsigned options,
                float device_scale_factor,
-               scoped_refptr<FontVariationSettings> variation_settings)
+               scoped_refptr<FontVariationSettings> variation_settings,
+               bool is_unique_match)
       : creation_params_(creation_params),
         font_size_(font_size * kFontSizePrecisionMultiplier),
         options_(options),
         device_scale_factor_(device_scale_factor),
-        variation_settings_(std::move(variation_settings)) {}
+        variation_settings_(std::move(variation_settings)),
+        is_unique_match_(is_unique_match) {}
 
   FontCacheKey(WTF::HashTableDeletedValueType)
       : font_size_(HashTableDeletedSize()) {}
@@ -71,10 +74,13 @@
   unsigned GetHash() const {
     // Convert from float with 3 digit precision before hashing.
     unsigned device_scale_factor_hash = device_scale_factor_ * 1000;
-    unsigned hash_codes[5] = {
-        creation_params_.GetHash(), font_size_, options_,
+    unsigned hash_codes[6] = {
+        creation_params_.GetHash(),
+        font_size_,
+        options_,
         device_scale_factor_hash,
-        variation_settings_ ? variation_settings_->GetHash() : 0};
+        variation_settings_ ? variation_settings_->GetHash() : 0,
+        is_unique_match_};
     return StringHasher::HashMemory<sizeof(hash_codes)>(hash_codes);
   }
 
@@ -82,7 +88,8 @@
     return creation_params_ == other.creation_params_ &&
            font_size_ == other.font_size_ && options_ == other.options_ &&
            device_scale_factor_ == other.device_scale_factor_ &&
-           variation_settings_ == other.variation_settings_;
+           variation_settings_ == other.variation_settings_ &&
+           is_unique_match_ == other.is_unique_match_;
   }
 
   bool IsHashTableDeletedValue() const {
@@ -105,6 +112,7 @@
   // device_scale_factor_ to be a part of computing the cache key.
   float device_scale_factor_;
   scoped_refptr<FontVariationSettings> variation_settings_;
+  bool is_unique_match_;
 };
 
 struct FontCacheKeyHash {
diff --git a/third_party/blink/renderer/platform/fonts/font_description.cc b/third_party/blink/renderer/platform/fonts/font_description.cc
index 32d2a97..63eff2f 100644
--- a/third_party/blink/renderer/platform/fonts/font_description.cc
+++ b/third_party/blink/renderer/platform/fonts/font_description.cc
@@ -214,6 +214,7 @@
 
 FontCacheKey FontDescription::CacheKey(
     const FontFaceCreationParams& creation_params,
+    bool is_unique_match,
     const FontSelectionRequest& font_selection_request) const {
   unsigned options =
       static_cast<unsigned>(fields_.synthetic_italic_) << 6 |  // bit 7
@@ -229,7 +230,8 @@
 #endif
   FontCacheKey cache_key(creation_params, EffectiveFontSize(),
                          options | font_selection_request_.GetHash() << 8,
-                         device_scale_factor_for_key, variation_settings_);
+                         device_scale_factor_for_key, variation_settings_,
+                         is_unique_match);
   return cache_key;
 }
 
diff --git a/third_party/blink/renderer/platform/fonts/font_description.h b/third_party/blink/renderer/platform/fonts/font_description.h
index 925923d..f97284d 100644
--- a/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/third_party/blink/renderer/platform/fonts/font_description.h
@@ -252,6 +252,7 @@
       const;  // Returns either the computedSize or the computedPixelSize
   FontCacheKey CacheKey(
       const FontFaceCreationParams&,
+      bool is_unique_match,
       const FontSelectionRequest& = FontSelectionRequest()) const;
 
   void SetFamily(const FontFamily& family) { family_list_ = family; }
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
index 85e8fbc1..be346f3 100644
--- a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -202,7 +202,8 @@
               platform_data);
       }
       if (result) {
-        key.Add(font_description.CacheKey(params));
+        bool is_unique_match = false;
+        key.Add(font_description.CacheKey(params, is_unique_match));
         if (!result->IsSegmented() && !result->IsCustomFont())
           FontCache::GetFontCache()->ReleaseFontData(ToSimpleFontData(result));
       }