Instrument PostScript name to typeface mapping for identifiability study
Currently, local font lookups are instrumented with a digest of the
lookup value and a digest of the resulting typeface being recorded. We
expand this recording for successful local font lookups: we now also
record a digest of the resulting typeface's PostScript name with the
typeface digest. This will allow the identifiability study to measure
the diversity of installed typeface files with the same PostScript name
(for example, differing versions of the same typeface) and thus
evaluate the privacy impact of that variation.
(cherry picked from commit fffc6331d8120fe5d4390af6fdfb711f139d7258)
Bug: 1136210
Change-Id: Id7ac6229db287af776474f43abd200c51319992e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2453439
Reviewed-by: Dominik Röttsches <[email protected]>
Reviewed-by: Asanka Herath <[email protected]>
Commit-Queue: Alex Turner <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#815773}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2477042
Cr-Commit-Position: refs/branch-heads/4280@{#491}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/third_party/blink/public/common/privacy_budget/identifiable_surface.h b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
index bface9c..f3508c5f 100644
--- a/third_party/blink/public/common/privacy_budget/identifiable_surface.h
+++ b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
@@ -171,7 +171,7 @@
// FontSelectionRequest (i.e. weight, width and slope).
kLocalFontLookupByFallbackCharacter = 13,
- // Represents loading a font locally as a last resort. Input is the
+ // Represents looking up a font locally as a last resort. Input is the
// FontSelectionRequest (i.e. weight, width and slope).
kLocalFontLookupAsLastResort = 14,
@@ -184,6 +184,9 @@
// will key this type on a digest of both the enums' values.
kWebGLShaderPrecisionFormat = 16,
+ // Represents loading a font locally. Input is the PostScript name.
+ kLocalFontLoadPostScriptName = 29,
+
// We can use values up to and including |kMax|.
kMax = (1 << kTypeBits) - 1
};
diff --git a/third_party/blink/renderer/platform/fonts/font_global_context.cc b/third_party/blink/renderer/platform/fonts/font_global_context.cc
index 3e80b58..05d13203 100644
--- a/third_party/blink/renderer/platform/fonts/font_global_context.cc
+++ b/third_party/blink/renderer/platform/fonts/font_global_context.cc
@@ -7,12 +7,13 @@
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h"
+#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
-// While the size of this cache should usually be small (up to tens), we protect
-// against the possibility of it growing quickly to thousands when animating
-// variable font parameters.
-static constexpr size_t kTypefaceDigestCacheMaxSize = 250;
+// While the size of these caches should usually be small (up to tens), we
+// protect against the possibility of it growing quickly to thousands when
+// animating variable font parameters.
+static constexpr size_t kCachesMaxSize = 250;
namespace blink {
@@ -28,7 +29,8 @@
FontGlobalContext::FontGlobalContext()
: harfbuzz_font_funcs_skia_advances_(nullptr),
harfbuzz_font_funcs_harfbuzz_advances_(nullptr),
- typeface_digest_cache_(kTypefaceDigestCacheMaxSize) {}
+ typeface_digest_cache_(kCachesMaxSize),
+ postscript_name_digest_cache_(kCachesMaxSize) {}
FontGlobalContext::~FontGlobalContext() = default;
@@ -67,12 +69,33 @@
return *cached_value;
}
+IdentifiableToken FontGlobalContext::GetOrComputePostScriptNameDigest(
+ const FontPlatformData& source) {
+ SkTypeface* typeface = source.Typeface();
+ if (!typeface)
+ return IdentifiableToken();
+
+ SkFontID font_id = typeface->uniqueID();
+
+ IdentifiableToken* cached_value = postscript_name_digest_cache_.Get(font_id);
+ if (!cached_value) {
+ postscript_name_digest_cache_.Put(
+ font_id, IdentifiabilityBenignStringToken(source.GetPostScriptName()));
+ cached_value = postscript_name_digest_cache_.Get(font_id);
+ } else {
+ DCHECK(*cached_value ==
+ IdentifiabilityBenignStringToken(source.GetPostScriptName()));
+ }
+ return *cached_value;
+}
+
void FontGlobalContext::ClearMemory() {
if (!Get(kDoNotCreate))
return;
GetFontCache().Invalidate();
Get()->typeface_digest_cache_.Clear();
+ Get()->postscript_name_digest_cache_.Clear();
}
} // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/font_global_context.h b/third_party/blink/renderer/platform/fonts/font_global_context.h
index 11f9697..e2c8361 100644
--- a/third_party/blink/renderer/platform/fonts/font_global_context.h
+++ b/third_party/blink/renderer/platform/fonts/font_global_context.h
@@ -59,6 +59,8 @@
static FontUniqueNameLookup* GetFontUniqueNameLookup();
IdentifiableToken GetOrComputeTypefaceDigest(const FontPlatformData& source);
+ IdentifiableToken GetOrComputePostScriptNameDigest(
+ const FontPlatformData& source);
// Called by MemoryPressureListenerRegistry to clear memory.
static void ClearMemory();
@@ -75,6 +77,7 @@
hb_font_funcs_t* harfbuzz_font_funcs_harfbuzz_advances_;
std::unique_ptr<FontUniqueNameLookup> font_unique_name_lookup_;
WTF::LruCache<SkFontID, IdentifiableToken> typeface_digest_cache_;
+ WTF::LruCache<SkFontID, IdentifiableToken> postscript_name_digest_cache_;
DISALLOW_COPY_AND_ASSIGN(FontGlobalContext);
};
diff --git a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
index 63ef79a..f70006b 100644
--- a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
+++ b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
@@ -109,6 +109,12 @@
return;
IdentifiableToken output_token(GetHashForFontData(font_data));
hash_map.insert(input_key, output_token);
+
+ if (!font_data)
+ return;
+ IdentifiableTokenKey postscript_name_key(
+ GetPostScriptNameTokenForFontData(font_data));
+ font_load_postscript_name_.insert(postscript_name_key, output_token);
}
IdentifiableTokenBuilder
@@ -245,6 +251,8 @@
IdentifiableSurface::Type::kLocalFontLookupAsLastResort},
{&generic_font_lookups_,
IdentifiableSurface::Type::kGenericFontLookup},
+ {&font_load_postscript_name_,
+ IdentifiableSurface::Type::kLocalFontLoadPostScriptName},
};
for (const auto& surface_entry : hash_maps_with_corresponding_surface_types) {
@@ -310,4 +318,11 @@
: 0;
}
+IdentifiableToken FontMatchingMetrics::GetPostScriptNameTokenForFontData(
+ SimpleFontData* font_data) {
+ DCHECK(font_data);
+ return FontGlobalContext::Get()->GetOrComputePostScriptNameDigest(
+ font_data->PlatformData());
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/font_matching_metrics.h b/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
index 175d193f..17d136c 100644
--- a/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
+++ b/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
@@ -193,7 +193,9 @@
IdentifiableTokenKeyHashTraits>;
// Adds a digest of the |font_data|'s typeface to |hash_map| using the key
- // |input_key|, unless that key is already present.
+ // |input_key|, unless that key is already present. If |font_data| is not
+ // nullptr, then the typeface digest will also be saved with its PostScript
+ // name in |font_load_postscript_name_|.
void InsertFontHashIntoMap(IdentifiableTokenKey input_key,
SimpleFontData* font_data,
TokenToTokenHashMap hash_map);
@@ -208,6 +210,11 @@
void Initialize();
+ // Get a token that uniquely represents the typeface's PostScript name. May
+ // represent the empty string if no PostScript name was found.
+ IdentifiableToken GetPostScriptNameTokenForFontData(
+ SimpleFontData* font_data);
+
// Font family names successfully matched.
HashSet<AtomicString> successful_font_families_;
@@ -235,6 +242,7 @@
TokenToTokenHashMap font_lookups_by_fallback_character_;
TokenToTokenHashMap font_lookups_as_last_resort_;
TokenToTokenHashMap generic_font_lookups_;
+ TokenToTokenHashMap font_load_postscript_name_;
ukm::UkmRecorder* const ukm_recorder_;
const ukm::SourceId source_id_;
diff --git a/third_party/blink/renderer/platform/fonts/font_platform_data.cc b/third_party/blink/renderer/platform/fonts/font_platform_data.cc
index fc5e804c..f96cee1 100644
--- a/third_party/blink/renderer/platform/fonts/font_platform_data.cc
+++ b/third_party/blink/renderer/platform/fonts/font_platform_data.cc
@@ -338,4 +338,13 @@
return builder.GetToken(); // hasher.GetHash();
}
+String FontPlatformData::GetPostScriptName() const {
+ if (!typeface_)
+ return String();
+
+ SkString postscript_name;
+ bool success = typeface_->getPostScriptName(&postscript_name);
+ return success ? postscript_name.c_str() : String();
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/font_platform_data.h b/third_party/blink/renderer/platform/fonts/font_platform_data.h
index c5836d9..b10ff2e8b 100644
--- a/third_party/blink/renderer/platform/fonts/font_platform_data.h
+++ b/third_party/blink/renderer/platform/fonts/font_platform_data.h
@@ -145,6 +145,9 @@
// the fingerprinting algorithm.
IdentifiableToken ComputeTypefaceDigest() const;
+ // Gets the postscript name from the typeface.
+ String GetPostScriptName() const;
+
private:
#if !defined(OS_WIN) && !defined(OS_MAC)
WebFontRenderStyle QuerySystemRenderStyle(const std::string& family,