summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/fonts
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/third_party/blink/renderer/platform/fonts
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
downloadqtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/fonts')
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.cc66
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc75
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_data.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc72
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc74
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h50
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_global_context.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selector.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm62
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm129
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h45
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc258
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h120
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc466
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc156
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc92
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc223
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc264
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc45
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc57
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h91
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc4
72 files changed, 2388 insertions, 561 deletions
diff --git a/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc
index c9a48d57f2f..48295090b57 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h"
#include "mojo/public/mojom/base/shared_memory.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -86,7 +86,7 @@ void FontUniqueNameLookupAndroid::EnsureServiceConnected() {
if (service_)
return;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
service_.BindNewPipeAndPassReceiver());
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.cc b/chromium/third_party/blink/renderer/platform/fonts/font.cc
index 2b110b2e0e0..7a9414845a0 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.cc
@@ -48,27 +48,20 @@
namespace blink {
-Font::Font() : can_shape_word_by_word_(0), shape_word_by_word_computed_(0) {}
-
-Font::Font(const FontDescription& fd)
- : font_description_(fd),
- can_shape_word_by_word_(0),
- shape_word_by_word_computed_(0) {}
-
-Font::Font(const Font& other)
- : font_description_(other.font_description_),
- font_fallback_list_(other.font_fallback_list_),
- // TODO(yosin): We should have a comment the reason why don't we copy
- // |m_canShapeWordByWord| and |m_shapeWordByWordComputed| from |other|,
- // since |operator=()| copies them from |other|.
- can_shape_word_by_word_(0),
- shape_word_by_word_computed_(0) {}
+Font::Font() = default;
+
+Font::Font(const FontDescription& fd) : font_description_(fd) {}
+
+Font::Font(const FontDescription& font_description, FontSelector* font_selector)
+ : font_description_(font_description),
+ font_fallback_list_(
+ font_selector ? FontFallbackList::Create(font_selector) : nullptr) {}
+
+Font::Font(const Font& other) = default;
Font& Font::operator=(const Font& other) {
font_description_ = other.font_description_;
font_fallback_list_ = other.font_fallback_list_;
- can_shape_word_by_word_ = other.can_shape_word_by_word_;
- shape_word_by_word_computed_ = other.shape_word_by_word_computed_;
return *this;
}
@@ -91,18 +84,6 @@ bool Font::operator==(const Font& other) const {
: 0);
}
-void Font::Update(FontSelector* font_selector) const {
- // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr,
- // but it ends up being reasonably safe (because inherited fonts in the render
- // tree pick up the new style anyway. Other copies are transient, e.g., the
- // state in the GraphicsContext, and won't stick around long enough to get you
- // in trouble). Still, this is pretty disgusting, and could eventually be
- // rectified by using RefPtrs for Fonts themselves.
- if (!font_fallback_list_)
- font_fallback_list_ = FontFallbackList::Create();
- font_fallback_list_->Invalidate(font_selector);
-}
-
namespace {
void DrawBlobs(cc::PaintCanvas* canvas,
@@ -217,7 +198,10 @@ bool Font::DrawBidiText(cc::PaintCanvas* canvas,
TextRunPaintInfo subrun_info(subrun);
- ShapeResultBloberizer bloberizer(*this, device_scale_factor);
+ // Fix regression with -ftrivial-auto-var-init=pattern. See
+ // crbug.com/1055652.
+ STACK_UNINITIALIZED ShapeResultBloberizer bloberizer(*this,
+ device_scale_factor);
ShapeResultBuffer buffer;
word_shaper.FillResultBuffer(subrun_info, &buffer);
float run_width = bloberizer.FillGlyphs(subrun_info, buffer);
@@ -422,31 +406,15 @@ int Font::OffsetForPosition(const TextRun& run,
}
ShapeCache* Font::GetShapeCache() const {
- return font_fallback_list_->GetShapeCache(font_description_);
+ return EnsureFontFallbackList()->GetShapeCache(font_description_);
}
bool Font::CanShapeWordByWord() const {
- if (!shape_word_by_word_computed_) {
- can_shape_word_by_word_ = ComputeCanShapeWordByWord();
- shape_word_by_word_computed_ = true;
- }
- return can_shape_word_by_word_;
-}
-
-bool Font::ComputeCanShapeWordByWord() const {
- if (!GetFontDescription().GetTypesettingFeatures())
- return true;
-
- if (!PrimaryFont())
- return false;
-
- const FontPlatformData& platform_data = PrimaryFont()->PlatformData();
- TypesettingFeatures features = GetFontDescription().GetTypesettingFeatures();
- return !platform_data.HasSpaceInLigaturesOrKerning(features);
+ return EnsureFontFallbackList()->CanShapeWordByWord(GetFontDescription());
}
void Font::ReportNotDefGlyph() const {
- FontSelector* fontSelector = font_fallback_list_->GetFontSelector();
+ FontSelector* fontSelector = EnsureFontFallbackList()->GetFontSelector();
// We have a few non-DOM usages of Font code, for example in DragImage::Create
// and in EmbeddedObjectPainter::paintReplaced. In those cases, we can't
// retrieve a font selector as our connection to a Document object to report
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.h b/chromium/third_party/blink/renderer/platform/fonts/font.h
index ca24f5f5e49..2aeb6057caa 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.h
@@ -54,7 +54,6 @@ namespace blink {
struct CharacterRange;
class FloatPoint;
class FloatRect;
-class FontData;
class FontSelector;
class ShapeCache;
class TextRun;
@@ -66,7 +65,8 @@ class PLATFORM_EXPORT Font {
public:
Font();
- Font(const FontDescription&);
+ explicit Font(const FontDescription&);
+ Font(const FontDescription&, FontSelector*);
~Font();
Font(const Font&);
@@ -79,8 +79,6 @@ class PLATFORM_EXPORT Font {
return font_description_;
}
- void Update(FontSelector*) const;
-
enum CustomFontNotReadyAction {
kDoNotPaintIfFontNotReady,
kUseFallbackIfFontNotReady
@@ -203,7 +201,6 @@ class PLATFORM_EXPORT Font {
// loaded. This *should* not happen but in reality it does ever now and then
// when, for whatever reason, the last resort font cannot be loaded.
const SimpleFontData* PrimaryFont() const;
- const FontData* FontDataAt(unsigned) const;
// Access the shape cache associated with this particular font object.
// Should *not* be retained across layout calls as it may become invalid.
@@ -215,8 +212,7 @@ class PLATFORM_EXPORT Font {
bool CanShapeWordByWord() const;
void SetCanShapeWordByWordForTesting(bool b) {
- can_shape_word_by_word_ = b;
- shape_word_by_word_computed_ = true;
+ EnsureFontFallbackList()->SetCanShapeWordByWordForTesting(b);
}
void ReportNotDefGlyph() const;
@@ -226,12 +222,11 @@ class PLATFORM_EXPORT Font {
GlyphData GetEmphasisMarkGlyphData(const AtomicString&) const;
- bool ComputeCanShapeWordByWord() const;
-
public:
FontSelector* GetFontSelector() const;
FontFallbackIterator CreateFontFallbackIterator(
FontFallbackPriority fallback_priority) const {
+ EnsureFontFallbackList();
return FontFallbackIterator(font_description_, font_fallback_list_,
fallback_priority);
}
@@ -246,25 +241,20 @@ class PLATFORM_EXPORT Font {
}
private:
+ FontFallbackList* EnsureFontFallbackList() const {
+ if (!font_fallback_list_)
+ font_fallback_list_ = FontFallbackList::Create(nullptr);
+ return font_fallback_list_.get();
+ }
+
FontDescription font_description_;
mutable scoped_refptr<FontFallbackList> font_fallback_list_;
- mutable unsigned can_shape_word_by_word_ : 1;
- mutable unsigned shape_word_by_word_computed_ : 1;
-
- // For m_fontDescription & m_fontFallbackList access.
- friend class CachingWordShaper;
};
inline Font::~Font() = default;
inline const SimpleFontData* Font::PrimaryFont() const {
- DCHECK(font_fallback_list_);
- return font_fallback_list_->PrimarySimpleFontData(font_description_);
-}
-
-inline const FontData* Font::FontDataAt(unsigned index) const {
- DCHECK(font_fallback_list_);
- return font_fallback_list_->FontDataAt(font_description_, index);
+ return EnsureFontFallbackList()->PrimarySimpleFontData(font_description_);
}
inline FontSelector* Font::GetFontSelector() const {
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
index b4a7e9509cf..396a27aa4fe 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
@@ -386,6 +386,11 @@ void FontCache::InvalidateShapeCache() {
PurgeFallbackListShaperCache();
}
+void FontCache::InvalidateEnumerationCache() {
+ TRACE_EVENT0("fonts,ui", "FontCache::InvalidateEnumerationCache");
+ font_enumeration_cache_.clear();
+}
+
void FontCache::Purge(PurgeSeverity purge_severity) {
// Ideally we should never be forcing the purge while the
// FontCachePurgePreventer is in scope, but we call purge() at any timing
@@ -398,6 +403,7 @@ void FontCache::Purge(PurgeSeverity purge_severity) {
PurgePlatformFontDataCache();
PurgeFallbackListShaperCache();
+ InvalidateEnumerationCache();
}
void FontCache::AddClient(FontCacheClient* client) {
@@ -418,6 +424,10 @@ uint16_t FontCache::Generation() {
void FontCache::Invalidate() {
TRACE_EVENT0("fonts,ui", "FontCache::Invalidate");
font_platform_data_cache_.clear();
+ // TODO(https://crbug.com/1061630): Determine optimal cache invalidation
+ // strategy for enumeration. As implemented, the enumeration cache might not
+ // get invalidated when the system fonts change.
+ InvalidateEnumerationCache();
generation_++;
if (font_cache_clients_) {
@@ -524,4 +534,15 @@ FontCache::Bcp47Vector FontCache::GetBcp47LocaleForRequest(
return result;
}
+const std::vector<FontEnumerationEntry>& FontCache::EnumerateAvailableFonts() {
+ if (font_enumeration_cache_.size() == 0) {
+ base::TimeTicks enum_start = base::TimeTicks::Now();
+ font_enumeration_cache_ = EnumeratePlatformAvailableFonts();
+ base::TimeDelta time_taken = base::TimeTicks::Now() - enum_start;
+ UMA_HISTOGRAM_TIMES("Blink.Fonts.Enumeration.Duration", time_taken);
+ }
+
+ return font_enumeration_cache_;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
index 08c723bc646..41c63400fbb 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
@@ -90,21 +90,24 @@ enum class AlternateFontName {
kLastResort
};
+struct FontEnumerationEntry {
+ String postscript_name;
+ String full_name;
+ String family;
+};
+
typedef HashMap<unsigned,
std::unique_ptr<FontPlatformData>,
WTF::IntHash<unsigned>,
WTF::UnsignedWithZeroKeyHashTraits<unsigned>>
SizedFontPlatformDataSet;
-typedef HashMap<FontCacheKey,
- SizedFontPlatformDataSet,
- FontCacheKeyHash,
- FontCacheKeyTraits>
- FontPlatformDataCache;
+typedef HashMap<FontCacheKey, SizedFontPlatformDataSet> FontPlatformDataCache;
typedef HashMap<FallbackListCompositeKey,
std::unique_ptr<ShapeCache>,
FallbackListCompositeKeyHash,
FallbackListCompositeKeyTraits>
FallbackListShaperCache;
+typedef std::vector<FontEnumerationEntry> FontEnumerationCache;
class PLATFORM_EXPORT FontCache {
friend class FontCachePurgePreventer;
@@ -252,7 +255,13 @@ class PLATFORM_EXPORT FontCache {
ShouldRetain = kRetain,
bool subpixel_ascent_descent = false);
+ const std::vector<FontEnumerationEntry>& EnumerateAvailableFonts();
+ size_t EnumerationCacheSizeForTesting() {
+ return font_enumeration_cache_.size();
+ }
+
void InvalidateShapeCache();
+ void InvalidateEnumerationCache();
static void CrashWithFontInfo(const FontDescription*);
@@ -312,6 +321,7 @@ class PLATFORM_EXPORT FontCache {
const FontDescription&,
const FontFaceCreationParams&,
float font_size);
+ std::vector<FontEnumerationEntry> EnumeratePlatformAvailableFonts();
sk_sp<SkTypeface> CreateTypeface(const FontDescription&,
const FontFaceCreationParams&,
@@ -366,6 +376,9 @@ class PLATFORM_EXPORT FontCache {
FontPlatformDataCache font_platform_data_cache_;
FallbackListShaperCache fallback_list_shaper_cache_;
FontDataCache font_data_cache_;
+ // TODO(https://crbug.com/1061625): Move to the browser process for better
+ // resource utilization.
+ FontEnumerationCache font_enumeration_cache_;
void PurgePlatformFontDataCache();
void PurgeFallbackListShaperCache();
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h b/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h
index 2160fcb2c3b..6b7c90a227d 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache_client.h
@@ -42,7 +42,7 @@ class PLATFORM_EXPORT FontCacheClient
virtual ~FontCacheClient() = default;
virtual void FontCacheInvalidated() = 0;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h b/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h
index 90063cb2eac..a860a0ad051 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h
@@ -93,13 +93,19 @@ struct FontCacheKey {
}
bool operator==(const FontCacheKey& other) const {
+ bool variation_settings_equal =
+ (!variation_settings_ && !other.variation_settings_) ||
+ (variation_settings_ && other.variation_settings_ &&
+ *variation_settings_ == *other.variation_settings_);
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_equal &&
is_unique_match_ == other.is_unique_match_;
}
+ bool operator!=(const FontCacheKey& other) const { return !(*this == other); }
+
static constexpr unsigned PrecisionMultiplier() {
return kFontSizePrecisionMultiplier;
}
@@ -141,4 +147,23 @@ struct FontCacheKeyTraits : WTF::SimpleClassHashTraits<FontCacheKey> {
} // namespace blink
+namespace WTF {
+template <>
+struct DefaultHash<blink::FontCacheKey> {
+ STATIC_ONLY(DefaultHash);
+ typedef blink::FontCacheKeyHash Hash;
+};
+
+template <>
+struct HashTraits<blink::FontCacheKey>
+ : WTF::SimpleClassHashTraits<blink::FontCacheKey> {
+ STATIC_ONLY(HashTraits);
+
+ // std::string's empty state need not be zero in all implementations,
+ // and it is held within FontFaceCreationParams.
+ static const bool kEmptyValueIsZero = false;
+};
+
+} // namespace WTF
+
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_CACHE_KEY_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc b/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc
index a9233996c15..0f2c270892c 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc
@@ -89,4 +89,79 @@ TEST(FontCache, systemFont) {
}
#endif
+class EnumerationConsumer {
+ public:
+ explicit EnumerationConsumer(
+ const std::vector<FontEnumerationEntry>& expectations) {
+ for (const auto& f : expectations) {
+ ps_name_set_.insert(f.postscript_name.Utf8());
+ full_name_set_.insert(f.full_name.Utf8());
+ family_set_.insert(f.family.Utf8());
+ }
+ }
+
+ void Consume(const std::vector<FontEnumerationEntry>& entries) {
+ for (auto f : entries) {
+ ps_name_set_.erase(f.postscript_name.Utf8());
+ full_name_set_.erase(f.full_name.Utf8());
+ family_set_.erase(f.family.Utf8());
+ }
+ }
+
+ bool AllExpectationsMet() {
+ return ps_name_set_.empty() && full_name_set_.empty() &&
+ family_set_.empty();
+ }
+
+ private:
+ std::set<std::string> ps_name_set_;
+ std::set<std::string> full_name_set_;
+ std::set<std::string> family_set_;
+};
+
+TEST(FontCache, EnumerateAvailableFonts) {
+ FontCache* font_cache = FontCache::GetFontCache();
+ ASSERT_TRUE(font_cache);
+
+ std::vector<FontEnumerationEntry> expectations;
+
+#if defined(OS_MACOSX)
+ expectations.push_back(FontEnumerationEntry{"Monaco", "Monaco", "Monaco"});
+ expectations.push_back(
+ FontEnumerationEntry{"Menlo-Regular", "Menlo Regular", "Menlo"});
+ expectations.push_back(
+ FontEnumerationEntry{"Menlo-Bold", "Menlo Bold", "Menlo"});
+ expectations.push_back(
+ FontEnumerationEntry{"Menlo-BoldItalic", "Menlo Bold Italic", "Menlo"});
+#endif
+
+ auto entries = font_cache->EnumerateAvailableFonts();
+ auto consumer = EnumerationConsumer(expectations);
+
+ consumer.Consume(entries);
+ ASSERT_TRUE(consumer.AllExpectationsMet());
+}
+
+TEST(FontCache, EnumerateAvailableFontsInvalidation) {
+ FontCache* font_cache = FontCache::GetFontCache();
+ ASSERT_TRUE(font_cache);
+
+ // Make sure we start at zero.
+ font_cache->Invalidate();
+ size_t zero = 0;
+ ASSERT_EQ(zero, font_cache->EnumerationCacheSizeForTesting());
+
+ // The cache gets populated.
+ size_t enum_size_1 = font_cache->EnumerateAvailableFonts().size();
+ ASSERT_EQ(enum_size_1, font_cache->EnumerationCacheSizeForTesting());
+
+ // Invalidation clears the cache.
+ font_cache->Invalidate();
+ ASSERT_EQ(zero, font_cache->EnumerationCacheSizeForTesting());
+
+ // The cache gets re-populated.
+ size_t enum_size_2 = font_cache->EnumerateAvailableFonts().size();
+ ASSERT_EQ(enum_size_1, enum_size_2);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc b/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
index ecc8454ff02..b00c9e9b10d 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
@@ -45,16 +45,6 @@
namespace blink {
-namespace {
-sk_sp<SkFontMgr> FontManagerForSubType(
- FontFormatCheck::VariableFontSubType font_sub_type) {
- CHECK_NE(font_sub_type, FontFormatCheck::VariableFontSubType::kNotVariable);
- if (font_sub_type == FontFormatCheck::VariableFontSubType::kVariableCFF2)
- return WebFontTypefaceFactory::FreeTypeFontManager();
- return WebFontTypefaceFactory::FontManagerForVariations();
-}
-} // namespace
-
FontCustomPlatformData::FontCustomPlatformData(sk_sp<SkTypeface> typeface,
size_t data_size)
: base_typeface_(std::move(typeface)), data_size_(data_size) {}
@@ -97,9 +87,14 @@ FontPlatformData FontCustomPlatformData::GetFontPlatformData(
SkSetFourByteTag('w', 'd', 't', 'h'),
SkFloatToScalar(selection_capabilities.width.clampToRange(
selection_request.width))};
+ // CSS and OpenType have opposite definitions of direction of slant
+ // angle. In OpenType positive values turn counter-clockwise, negative
+ // values clockwise - in CSS positive values are clockwise rotations /
+ // skew. See note in https://drafts.csswg.org/css-fonts/#font-style-prop -
+ // map value from CSS to OpenType here.
SkFontArguments::Axis slant_axis = {
SkSetFourByteTag('s', 'l', 'n', 't'),
- SkFloatToScalar(selection_capabilities.slope.clampToRange(
+ SkFloatToScalar(-selection_capabilities.slope.clampToRange(
selection_request.slope))};
axes.push_back(weight_axis);
@@ -124,12 +119,8 @@ FontPlatformData FontCustomPlatformData::GetFontPlatformData(
axes.push_back(opsz_axis);
}
- int index;
- std::unique_ptr<SkStreamAsset> stream(base_typeface_->openStream(&index));
- sk_sp<SkTypeface> sk_variation_font(FontManagerForSubType(font_sub_type)
- ->makeFromStream(std::move(stream),
- SkFontArguments().setCollectionIndex(index)
- .setAxes(axes.data(), axes.size())));
+ sk_sp<SkTypeface> sk_variation_font(base_typeface_->makeClone(
+ SkFontArguments().setAxes(axes.data(), axes.size())));
if (sk_variation_font) {
return_typeface = sk_variation_font;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_data.h b/chromium/third_party/blink/renderer/platform/fonts/font_data.h
index 3535115d1e4..d79e7fd5a70 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_data.h
@@ -57,15 +57,6 @@ class PLATFORM_EXPORT FontData : public RefCounted<FontData> {
DISALLOW_COPY_AND_ASSIGN(FontData);
};
-#define DEFINE_FONT_DATA_TYPE_CASTS(thisType, predicate) \
- template <typename T> \
- inline thisType* To##thisType(const scoped_refptr<T>& fontData) { \
- return To##thisType(fontData.get()); \
- } \
- DEFINE_TYPE_CASTS(thisType, FontData, fontData, \
- fontData->IsSegmented() == predicate, \
- fontData.IsSegmented() == predicate)
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DATA_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc
index 060207ea5e5..680da1679bd 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc
@@ -132,7 +132,7 @@ bool FontDataCache::PurgeLeastRecentlyUsed(int count) {
auto end = inactive_font_data_.end();
auto it = inactive_font_data_.begin();
for (int i = 0; i < count && it != end; ++it, ++i) {
- scoped_refptr<SimpleFontData>& font_data = *it.Get();
+ const scoped_refptr<SimpleFontData>& font_data = *it;
cache_.erase(&(font_data->PlatformData()));
// We should not delete SimpleFontData here because deletion can modify
// m_inactiveFontData. See http://trac.webkit.org/changeset/44011
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description.cc b/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
index 6f20525f341..9e3ffe63834 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
@@ -436,8 +436,6 @@ String FontDescription::ToString(GenericFamilyType familyType) {
return "Cursive";
case GenericFamilyType::kFantasyFamily:
return "Fantasy";
- case GenericFamilyType::kPictographFamily:
- return "Pictograph";
}
return "Unknown";
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description.h b/chromium/third_party/blink/renderer/platform/fonts/font_description.h
index 8d19bd6873c..782b843707b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.h
@@ -63,8 +63,7 @@ class PLATFORM_EXPORT FontDescription {
kSansSerifFamily,
kMonospaceFamily,
kCursiveFamily,
- kFantasyFamily,
- kPictographFamily
+ kFantasyFamily
};
static String ToString(GenericFamilyType);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc b/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc
index 737580ef6bf..1bb413937f9 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc
@@ -63,6 +63,78 @@ TEST(FontDescriptionTest, TestHashCollision) {
}
}
+TEST(FontDescriptionTest, VariationSettingsIdentical) {
+ FontDescription a;
+ FontDescription b(a);
+
+ scoped_refptr<FontVariationSettings> settings_a =
+ FontVariationSettings::Create();
+ settings_a->Append(FontVariationAxis("test", 1));
+
+ scoped_refptr<FontVariationSettings> settings_b =
+ FontVariationSettings::Create();
+ settings_b->Append(FontVariationAxis("test", 1));
+
+ ASSERT_EQ(*settings_a, *settings_b);
+
+ a.SetVariationSettings(settings_a);
+ b.SetVariationSettings(settings_b);
+
+ ASSERT_EQ(a, b);
+
+ FontFaceCreationParams test_creation_params;
+ FontCacheKey cache_key_a = a.CacheKey(test_creation_params, false);
+ FontCacheKey cache_key_b = b.CacheKey(test_creation_params, false);
+
+ ASSERT_EQ(cache_key_a, cache_key_b);
+}
+
+TEST(FontDescriptionTest, VariationSettingsDifferent) {
+ FontDescription a;
+ FontDescription b(a);
+
+ scoped_refptr<FontVariationSettings> settings_a =
+ FontVariationSettings::Create();
+ settings_a->Append(FontVariationAxis("test", 1));
+
+ scoped_refptr<FontVariationSettings> settings_b =
+ FontVariationSettings::Create();
+ settings_b->Append(FontVariationAxis("0000", 1));
+
+ ASSERT_NE(*settings_a, *settings_b);
+
+ a.SetVariationSettings(settings_a);
+ b.SetVariationSettings(settings_b);
+
+ ASSERT_NE(a, b);
+
+ FontFaceCreationParams test_creation_params;
+
+ FontCacheKey cache_key_a = a.CacheKey(test_creation_params, false);
+ FontCacheKey cache_key_b = b.CacheKey(test_creation_params, false);
+
+ ASSERT_NE(cache_key_a, cache_key_b);
+
+ scoped_refptr<FontVariationSettings> second_settings_a =
+ FontVariationSettings::Create();
+ second_settings_a->Append(FontVariationAxis("test", 1));
+
+ scoped_refptr<FontVariationSettings> second_settings_b =
+ FontVariationSettings::Create();
+
+ ASSERT_NE(*second_settings_a, *second_settings_b);
+
+ a.SetVariationSettings(second_settings_a);
+ b.SetVariationSettings(second_settings_b);
+
+ ASSERT_NE(a, b);
+
+ FontCacheKey second_cache_key_a = a.CacheKey(test_creation_params, false);
+ FontCacheKey second_cache_key_b = b.CacheKey(test_creation_params, false);
+
+ ASSERT_NE(second_cache_key_a, second_cache_key_b);
+}
+
TEST(FontDescriptionTest, ToString) {
FontDescription description;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
index 1362d480c4b..eb076725400 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
@@ -153,7 +153,7 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
current_font_data_index_++;
if (!font_data->IsLoading()) {
scoped_refptr<SimpleFontData> non_segmented =
- const_cast<SimpleFontData*>(ToSimpleFontData(font_data));
+ const_cast<SimpleFontData*>(To<SimpleFontData>(font_data));
// The fontData object that we have here is tracked in m_fontList of
// FontFallbackList and gets released in the font cache when the
// FontFallbackList is destroyed.
@@ -165,7 +165,7 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
// Iterate over ranges of a segmented font below.
- const SegmentedFontData* segmented = ToSegmentedFontData(font_data);
+ const auto* segmented = To<SegmentedFontData>(font_data);
if (fallback_stage_ != kSegmentedFace) {
segmented_face_index_ = 0;
fallback_stage_ = kSegmentedFace;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
index fa1a455e591..d00d18310bb 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -39,22 +39,24 @@
namespace blink {
-FontFallbackList::FontFallbackList()
+FontFallbackList::FontFallbackList(FontSelector* font_selector)
: cached_primary_simple_font_data_(nullptr),
- font_selector_(nullptr),
- font_selector_version_(0),
+ font_selector_(font_selector),
+ font_selector_version_(font_selector ? font_selector->Version() : 0),
family_index_(0),
generation_(FontCache::GetFontCache()->Generation()),
- has_loading_fallback_(false) {}
+ has_loading_fallback_(false),
+ can_shape_word_by_word_(false),
+ can_shape_word_by_word_computed_(false) {}
-void FontFallbackList::Invalidate(FontSelector* font_selector) {
+void FontFallbackList::Invalidate() {
ReleaseFontData();
font_list_.clear();
cached_primary_simple_font_data_ = nullptr;
family_index_ = 0;
has_loading_fallback_ = false;
- if (font_selector_ != font_selector)
- font_selector_ = font_selector;
+ can_shape_word_by_word_ = false;
+ can_shape_word_by_word_computed_ = false;
font_selector_version_ = font_selector_ ? font_selector_->Version() : 0;
generation_ = FontCache::GetFontCache()->Generation();
}
@@ -65,13 +67,18 @@ void FontFallbackList::ReleaseFontData() {
if (!font_list_[i]->IsCustomFont()) {
DCHECK(!font_list_[i]->IsSegmented());
FontCache::GetFontCache()->ReleaseFontData(
- ToSimpleFontData(font_list_[i]));
+ To<SimpleFontData>(font_list_[i].get()));
}
}
shape_cache_.reset(); // Clear the weak pointer to the cache instance.
}
bool FontFallbackList::LoadingCustomFonts() const {
+ // This function is only used for style and layout invalidation purposes. We
+ // don't need it for invalidation when the feature below is enabled.
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled())
+ return false;
+
if (!has_loading_fallback_)
return false;
@@ -84,6 +91,8 @@ bool FontFallbackList::LoadingCustomFonts() const {
}
bool FontFallbackList::ShouldSkipDrawing() const {
+ DCHECK(IsValid());
+
if (!has_loading_fallback_)
return false;
@@ -96,7 +105,7 @@ bool FontFallbackList::ShouldSkipDrawing() const {
}
const SimpleFontData* FontFallbackList::DeterminePrimarySimpleFontData(
- const FontDescription& font_description) const {
+ const FontDescription& font_description) {
bool should_load_custom_font = true;
for (unsigned font_index = 0;; ++font_index) {
@@ -114,8 +123,8 @@ const SimpleFontData* FontFallbackList::DeterminePrimarySimpleFontData(
return last_resort_fallback;
}
- if (font_data->IsSegmented() &&
- !ToSegmentedFontData(font_data)->ContainsCharacter(kSpaceCharacter))
+ const auto* segmented = DynamicTo<SegmentedFontData>(font_data);
+ if (segmented && !segmented->ContainsCharacter(kSpaceCharacter))
continue;
const SimpleFontData* font_data_for_space =
@@ -128,8 +137,7 @@ const SimpleFontData* FontFallbackList::DeterminePrimarySimpleFontData(
if (!font_data_for_space->IsLoadingFallback())
return font_data_for_space;
- if (font_data->IsSegmented()) {
- const SegmentedFontData* segmented = ToSegmentedFontData(font_data);
+ if (segmented) {
for (unsigned i = 0; i < segmented->NumFaces(); i++) {
const SimpleFontData* range_font_data =
segmented->FaceAt(i)->FontData();
@@ -212,8 +220,9 @@ FallbackListCompositeKey FontFallbackList::CompositeKey(
if (result) {
bool is_unique_match = false;
key.Add(font_description.CacheKey(params, is_unique_match));
- if (!result->IsSegmented() && !result->IsCustomFont())
- FontCache::GetFontCache()->ReleaseFontData(ToSimpleFontData(result));
+ auto* font_data = DynamicTo<SimpleFontData>(result.get());
+ if (!font_data && !result->IsCustomFont())
+ FontCache::GetFontCache()->ReleaseFontData(font_data);
}
}
current_family = current_family->Next();
@@ -224,7 +233,12 @@ FallbackListCompositeKey FontFallbackList::CompositeKey(
const FontData* FontFallbackList::FontDataAt(
const FontDescription& font_description,
- unsigned realized_font_index) const {
+ unsigned realized_font_index) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
// This fallback font is already in our list.
if (realized_font_index < font_list_.size())
return font_list_[realized_font_index].get();
@@ -250,6 +264,34 @@ const FontData* FontFallbackList::FontDataAt(
return result.get();
}
+bool FontFallbackList::ComputeCanShapeWordByWord(
+ const FontDescription& font_description) {
+ if (!font_description.GetTypesettingFeatures())
+ return true;
+
+ const SimpleFontData* primary_font = PrimarySimpleFontData(font_description);
+ if (!primary_font)
+ return false;
+
+ const FontPlatformData& platform_data = primary_font->PlatformData();
+ TypesettingFeatures features = font_description.GetTypesettingFeatures();
+ return !platform_data.HasSpaceInLigaturesOrKerning(features);
+}
+
+bool FontFallbackList::CanShapeWordByWord(
+ const FontDescription& font_description) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
+ if (!can_shape_word_by_word_computed_) {
+ can_shape_word_by_word_ = ComputeCanShapeWordByWord(font_description);
+ can_shape_word_by_word_computed_ = true;
+ }
+ return can_shape_word_by_word_;
+}
+
bool FontFallbackList::IsValid() const {
if (!font_selector_)
return font_selector_version_ == 0;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h
index 4a604216015..6ef8c3774b8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/platform/fonts/shaping/shape_cache.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
@@ -42,13 +43,13 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
USING_FAST_MALLOC(FontFallbackList);
public:
- static scoped_refptr<FontFallbackList> Create() {
- return base::AdoptRef(new FontFallbackList());
+ static scoped_refptr<FontFallbackList> Create(FontSelector* font_selector) {
+ return base::AdoptRef(new FontFallbackList(font_selector));
}
~FontFallbackList() { ReleaseFontData(); }
bool IsValid() const;
- void Invalidate(FontSelector*);
+ void Invalidate();
bool LoadingCustomFonts() const;
bool ShouldSkipDrawing() const;
@@ -58,7 +59,12 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
unsigned FontSelectorVersion() const { return font_selector_version_; }
uint16_t Generation() const { return generation_; }
- ShapeCache* GetShapeCache(const FontDescription& font_description) const {
+ ShapeCache* GetShapeCache(const FontDescription& font_description) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
if (!shape_cache_) {
FallbackListCompositeKey key = CompositeKey(font_description);
shape_cache_ =
@@ -72,6 +78,11 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
const SimpleFontData* PrimarySimpleFontData(
const FontDescription& font_description) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
if (!cached_primary_simple_font_data_) {
cached_primary_simple_font_data_ =
DeterminePrimarySimpleFontData(font_description);
@@ -79,28 +90,37 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
}
return cached_primary_simple_font_data_;
}
- const FontData* FontDataAt(const FontDescription&, unsigned index) const;
+ const FontData* FontDataAt(const FontDescription&, unsigned index);
- FallbackListCompositeKey CompositeKey(const FontDescription&) const;
+ bool CanShapeWordByWord(const FontDescription&);
+
+ void SetCanShapeWordByWordForTesting(bool b) {
+ can_shape_word_by_word_ = b;
+ can_shape_word_by_word_computed_ = true;
+ }
private:
- FontFallbackList();
+ explicit FontFallbackList(FontSelector* font_selector);
scoped_refptr<FontData> GetFontData(const FontDescription&, int& family_index) const;
- const SimpleFontData* DeterminePrimarySimpleFontData(
- const FontDescription&) const;
+ const SimpleFontData* DeterminePrimarySimpleFontData(const FontDescription&);
+
+ FallbackListCompositeKey CompositeKey(const FontDescription&) const;
void ReleaseFontData();
+ bool ComputeCanShapeWordByWord(const FontDescription&);
- mutable Vector<scoped_refptr<FontData>, 1> font_list_;
- mutable const SimpleFontData* cached_primary_simple_font_data_;
- Persistent<FontSelector> font_selector_;
+ Vector<scoped_refptr<FontData>, 1> font_list_;
+ const SimpleFontData* cached_primary_simple_font_data_;
+ const Persistent<FontSelector> font_selector_;
unsigned font_selector_version_;
- mutable int family_index_;
+ int family_index_;
uint16_t generation_;
- mutable bool has_loading_fallback_ : 1;
- mutable base::WeakPtr<ShapeCache> shape_cache_;
+ bool has_loading_fallback_ : 1;
+ bool can_shape_word_by_word_ : 1;
+ bool can_shape_word_by_word_computed_ : 1;
+ base::WeakPtr<ShapeCache> shape_cache_;
DISALLOW_COPY_AND_ASSIGN(FontFallbackList);
};
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc
index ff2fd249e6c..ee1cb3b220c 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc
@@ -20,7 +20,9 @@ FontGlobalContext* FontGlobalContext::Get(CreateIfNeeded create_if_needed) {
return *font_persistent;
}
-FontGlobalContext::FontGlobalContext() : harfbuzz_font_funcs_(nullptr) {}
+FontGlobalContext::FontGlobalContext()
+ : harfbuzz_font_funcs_skia_advances_(nullptr),
+ harfbuzz_font_funcs_harfbuzz_advances_(nullptr) {}
FontGlobalContext::~FontGlobalContext() = default;
@@ -32,6 +34,15 @@ FontUniqueNameLookup* FontGlobalContext::GetFontUniqueNameLookup() {
return Get()->font_unique_name_lookup_.get();
}
+HarfBuzzFontCache* FontGlobalContext::GetHarfBuzzFontCache() {
+ std::unique_ptr<HarfBuzzFontCache>& global_context_harfbuzz_font_cache =
+ Get()->harfbuzz_font_cache_;
+ if (!global_context_harfbuzz_font_cache) {
+ global_context_harfbuzz_font_cache = std::make_unique<HarfBuzzFontCache>();
+ }
+ return global_context_harfbuzz_font_cache.get();
+}
+
void FontGlobalContext::ClearMemory() {
if (!Get(kDoNotCreate))
return;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h
index 63c3c861d6e..37e743c2264 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_GLOBAL_CONTEXT_H_
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
-#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/text/layout_locale.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -17,6 +16,7 @@ namespace blink {
class FontCache;
class FontUniqueNameLookup;
+class HarfBuzzFontCache;
enum CreateIfNeeded { kDoNotCreate, kCreate };
@@ -30,16 +30,27 @@ class PLATFORM_EXPORT FontGlobalContext {
static inline FontCache& GetFontCache() { return Get()->font_cache_; }
- static inline HarfBuzzFontCache& GetHarfBuzzFontCache() {
- return Get()->harfbuzz_font_cache_;
- }
+ static HarfBuzzFontCache* GetHarfBuzzFontCache();
+
+ enum HorizontalAdvanceSource {
+ kSkiaHorizontalAdvances,
+ kHarfBuzzHorizontalAdvances
+ };
- static hb_font_funcs_t* GetHarfBuzzFontFuncs() {
- return Get()->harfbuzz_font_funcs_;
+ static hb_font_funcs_t* GetHarfBuzzFontFuncs(
+ HorizontalAdvanceSource advance_source) {
+ if (advance_source == kHarfBuzzHorizontalAdvances) {
+ return Get()->harfbuzz_font_funcs_harfbuzz_advances_;
+ }
+ return Get()->harfbuzz_font_funcs_skia_advances_;
}
- static void SetHarfBuzzFontFuncs(hb_font_funcs_t* funcs) {
- Get()->harfbuzz_font_funcs_ = funcs;
+ static void SetHarfBuzzFontFuncs(HorizontalAdvanceSource advance_source,
+ hb_font_funcs_t* funcs) {
+ if (advance_source == kHarfBuzzHorizontalAdvances) {
+ Get()->harfbuzz_font_funcs_harfbuzz_advances_ = funcs;
+ }
+ Get()->harfbuzz_font_funcs_skia_advances_ = funcs;
}
static FontUniqueNameLookup* GetFontUniqueNameLookup();
@@ -54,8 +65,9 @@ class PLATFORM_EXPORT FontGlobalContext {
~FontGlobalContext();
FontCache font_cache_;
- HarfBuzzFontCache harfbuzz_font_cache_;
- hb_font_funcs_t* harfbuzz_font_funcs_;
+ std::unique_ptr<HarfBuzzFontCache> harfbuzz_font_cache_;
+ hb_font_funcs_t* harfbuzz_font_funcs_skia_advances_;
+ hb_font_funcs_t* harfbuzz_font_funcs_harfbuzz_advances_;
std::unique_ptr<FontUniqueNameLookup> font_unique_name_lookup_;
DISALLOW_COPY_AND_ASSIGN(FontGlobalContext);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
index 5e1005a2e4d..a9a0511de03 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
@@ -28,6 +28,18 @@ HashSet<T> Intersection(const HashSet<T>& a, const HashSet<T>& b) {
namespace blink {
+FontMatchingMetrics::FontMatchingMetrics(bool top_level,
+ ukm::UkmRecorder* ukm_recorder,
+ ukm::SourceId source_id)
+ : top_level_(top_level),
+ ukm_recorder_(ukm_recorder),
+ source_id_(source_id) {
+ // Estimate of average page font use from anecdotal browsing session.
+ constexpr unsigned kEstimatedFontCount = 7;
+ local_fonts_succeeded_.ReserveCapacityForSize(kEstimatedFontCount);
+ local_fonts_failed_.ReserveCapacityForSize(kEstimatedFontCount);
+}
+
void FontMatchingMetrics::ReportSuccessfulFontFamilyMatch(
const AtomicString& font_family_name) {
successful_font_families_.insert(font_family_name);
@@ -48,6 +60,16 @@ void FontMatchingMetrics::ReportWebFontFamily(
web_font_families_.insert(font_family_name);
}
+void FontMatchingMetrics::ReportSuccessfulLocalFontMatch(
+ const AtomicString& font_name) {
+ local_fonts_succeeded_.insert(font_name);
+}
+
+void FontMatchingMetrics::ReportFailedLocalFontMatch(
+ const AtomicString& font_name) {
+ local_fonts_failed_.insert(font_name);
+}
+
void FontMatchingMetrics::PublishUkmMetrics() {
ukm::builders::FontMatchAttempts(source_id_)
.SetLoadContext(top_level_ ? kTopLevel : kSubFrame)
@@ -63,6 +85,10 @@ void FontMatchingMetrics::PublishUkmMetrics() {
.SetWebFontFamilyFailures(ukm::GetExponentialBucketMin(
Intersection(failed_font_families_, web_font_families_).size(),
kUkmFontLoadCountBucketSpacing))
+ .SetLocalFontFailures(ukm::GetExponentialBucketMin(
+ local_fonts_failed_.size(), kUkmFontLoadCountBucketSpacing))
+ .SetLocalFontSuccesses(ukm::GetExponentialBucketMin(
+ local_fonts_succeeded_.size(), kUkmFontLoadCountBucketSpacing))
.Record(ukm_recorder_);
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
index c31be1c51b5..59827c38e53 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
@@ -27,10 +27,7 @@ class PLATFORM_EXPORT FontMatchingMetrics {
public:
FontMatchingMetrics(bool top_level,
ukm::UkmRecorder* ukm_recorder,
- ukm::SourceId source_id)
- : top_level_(top_level),
- ukm_recorder_(ukm_recorder),
- source_id_(source_id) {}
+ ukm::SourceId source_id);
// Called when a page attempts to match a font family, and the font family is
// available.
@@ -46,6 +43,14 @@ class PLATFORM_EXPORT FontMatchingMetrics {
// Called when a page attempts to match a web font family.
void ReportWebFontFamily(const AtomicString& font_family_name);
+ // Reports a font listed in a @font-face src:local rule that successfully
+ // matched.
+ void ReportSuccessfulLocalFontMatch(const AtomicString& font_name);
+
+ // Reports a font listed in a @font-face src:local rule that didn't
+ // successfully match.
+ void ReportFailedLocalFontMatch(const AtomicString& font_name);
+
// Publishes the number of font family matches attempted (both successful and
// otherwise) to UKM. Called at page unload.
void PublishUkmMetrics();
@@ -63,6 +68,12 @@ class PLATFORM_EXPORT FontMatchingMetrics {
// Web font families the page attempted to match.
HashSet<AtomicString> web_font_families_;
+ // @font-face src:local fonts that successfully matched.
+ HashSet<AtomicString> local_fonts_succeeded_;
+
+ // @font-face src:local fonts that didn't successfully match.
+ HashSet<AtomicString> local_fonts_failed_;
+
// True if this FontMatchingMetrics instance is for a top-level frame, false
// otherwise.
const bool top_level_ = false;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
index 0eaaf9e94fb..0861e6e15c8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
@@ -71,6 +71,15 @@ class PLATFORM_EXPORT FontSelector : public FontCacheClient {
virtual void ReportFailedFontFamilyMatch(
const AtomicString& font_family_name) = 0;
+ // Called when a page attempts to match a font name via a @font-face src:local
+ // rule, and the font is available.
+ virtual void ReportSuccessfulLocalFontMatch(
+ const AtomicString& font_name) = 0;
+
+ // Called when a page attempts to match a font name via a @font-face src:local
+ // rule, and the font is not available.
+ virtual void ReportFailedLocalFontMatch(const AtomicString& font_name) = 0;
+
virtual void RegisterForInvalidationCallbacks(FontSelectorClient*) = 0;
virtual void UnregisterForInvalidationCallbacks(FontSelectorClient*) = 0;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h b/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h
index 649b054fb68..b85832903ab 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h
@@ -17,7 +17,7 @@ class FontSelectorClient : public GarbageCollectedMixin {
virtual void FontsNeedUpdate(FontSelector*) = 0;
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc b/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
index 62d92b7f412..604a895c075 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
@@ -19,7 +19,6 @@ sk_sp<SkTypeface> FontUniqueNameLookupLinux::MatchUniqueName(
if (!Platform::Current()->GetSandboxSupport()) {
LOG(ERROR) << "@font-face src: local() instantiation only available when "
"connected to browser process.";
- DCHECK(Platform::Current()->GetSandboxSupport());
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h b/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
index 1816f6f49d7..b5f3ffe9738 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
@@ -9,6 +9,7 @@ namespace blink {
bool CoreTextVersionSupportsVariations();
bool CoreTextVersionSupportsColrCpal();
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_CORE_TEXT_FONT_FORMAT_SUPPORT_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
index f50fc36281d..fedd1b91424 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
@@ -29,8 +29,11 @@
#import "third_party/blink/renderer/platform/fonts/font_cache.h"
-#import <AppKit/AppKit.h>
#include <memory>
+
+#import <AppKit/AppKit.h>
+#import <CoreText/CoreText.h>
+
#include "base/location.h"
#include "base/mac/foundation_util.h"
#include "third_party/blink/public/platform/platform.h"
@@ -59,6 +62,22 @@
inLanguage:(id)useNil;
@end
+namespace {
+
+NSString* GetLocalizedString(CTFontDescriptorRef fd, CFStringRef attribute) {
+ base::ScopedCFTypeRef<CFStringRef> cf_str(base::mac::CFCast<CFStringRef>(
+ CTFontDescriptorCopyLocalizedAttribute(fd, attribute, nullptr)));
+ return [base::mac::CFToNSCast(cf_str.release()) autorelease];
+}
+
+NSString* GetString(CTFontDescriptorRef fd, CFStringRef attribute) {
+ base::ScopedCFTypeRef<CFStringRef> cf_str(base::mac::CFCast<CFStringRef>(
+ CTFontDescriptorCopyAttribute(fd, attribute)));
+ return [base::mac::CFToNSCast(cf_str.release()) autorelease];
+}
+
+} // namespace
+
namespace blink {
const char kColorEmojiFontMac[] = "Apple Color Emoji";
@@ -221,9 +240,12 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
substitute_font, platform_data.size(), synthetic_bold,
(traits & NSFontItalicTrait) &&
!(substitute_font_traits & NSFontItalicTrait),
- platform_data.Orientation(),
+ platform_data.Orientation(), font_description.FontOpticalSizing(),
nullptr); // No variation paramaters in fallback.
+ if (!alternate_font)
+ return nullptr;
+
return FontDataFromFontPlatformData(alternate_font.get(), kDoNotRetain);
}
@@ -295,11 +317,43 @@ std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
// the returned FontPlatformData since it will not have a valid SkTypeface.
std::unique_ptr<FontPlatformData> platform_data = FontPlatformDataFromNSFont(
platform_font, size, synthetic_bold, synthetic_italic,
- font_description.Orientation(), font_description.VariationSettings());
- if (!platform_data->Typeface()) {
+ font_description.Orientation(), font_description.FontOpticalSizing(),
+ font_description.VariationSettings());
+ if (!platform_data || !platform_data->Typeface()) {
return nullptr;
}
return platform_data;
}
+std::vector<FontEnumerationEntry> FontCache::EnumeratePlatformAvailableFonts() {
+ DCHECK(RuntimeEnabledFeatures::FontAccessEnabled());
+ @autoreleasepool {
+ std::vector<FontEnumerationEntry> output;
+
+ CFTypeRef values[1] = {kCFBooleanTrue};
+ base::ScopedCFTypeRef<CFDictionaryRef> options(CFDictionaryCreate(
+ kCFAllocatorDefault,
+ (const void**)kCTFontCollectionRemoveDuplicatesOption,
+ (const void**)&values,
+ /*numValues=*/1, &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ base::ScopedCFTypeRef<CTFontCollectionRef> collection(
+ CTFontCollectionCreateFromAvailableFonts(options));
+
+ base::ScopedCFTypeRef<CFArrayRef> font_descs(
+ CTFontCollectionCreateMatchingFontDescriptors(collection));
+
+ for (CFIndex i = 0; i < CFArrayGetCount(font_descs); ++i) {
+ CTFontDescriptorRef fd = base::mac::CFCast<CTFontDescriptorRef>(
+ CFArrayGetValueAtIndex(font_descs, i));
+ NSString* postscript_name = GetString(fd, kCTFontNameAttribute);
+ NSString* full_name = GetLocalizedString(fd, kCTFontDisplayNameAttribute);
+ NSString* family = GetLocalizedString(fd, kCTFontFamilyNameAttribute);
+ output.push_back(FontEnumerationEntry{String(postscript_name),
+ String(full_name), String(family)});
+ }
+ return output;
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
index 8d01704041c..cf25ba022f2 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -46,7 +46,7 @@
namespace {
-static CGFloat toYosemiteFontWeight(blink::FontSelectionValue font_weight) {
+static CGFloat toFontWeight(blink::FontSelectionValue font_weight) {
static uint64_t ns_font_weights[] = {
0xbfe99999a0000000, // NSFontWeightUltraLight
0xbfe3333340000000, // NSFontWeightThin
@@ -181,8 +181,7 @@ NSFont* MatchNSFontFamily(const AtomicString& desired_family_string,
// On OSX 10.10+, the default system font has more weights.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
- font = [NSFont systemFontOfSize:size
- weight:toYosemiteFontWeight(desired_weight)];
+ font = [NSFont systemFontOfSize:size weight:toFontWeight(desired_weight)];
#pragma clang diagnostic pop
if (desired_traits & IMPORTANT_FONT_TRAITS)
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
index b1224beff2c..cd0e338cdb5 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
@@ -31,6 +31,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_FONT_PLATFORM_DATA_MAC_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_FONT_PLATFORM_DATA_MAC_H_
+#include "third_party/blink/renderer/platform/fonts/font_optical_sizing.h"
+
#include <memory>
@class NSFont;
@@ -47,6 +49,7 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
bool synthetic_bold,
bool synthetic_italic,
FontOrientation,
+ OpticalSizing,
FontVariationSettings*);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
index 16bcce4ba40..9bc59e46e5e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
@@ -27,21 +27,26 @@
#import <AvailabilityMacros.h>
#include "base/mac/foundation_util.h"
-#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "base/stl_util.h"
#import "third_party/blink/public/platform/mac/web_sandbox_support.h"
#import "third_party/blink/public/platform/platform.h"
#import "third_party/blink/renderer/platform/fonts/font.h"
#import "third_party/blink/renderer/platform/fonts/font_platform_data.h"
+#import "third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h"
#import "third_party/blink/renderer/platform/fonts/opentype/font_settings.h"
#import "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
#import "third_party/blink/renderer/platform/web_test_support.h"
#import "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#import "third_party/skia/include/core/SkFont.h"
#import "third_party/skia/include/core/SkStream.h"
+#import "third_party/skia/include/core/SkTypes.h"
#import "third_party/skia/include/ports/SkTypeface_mac.h"
+namespace {
+constexpr SkFourByteTag kOpszTag = SkSetFourByteTag('o', 'p', 's', 'z');
+}
+
namespace blink {
static bool CanLoadInProcess(NSFont* ns_font) {
@@ -53,10 +58,10 @@ static bool CanLoadInProcess(NSFont* ns_font) {
return ![font_name isEqualToString:@"LastResort"];
}
-static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
- static CTFontDescriptorRef descriptor;
- if (descriptor)
- return descriptor;
+static CFDictionaryRef CascadeToLastResortFontAttributes() {
+ static CFDictionaryRef attributes;
+ if (attributes)
+ return attributes;
base::ScopedCFTypeRef<CTFontDescriptorRef> last_resort(
CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0));
@@ -67,13 +72,10 @@ static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
const void* keys[] = {kCTFontCascadeListAttribute};
const void* values[] = {values_array};
- base::ScopedCFTypeRef<CFDictionaryRef> attributes(CFDictionaryCreate(
+ attributes = CFDictionaryCreate(
kCFAllocatorDefault, keys, values, base::size(keys),
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-
- descriptor = CTFontDescriptorCreateWithAttributes(attributes);
-
- return descriptor;
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ return attributes;
}
static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
@@ -88,20 +90,23 @@ static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
return nullptr;
}
- CGFontRef loaded_cg_font;
+ base::ScopedCFTypeRef<CTFontDescriptorRef> loaded_data_descriptor;
uint32_t font_id;
if (!sandbox_support->LoadFont(base::mac::NSToCFCast(ns_font),
- &loaded_cg_font, &font_id)) {
+ &loaded_data_descriptor, &font_id)) {
// TODO crbug.com/461279: Make this appear in the inspector console?
DLOG(ERROR)
<< "Loading user font \"" << [[ns_font familyName] UTF8String]
<< "\" from non system location failed. Corrupt or missing font file?";
return nullptr;
}
- base::ScopedCFTypeRef<CGFontRef> cg_font(loaded_cg_font);
- base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithGraphicsFont(
- cg_font, text_size, 0, CascadeToLastResortFontDescriptor()));
- sk_sp<SkTypeface> return_font(SkCreateTypefaceFromCTFont(ct_font, cg_font));
+
+ base::ScopedCFTypeRef<CTFontDescriptorRef> data_descriptor_with_cascade(
+ CTFontDescriptorCreateCopyWithAttributes(
+ loaded_data_descriptor, CascadeToLastResortFontAttributes()));
+ base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithFontDescriptor(
+ data_descriptor_with_cascade.get(), text_size, 0));
+ sk_sp<SkTypeface> return_font = SkMakeTypefaceFromCTFont(ct_font);
if (!return_font.get())
// TODO crbug.com/461279: Make this appear in the inspector console?
@@ -117,11 +122,12 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
bool synthetic_bold,
bool synthetic_italic,
FontOrientation orientation,
+ OpticalSizing optical_sizing,
FontVariationSettings* variation_settings) {
DCHECK(ns_font);
sk_sp<SkTypeface> typeface;
if (CanLoadInProcess(ns_font)) {
- typeface.reset(SkCreateTypefaceFromCTFont(base::mac::NSToCFCast(ns_font)));
+ typeface = SkMakeTypefaceFromCTFont(base::mac::NSToCFCast(ns_font));
} else {
// In process loading fails for cases where third party font manager
// software registers fonts in non system locations such as /Library/Fonts
@@ -129,26 +135,79 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
typeface = LoadFromBrowserProcess(ns_font, size);
}
- if (variation_settings && variation_settings->size() < UINT16_MAX) {
- SkFontArguments::Axis axes[variation_settings->size()];
- for (size_t i = 0; i < variation_settings->size(); ++i) {
- AtomicString feature_tag = variation_settings->at(i).Tag();
- axes[i] = {AtomicStringToFourByteTag(feature_tag),
- SkFloatToScalar(variation_settings->at(i).Value())};
+ auto make_typeface_fontplatformdata = [&typeface, &size, &synthetic_bold,
+ &synthetic_italic, &orientation]() {
+ return std::make_unique<FontPlatformData>(
+ std::move(typeface), std::string(), size, synthetic_bold,
+ synthetic_italic, orientation);
+ };
+
+ wtf_size_t valid_configured_axes =
+ variation_settings && variation_settings->size() < UINT16_MAX
+ ? variation_settings->size()
+ : 0;
+
+ // No variable font requested, return static font.
+ if (!valid_configured_axes && optical_sizing == kNoneOpticalSizing)
+ return make_typeface_fontplatformdata();
+
+ if (!typeface)
+ return nullptr;
+
+ int existing_axes = typeface->getVariationDesignPosition(nullptr, 0);
+ // Don't apply variation parameters if the font does not have axes or we
+ // fail to retrieve the existing ones.
+ if (existing_axes <= 0)
+ return make_typeface_fontplatformdata();
+
+ Vector<SkFontArguments::VariationPosition::Coordinate> coordinates_to_set;
+ coordinates_to_set.resize(existing_axes);
+
+ if (typeface->getVariationDesignPosition(coordinates_to_set.data(),
+ existing_axes) != existing_axes) {
+ return make_typeface_fontplatformdata();
+ }
+
+ // Iterate over the font's axes and find a missing tag from variation
+ // settings, special case opsz, track the number of axes reconfigured.
+ bool axes_reconfigured = false;
+ for (auto& coordinate : coordinates_to_set) {
+ // Set opsz to font size but allow having it overriden by
+ // font-variation-settings in case it has 'opsz'.
+ if (coordinate.axis == kOpszTag && optical_sizing == kAutoOpticalSizing) {
+ if (coordinate.value != SkFloatToScalar(size)) {
+ coordinate.value = SkFloatToScalar(size);
+ axes_reconfigured = true;
+ }
+ }
+ FontVariationAxis found_variation_setting(AtomicString(), 0);
+ if (variation_settings &&
+ variation_settings->FindPair(FourByteTagToAtomicString(coordinate.axis),
+ &found_variation_setting)) {
+ if (coordinate.value != found_variation_setting.Value()) {
+ coordinate.value = found_variation_setting.Value();
+ axes_reconfigured = true;
+ }
}
- sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
- // TODO crbug.com/670246: Refactor this to a future Skia API that acccepts
- // axis parameters on system fonts directly.
- typeface = fm->makeFromStream(
- typeface->openStream(nullptr)->duplicate(),
- SkFontArguments().setAxes(axes, variation_settings->size()));
}
- return std::make_unique<FontPlatformData>(
- std::move(typeface),
- std::string(), // family_ doesn't exist on Mac, this avoids conversion
- // from NSString which requires including a //base header
- size, synthetic_bold, synthetic_italic, orientation);
+ if (!axes_reconfigured) {
+ // No variable axes touched, return the previous typeface.
+ return make_typeface_fontplatformdata();
+ }
+
+ SkFontArguments::VariationPosition variation_design_position{
+ coordinates_to_set.data(), coordinates_to_set.size()};
+
+ sk_sp<SkTypeface> cloned_typeface(typeface->makeClone(
+ SkFontArguments().setVariationDesignPosition(variation_design_position)));
+
+ if (!cloned_typeface) {
+ // Applying varition parameters failed, return original typeface.
+ return make_typeface_fontplatformdata();
+ }
+ typeface = cloned_typeface;
+ return make_typeface_fontplatformdata();
}
void FontPlatformData::SetupSkFont(SkFont* skfont,
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
index 964943fa0b2..2c11652ffcf 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
@@ -4,32 +4,21 @@
#include "third_party/blink/renderer/platform/fonts/opentype/font_format_check.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-
// Include HarfBuzz to have a cross-platform way to retrieve table tags without
// having to rely on the platform being able to instantiate this font format.
#include <hb.h>
-namespace blink {
-
-namespace {
-
-struct HarfbuzzBlobDestroyer {
- inline void operator()(hb_blob_t* blob) { hb_blob_destroy(blob); }
-};
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
+#include "third_party/skia/include/core/SkTypeface.h"
-struct HarfbuzzFaceDestroyer {
- inline void operator()(hb_face_t* face) { hb_face_destroy(face); }
-};
-} // namespace
+namespace blink {
FontFormatCheck::FontFormatCheck(sk_sp<SkData> sk_data) {
- std::unique_ptr<hb_blob_t, HarfbuzzBlobDestroyer> font_blob(hb_blob_create(
+ HbScoped<hb_blob_t> font_blob(hb_blob_create(
reinterpret_cast<const char*>(sk_data->bytes()), sk_data->size(),
HB_MEMORY_MODE_READONLY, nullptr, nullptr));
- std::unique_ptr<hb_face_t, HarfbuzzFaceDestroyer> face(
- hb_face_create(font_blob.get(), 0));
+ HbScoped<hb_face_t> face(hb_face_create(font_blob.get(), 0));
unsigned table_count = 0;
table_count = hb_face_get_table_tags(face.get(), 0, nullptr, nullptr);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc
index 733d76d0db4..84c34be7a02 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/fonts/opentype/font_settings.h"
#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hasher.h"
@@ -16,6 +17,13 @@ uint32_t AtomicStringToFourByteTag(AtomicString tag) {
return (((tag[0]) << 24) | ((tag[1]) << 16) | ((tag[2]) << 8) | (tag[3]));
}
+AtomicString FourByteTagToAtomicString(uint32_t tag) {
+ constexpr size_t tag_size = 4;
+ LChar tag_string[tag_size] = {(tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
+ (tag >> 8) & 0xFF, tag & 0xFF};
+ return AtomicString(tag_string, tag_size);
+}
+
unsigned FontVariationSettings::GetHash() const {
unsigned computed_hash = size() ? 5381 : 0;
unsigned num_features = size();
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h
index 10ab2aec21e..ea5b8c942f8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h
@@ -17,6 +17,7 @@
namespace blink {
uint32_t AtomicStringToFourByteTag(AtomicString tag);
+AtomicString FourByteTagToAtomicString(uint32_t tag);
template <typename T>
class FontTagValuePair {
@@ -34,7 +35,7 @@ class FontTagValuePair {
private:
AtomicString tag_;
- const T value_;
+ T value_;
};
template <typename T>
@@ -47,6 +48,7 @@ class FontSettings {
bool operator==(const FontSettings& other) const {
return list_ == other.list_;
}
+ bool operator!=(const FontSettings& other) const { return !(*this == other); }
String ToString() const {
StringBuilder builder;
wtf_size_t num_features = size();
@@ -60,6 +62,20 @@ class FontSettings {
}
return builder.ToString();
}
+
+ bool FindPair(AtomicString tag, T* found_pair) const {
+ if (!found_pair)
+ return false;
+
+ for (auto& pair : list_) {
+ if (pair.Tag() == tag) {
+ *found_pair = pair;
+ return true;
+ }
+ }
+ return false;
+ }
+
const T* begin() const { return list_.begin(); }
const T* end() const { return list_.end(); }
T* begin() { return list_.begin(); }
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc
index 5c2fa7d94e8..6a3e0457ac3 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc
@@ -61,4 +61,30 @@ TEST(FontSettingsTest, ToString) {
}
}
+TEST(FontSettingsTest, FindTest) {
+ {
+ scoped_refptr<FontVariationSettings> settings =
+ MakeSettings<FontVariationSettings, FontVariationAxis>(
+ {FontVariationAxis{"a", 42}, FontVariationAxis{"b", 8118}});
+ FontVariationAxis found_axis(AtomicString(), 0);
+ ASSERT_FALSE(settings->FindPair("c", &found_axis));
+ ASSERT_FALSE(settings->FindPair("ddddd", &found_axis));
+ ASSERT_FALSE(settings->FindPair("", &found_axis));
+ ASSERT_EQ(found_axis.Value(), 0);
+ ASSERT_TRUE(settings->FindPair("a", &found_axis));
+ ASSERT_EQ(found_axis.Tag(), AtomicString("a"));
+ ASSERT_EQ(found_axis.Value(), 42);
+ ASSERT_TRUE(settings->FindPair("b", &found_axis));
+ ASSERT_EQ(found_axis.Tag(), AtomicString("b"));
+ ASSERT_EQ(found_axis.Value(), 8118);
+ }
+}
+
+TEST(FontSettingsTest, FindTestEmpty) {
+ scoped_refptr<FontVariationSettings> settings =
+ MakeSettings<FontVariationSettings, FontVariationAxis>({});
+ FontVariationAxis found_axis(AtomicString(), 0);
+ ASSERT_FALSE(settings->FindPair("a", &found_axis));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc
index 4c18c37138f..542975a52ba 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h"
-
-#include <hb-aat.h>
+// clang-format off
#include <hb.h>
+#include <hb-aat.h>
+// clang-format on
+
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h"
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
namespace blink {
@@ -138,12 +141,10 @@ OpenTypeCapsSupport::FontFormat OpenTypeCapsSupport::GetFontFormat() const {
hb_face_t* hb_face = hb_font_get_face(
harfbuzz_face_->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout));
- std::unique_ptr<hb_blob_t, decltype(&hb_blob_destroy)> morx_blob(
- hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 'x')),
- hb_blob_destroy);
- std::unique_ptr<hb_blob_t, decltype(&hb_blob_destroy)> mort_blob(
- hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 't')),
- hb_blob_destroy);
+ HbScoped<hb_blob_t> morx_blob(
+ hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 'x')));
+ HbScoped<hb_blob_t> mort_blob(
+ hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 't')));
// TODO(crbug.com/911149): Use hb_aat_layout_has_substitution() for
// has_morx_or_mort and hb_ot_layout_has_substitution() for has_gsub once is
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h
new file mode 100644
index 00000000000..af3cc059903
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h
@@ -0,0 +1,45 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_STRETCH_DATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_STRETCH_DATA_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/fonts/glyph.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT OpenTypeMathStretchData {
+ public:
+ enum StretchAxis : uint8_t { Horizontal = 0, Vertical = 1 };
+
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathGlyphVariantRecordFormat
+ // Note: Only variantGlyph is considered as using advanceMeasurement can lead
+ // to inconsistent values compared to what SimpleFontData returns.
+ using GlyphVariantRecord = Glyph;
+
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#glyphPartRecord
+ struct GlyphPartRecord {
+ Glyph glyph;
+ float start_connector_length;
+ float end_connector_length;
+ float full_advance;
+ bool is_extender;
+ };
+
+ // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table
+ struct AssemblyParameters {
+ float connector_overlap{0};
+ unsigned repetition_count{0};
+ unsigned glyph_count{0};
+ float stretch_size{0};
+ Vector<GlyphPartRecord> parts;
+ };
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_STRETCH_DATA_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc
new file mode 100644
index 00000000000..80d94665ab7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc
@@ -0,0 +1,258 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+
+// clang-format off
+#include <hb.h>
+#include <hb-ot.h>
+// clang-format on
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
+
+namespace {
+// HarfBuzz' hb_position_t is a 16.16 fixed-point value.
+float HarfBuzzUnitsToFloat(hb_position_t value) {
+ static const float kFloatToHbRatio = 1.0f / (1 << 16);
+ return kFloatToHbRatio * value;
+}
+
+// Latin Modern, STIX Two, XITS, Asana, Deja Vu, Libertinus and TeX Gyre fonts
+// provide at most 13 size variant and 5 assembly parts.
+// See https://chromium-review.googlesource.com/c/chromium/src/+/2074678
+unsigned kMaxHarfBuzzRecords = 20;
+
+hb_direction_t HarfBuzzDirection(
+ blink::OpenTypeMathStretchData::StretchAxis stretch_axis) {
+ return stretch_axis == blink::OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? HB_DIRECTION_LTR
+ : HB_DIRECTION_BTT;
+}
+
+} // namespace
+
+namespace blink {
+
+bool OpenTypeMathSupport::HasMathData(const HarfBuzzFace* harfbuzz_face) {
+ if (!harfbuzz_face)
+ return false;
+
+ hb_font_t* font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ DCHECK(font);
+ hb_face_t* face = hb_font_get_face(font);
+ DCHECK(face);
+
+ return hb_ot_math_has_data(face);
+}
+
+base::Optional<float> OpenTypeMathSupport::MathConstant(
+ const HarfBuzzFace* harfbuzz_face,
+ MathConstants constant) {
+ if (!HasMathData(harfbuzz_face))
+ return base::nullopt;
+
+ hb_font_t* font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ DCHECK(font);
+
+ hb_position_t harfbuzz_value = hb_ot_math_get_constant(
+ font, static_cast<hb_ot_math_constant_t>(constant));
+
+ switch (constant) {
+ case kScriptPercentScaleDown:
+ case kScriptScriptPercentScaleDown:
+ case kRadicalDegreeBottomRaisePercent:
+ return base::Optional<float>(harfbuzz_value / 100.0);
+ case kDelimitedSubFormulaMinHeight:
+ case kDisplayOperatorMinHeight:
+ case kMathLeading:
+ case kAxisHeight:
+ case kAccentBaseHeight:
+ case kFlattenedAccentBaseHeight:
+ case kSubscriptShiftDown:
+ case kSubscriptTopMax:
+ case kSubscriptBaselineDropMin:
+ case kSuperscriptShiftUp:
+ case kSuperscriptShiftUpCramped:
+ case kSuperscriptBottomMin:
+ case kSuperscriptBaselineDropMax:
+ case kSubSuperscriptGapMin:
+ case kSuperscriptBottomMaxWithSubscript:
+ case kSpaceAfterScript:
+ case kUpperLimitGapMin:
+ case kUpperLimitBaselineRiseMin:
+ case kLowerLimitGapMin:
+ case kLowerLimitBaselineDropMin:
+ case kStackTopShiftUp:
+ case kStackTopDisplayStyleShiftUp:
+ case kStackBottomShiftDown:
+ case kStackBottomDisplayStyleShiftDown:
+ case kStackGapMin:
+ case kStackDisplayStyleGapMin:
+ case kStretchStackTopShiftUp:
+ case kStretchStackBottomShiftDown:
+ case kStretchStackGapAboveMin:
+ case kStretchStackGapBelowMin:
+ case kFractionNumeratorShiftUp:
+ case kFractionNumeratorDisplayStyleShiftUp:
+ case kFractionDenominatorShiftDown:
+ case kFractionDenominatorDisplayStyleShiftDown:
+ case kFractionNumeratorGapMin:
+ case kFractionNumDisplayStyleGapMin:
+ case kFractionRuleThickness:
+ case kFractionDenominatorGapMin:
+ case kFractionDenomDisplayStyleGapMin:
+ case kSkewedFractionHorizontalGap:
+ case kSkewedFractionVerticalGap:
+ case kOverbarVerticalGap:
+ case kOverbarRuleThickness:
+ case kOverbarExtraAscender:
+ case kUnderbarVerticalGap:
+ case kUnderbarRuleThickness:
+ case kUnderbarExtraDescender:
+ case kRadicalVerticalGap:
+ case kRadicalDisplayStyleVerticalGap:
+ case kRadicalRuleThickness:
+ case kRadicalExtraAscender:
+ case kRadicalKernBeforeDegree:
+ case kRadicalKernAfterDegree:
+ return base::Optional<float>(HarfBuzzUnitsToFloat(harfbuzz_value));
+ default:
+ NOTREACHED();
+ }
+ return base::nullopt;
+}
+
+base::Optional<float> OpenTypeMathSupport::MathItalicCorrection(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph glyph) {
+ if (!harfbuzz_face)
+ return base::nullopt;
+
+ hb_font_t* font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+
+ return base::Optional<float>(HarfBuzzUnitsToFloat(
+ hb_ot_math_get_glyph_italics_correction(font, glyph)));
+}
+
+template <typename HarfBuzzRecordType>
+using GetHarfBuzzMathRecordGetter =
+ base::OnceCallback<unsigned int(hb_font_t* font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ unsigned int start_offset,
+ unsigned int* record_count,
+ HarfBuzzRecordType* record_array)>;
+
+template <typename HarfBuzzRecordType, typename RecordType>
+using HarfBuzzMathRecordConverter =
+ base::RepeatingCallback<RecordType(HarfBuzzRecordType)>;
+
+template <typename HarfBuzzRecordType, typename RecordType>
+Vector<RecordType> GetHarfBuzzMathRecord(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ GetHarfBuzzMathRecordGetter<HarfBuzzRecordType> getter,
+ HarfBuzzMathRecordConverter<HarfBuzzRecordType, RecordType> converter,
+ base::Optional<RecordType> prepended_record) {
+ hb_font_t* hb_font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ DCHECK(hb_font);
+
+ hb_direction_t hb_stretch_axis = HarfBuzzDirection(stretch_axis);
+
+ // In practice, math fonts have, for a given base glyph and stretch axis only
+ // provide a few GlyphVariantRecords (size variants of increasing sizes) and
+ // GlyphPartRecords (parts of a glyph assembly) so it is safe to truncate
+ // the result vector to a small size.
+ HarfBuzzRecordType chunk[kMaxHarfBuzzRecords];
+ unsigned int count = kMaxHarfBuzzRecords;
+ std::move(getter).Run(hb_font, base_glyph, hb_stretch_axis,
+ 0 /* start_offset */, &count, chunk);
+
+ // Create the vector to the determined size and initialize it with the results
+ // converted from HarfBuzz's ones, prepending any optional record.
+ Vector<RecordType> result;
+ result.ReserveInitialCapacity(prepended_record ? count + 1 : count);
+ if (prepended_record)
+ result.push_back(*prepended_record);
+ for (unsigned i = 0; i < count; i++) {
+ result.push_back(converter.Run(chunk[i]));
+ }
+ return result;
+}
+
+Vector<OpenTypeMathStretchData::GlyphVariantRecord>
+OpenTypeMathSupport::GetGlyphVariantRecords(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis) {
+ DCHECK(harfbuzz_face);
+ DCHECK(base_glyph);
+
+ auto getter = base::BindOnce(&hb_ot_math_get_glyph_variants);
+ auto converter =
+ base::BindRepeating([](hb_ot_math_glyph_variant_t record)
+ -> OpenTypeMathStretchData::GlyphVariantRecord {
+ return record.glyph;
+ });
+ return GetHarfBuzzMathRecord(
+ harfbuzz_face, base_glyph, stretch_axis, std::move(getter),
+ std::move(converter),
+ base::Optional<OpenTypeMathStretchData::GlyphVariantRecord>(base_glyph));
+}
+
+Vector<OpenTypeMathStretchData::GlyphPartRecord>
+OpenTypeMathSupport::GetGlyphPartRecords(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ float* italic_correction) {
+ DCHECK(harfbuzz_face);
+ DCHECK(base_glyph);
+
+ auto getter = base::BindOnce(
+ [](hb_font_t* font, hb_codepoint_t glyph, hb_direction_t direction,
+ unsigned int start_offset, unsigned int* parts_count,
+ hb_ot_math_glyph_part_t* parts) {
+ hb_position_t italic_correction;
+ return hb_ot_math_get_glyph_assembly(font, glyph, direction,
+ start_offset, parts_count, parts,
+ &italic_correction);
+ });
+ auto converter =
+ base::BindRepeating([](hb_ot_math_glyph_part_t record)
+ -> OpenTypeMathStretchData::GlyphPartRecord {
+ return {record.glyph,
+ HarfBuzzUnitsToFloat(record.start_connector_length),
+ HarfBuzzUnitsToFloat(record.end_connector_length),
+ HarfBuzzUnitsToFloat(record.full_advance),
+ record.flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER};
+ });
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ GetHarfBuzzMathRecord(
+ harfbuzz_face, base_glyph, stretch_axis, std::move(getter),
+ std::move(converter),
+ base::Optional<OpenTypeMathStretchData::GlyphPartRecord>());
+ if (italic_correction && !parts.IsEmpty()) {
+ hb_font_t* hb_font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ // A GlyphAssembly subtable exists for the specified font, glyph and stretch
+ // axis since it has been possible to retrieve the GlyphPartRecords. This
+ // means that the following call is guaranteed to get an italic correction.
+ hb_position_t harfbuzz_italic_correction;
+ hb_ot_math_get_glyph_assembly(hb_font, base_glyph,
+ HarfBuzzDirection(stretch_axis), 0, nullptr,
+ nullptr, &harfbuzz_italic_correction);
+ *italic_correction = HarfBuzzUnitsToFloat(harfbuzz_italic_correction);
+ }
+ return parts;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h
new file mode 100644
index 00000000000..633a4d11f2b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h
@@ -0,0 +1,120 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_SUPPORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_SUPPORT_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class HarfBuzzFace;
+
+class PLATFORM_EXPORT OpenTypeMathSupport {
+ public:
+ static bool HasMathData(const HarfBuzzFace*);
+
+ // These constants are defined in the OpenType MATH table:
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table
+ // Their values match the indices in the MathConstants subtable.
+ enum MathConstants {
+ kScriptPercentScaleDown = 0,
+ kScriptScriptPercentScaleDown = 1,
+ kDelimitedSubFormulaMinHeight = 2,
+ kDisplayOperatorMinHeight = 3,
+ kMathLeading = 4,
+ kAxisHeight = 5,
+ kAccentBaseHeight = 6,
+ kFlattenedAccentBaseHeight = 7,
+ kSubscriptShiftDown = 8,
+ kSubscriptTopMax = 9,
+ kSubscriptBaselineDropMin = 10,
+ kSuperscriptShiftUp = 11,
+ kSuperscriptShiftUpCramped = 12,
+ kSuperscriptBottomMin = 13,
+ kSuperscriptBaselineDropMax = 14,
+ kSubSuperscriptGapMin = 15,
+ kSuperscriptBottomMaxWithSubscript = 16,
+ kSpaceAfterScript = 17,
+ kUpperLimitGapMin = 18,
+ kUpperLimitBaselineRiseMin = 19,
+ kLowerLimitGapMin = 20,
+ kLowerLimitBaselineDropMin = 21,
+ kStackTopShiftUp = 22,
+ kStackTopDisplayStyleShiftUp = 23,
+ kStackBottomShiftDown = 24,
+ kStackBottomDisplayStyleShiftDown = 25,
+ kStackGapMin = 26,
+ kStackDisplayStyleGapMin = 27,
+ kStretchStackTopShiftUp = 28,
+ kStretchStackBottomShiftDown = 29,
+ kStretchStackGapAboveMin = 30,
+ kStretchStackGapBelowMin = 31,
+ kFractionNumeratorShiftUp = 32,
+ kFractionNumeratorDisplayStyleShiftUp = 33,
+ kFractionDenominatorShiftDown = 34,
+ kFractionDenominatorDisplayStyleShiftDown = 35,
+ kFractionNumeratorGapMin = 36,
+ kFractionNumDisplayStyleGapMin = 37,
+ kFractionRuleThickness = 38,
+ kFractionDenominatorGapMin = 39,
+ kFractionDenomDisplayStyleGapMin = 40,
+ kSkewedFractionHorizontalGap = 41,
+ kSkewedFractionVerticalGap = 42,
+ kOverbarVerticalGap = 43,
+ kOverbarRuleThickness = 44,
+ kOverbarExtraAscender = 45,
+ kUnderbarVerticalGap = 46,
+ kUnderbarRuleThickness = 47,
+ kUnderbarExtraDescender = 48,
+ kRadicalVerticalGap = 49,
+ kRadicalDisplayStyleVerticalGap = 50,
+ kRadicalRuleThickness = 51,
+ kRadicalExtraAscender = 52,
+ kRadicalKernBeforeDegree = 53,
+ kRadicalKernAfterDegree = 54,
+ kRadicalDegreeBottomRaisePercent = 55
+ };
+
+ // Returns the value of the requested math constant or null if the font does
+ // not have any OpenType MATH table. All values are 16.16 fixed-point values
+ // converted to float except percentages (kScriptPercentScaleDown,
+ // kScriptScriptPercentScaleDown and kRadicalDegreeBottomRaisePercent) which
+ // are represented by a number between 0 and 1.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table
+ static base::Optional<float> MathConstant(const HarfBuzzFace*, MathConstants);
+
+ // Returns the italic correction corresponding to the specified glyph or null
+ // if the font does not have any OpenType MATH table. This value provides an
+ // estimation of how much the glyph is slanted, which can be used e.g. when
+ // attaching scripts to the glyph.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathitalicscorrectioninfo-table
+ static base::Optional<float> MathItalicCorrection(const HarfBuzzFace*, Glyph);
+
+ // Returns a vector of GlyphVariantRecords corresponding to the specified
+ // glyph and stretch axis. The base glyph is always added as the first item.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table
+ static Vector<OpenTypeMathStretchData::GlyphVariantRecord>
+ GetGlyphVariantRecords(const HarfBuzzFace*,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis);
+
+ // Returns a vector of GlyphPartRecords corresponding to the specified
+ // glyph and stretch axis or an empty vector if there is no such construction.
+ // If the italic_correction parameter is specified and a construction is
+ // available, then it is set to the italic correction of the glyph assembly.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table
+ static Vector<OpenTypeMathStretchData::GlyphPartRecord> GetGlyphPartRecords(
+ const HarfBuzzFace*,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis,
+ float* italic_correction = nullptr);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_SUPPORT_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
new file mode 100644
index 00000000000..c6493f48399
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
@@ -0,0 +1,466 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+#include "base/memory/scoped_refptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/fonts/font.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_types.h"
+#include "third_party/blink/renderer/platform/testing/font_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace {
+const UChar32 kLeftBraceCodePoint = '{';
+const UChar32 kOverBraceCodePoint = 0x23DE;
+const UChar32 kArabicMathOperatorHahWithDalCodePoint = 0x1EEF1;
+const UChar32 kNAryWhiteVerticalBarCodePoint = 0x2AFF;
+} // namespace
+
+namespace blink {
+
+class OpenTypeMathSupportTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ font_description.SetComputedSize(10.0);
+ font = Font(font_description);
+ }
+
+ void TearDown() override {}
+
+ Font CreateMathFont(const String& name, float size = 1000) {
+ FontDescription::VariantLigatures ligatures;
+ return blink::test::CreateTestFont(
+ "MathTestFont",
+ blink::test::BlinkWebTestsFontsTestDataPath(String("math/") + name),
+ size, &ligatures);
+ }
+
+ bool HasMathData(const String& name) {
+ return OpenTypeMathSupport::HasMathData(
+ CreateMathFont(name).PrimaryFont()->PlatformData().GetHarfBuzzFace());
+ }
+
+ base::Optional<float> MathConstant(
+ const String& name,
+ OpenTypeMathSupport::MathConstants constant) {
+ Font math = CreateMathFont(name);
+ return OpenTypeMathSupport::MathConstant(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), constant);
+ }
+
+ FontDescription font_description;
+ Font font;
+};
+
+TEST_F(OpenTypeMathSupportTest, HasMathData) {
+ // Null parameter.
+ EXPECT_FALSE(OpenTypeMathSupport::HasMathData(nullptr));
+
+ // Font without a MATH table.
+ EXPECT_FALSE(HasMathData("math-text.woff"));
+
+ // Font with a MATH table.
+ EXPECT_TRUE(HasMathData("axisheight5000-verticalarrow14000.woff"));
+}
+
+TEST_F(OpenTypeMathSupportTest, MathConstantNullOpt) {
+ Font math_text = CreateMathFont("math-text.woff");
+
+ for (int i = OpenTypeMathSupport::MathConstants::kScriptPercentScaleDown;
+ i <=
+ OpenTypeMathSupport::MathConstants::kRadicalDegreeBottomRaisePercent;
+ i++) {
+ auto math_constant = static_cast<OpenTypeMathSupport::MathConstants>(i);
+
+ // Null parameter.
+ EXPECT_FALSE(OpenTypeMathSupport::MathConstant(nullptr, math_constant));
+
+ // Font without a MATH table.
+ EXPECT_FALSE(OpenTypeMathSupport::MathConstant(
+ math_text.PrimaryFont()->PlatformData().GetHarfBuzzFace(),
+ math_constant));
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/percentscaledown.py
+TEST_F(OpenTypeMathSupportTest, MathConstantPercentScaleDown) {
+ {
+ auto result = MathConstant(
+ "scriptpercentscaledown80-scriptscriptpercentscaledown0.woff",
+ OpenTypeMathSupport::MathConstants::kScriptPercentScaleDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, .8);
+ }
+
+ {
+ auto result = MathConstant(
+ "scriptpercentscaledown0-scriptscriptpercentscaledown40.woff",
+ OpenTypeMathSupport::MathConstants::kScriptScriptPercentScaleDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, .4);
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/fractions.py
+TEST_F(OpenTypeMathSupportTest, MathConstantFractions) {
+ {
+ auto result = MathConstant(
+ "fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionNumeratorShiftUp);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 11000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-numeratordisplaystyleshiftup2000-axisheight1000-"
+ "rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::
+ kFractionNumeratorDisplayStyleShiftUp);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 2000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000."
+ "woff",
+ OpenTypeMathSupport::MathConstants::kFractionDenominatorShiftDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 3000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatordisplaystyleshiftdown6000-axisheight1000-"
+ "rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::
+ kFractionDenominatorDisplayStyleShiftDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 6000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-numeratorgapmin9000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionNumeratorGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 9000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionNumDisplayStyleGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 8000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-rulethickness10000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionRuleThickness);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 10000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatorgapmin4000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionDenominatorGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 4000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatordisplaystylegapmin5000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionDenomDisplayStyleGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 5000);
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/radicals.py
+TEST_F(OpenTypeMathSupportTest, MathConstantRadicals) {
+ {
+ auto result = MathConstant(
+ "radical-degreebottomraisepercent25-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalDegreeBottomRaisePercent);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, .25);
+ }
+
+ {
+ auto result =
+ MathConstant("radical-verticalgap6000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalVerticalGap);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 6000);
+ }
+
+ {
+ auto result = MathConstant(
+ "radical-displaystyleverticalgap7000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalDisplayStyleVerticalGap);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 7000);
+ }
+
+ {
+ auto result =
+ MathConstant("radical-rulethickness8000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalRuleThickness);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 8000);
+ }
+
+ {
+ auto result =
+ MathConstant("radical-extraascender3000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalExtraAscender);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 3000);
+ }
+
+ {
+ auto result = MathConstant(
+ "radical-kernbeforedegree4000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalKernBeforeDegree);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 4000);
+ }
+
+ {
+ auto result = MathConstant(
+ "radical-kernafterdegreeminus5000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalKernAfterDegree);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, -5000);
+ }
+}
+
+TEST_F(OpenTypeMathSupportTest, MathVariantsWithoutTable) {
+ Font math = CreateMathFont("math-text.woff");
+ auto glyph = math.PrimaryFont()->GlyphForCharacter('A');
+
+ // Horizontal variants.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], glyph);
+ }
+
+ // Vertical variants.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], glyph);
+ }
+
+ // Horizontal parts.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+
+ // // Vertical parts.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+}
+
+TEST_F(OpenTypeMathSupportTest, MathVariantsWithTable) {
+ // operators.woff contains stretchy operators from the MathML operator
+ // dictionary (including left and over braces) represented by squares.
+ // It also contains glyphs h0, h1, h2, h3 and v0, v1, v2, v3 that are
+ // respectively horizontal and vertical rectangles of increasing size.
+ // The MathVariants table contains the following data for horizontal
+ // (respectively vertical) operators:
+ // - Glyph variants: h0, h1, h2, h3 (respectively v0, v1, v2, v3).
+ // - Glyph parts: non-extender h2 and extender h1 (respectively v2 and v1).
+ // For details, see createSizeVariants() and createStretchy() from
+ // third_party/blink/web_tests/external/wpt/mathml/tools/operator-dictionary.py
+
+ Font math = CreateMathFont("operators.woff");
+ auto left_brace = math.PrimaryFont()->GlyphForCharacter(kLeftBraceCodePoint);
+ auto over_brace = math.PrimaryFont()->GlyphForCharacter(kOverBraceCodePoint);
+
+ // Calculate glyph indices from the last unicode character in the font.
+ // TODO(https://crbug.com/1057596): Find a better way to access these glyph
+ // indices.
+ auto v0 = math.PrimaryFont()->GlyphForCharacter(
+ kArabicMathOperatorHahWithDalCodePoint) +
+ 1;
+ auto h0 = v0 + 1;
+ auto v1 = h0 + 1;
+ auto h1 = v1 + 1;
+ auto v2 = h1 + 1;
+ auto h2 = v2 + 1;
+ auto v3 = h2 + 1;
+ auto h3 = v3 + 1;
+
+ // Vertical variants for vertical operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 5u);
+ EXPECT_EQ(variants[0], left_brace);
+ EXPECT_EQ(variants[1], v0);
+ EXPECT_EQ(variants[2], v1);
+ EXPECT_EQ(variants[3], v2);
+ EXPECT_EQ(variants[4], v3);
+ }
+
+ // Horizontal variants for vertical operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], left_brace);
+ }
+
+ // Horizontal variants for horizontal operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_EQ(variants.size(), 5u);
+ EXPECT_EQ(variants[0], over_brace);
+ EXPECT_EQ(variants[1], h0);
+ EXPECT_EQ(variants[2], h1);
+ EXPECT_EQ(variants[3], h2);
+ EXPECT_EQ(variants[4], h3);
+ }
+
+ // Vertical variants for horizontal operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], over_brace);
+ }
+
+ // Vertical parts for vertical operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(parts.size(), 2u);
+ EXPECT_EQ(parts[0].glyph, v2);
+ EXPECT_FLOAT_EQ(parts[0].start_connector_length, 0);
+ EXPECT_FLOAT_EQ(parts[0].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[0].full_advance, 3000);
+ EXPECT_EQ(parts[0].is_extender, false);
+ EXPECT_EQ(parts[1].glyph, v1);
+ EXPECT_FLOAT_EQ(parts[1].start_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].full_advance, 2000);
+ EXPECT_EQ(parts[1].is_extender, true);
+ }
+
+ // Horizontal parts for vertical operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+
+ // Horizontal parts for horizontal operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+
+ EXPECT_EQ(parts.size(), 2u);
+ EXPECT_EQ(parts[0].glyph, h2);
+ EXPECT_FLOAT_EQ(parts[0].start_connector_length, 0);
+ EXPECT_FLOAT_EQ(parts[0].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[0].full_advance, 3000);
+ EXPECT_EQ(parts[0].is_extender, false);
+
+ EXPECT_EQ(parts[1].glyph, h1);
+ EXPECT_FLOAT_EQ(parts[1].start_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].full_advance, 2000);
+ EXPECT_EQ(parts[1].is_extender, true);
+ }
+
+ // Vertical parts for horizontal operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/largeop.py
+TEST_F(OpenTypeMathSupportTest, MathItalicCorrection) {
+ {
+ Font math = CreateMathFont(
+ "largeop-displayoperatorminheight2000-2AFF-italiccorrection3000.woff");
+ Glyph base_glyph =
+ math.PrimaryFont()->GlyphForCharacter(kNAryWhiteVerticalBarCodePoint);
+
+ // Retrieve the glyph with italic correction.
+ Vector<OpenTypeMathStretchData::GlyphVariantRecord> variants =
+ OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), base_glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 3u);
+ EXPECT_EQ(variants[0], base_glyph);
+ EXPECT_EQ(variants[1], base_glyph);
+ Glyph glyph_with_italic_correction = variants[2];
+
+ // MathItalicCorrection with a value.
+ base::Optional<float> glyph_with_italic_correction_value =
+ OpenTypeMathSupport::MathItalicCorrection(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(),
+ glyph_with_italic_correction);
+ EXPECT_TRUE(glyph_with_italic_correction_value);
+ EXPECT_FLOAT_EQ(*glyph_with_italic_correction_value, 3000);
+
+ // GetGlyphPartRecords does not set italic correction when there is no
+ // construction available.
+ float italic_correction = -1000;
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), base_glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical, &italic_correction);
+ EXPECT_TRUE(parts.IsEmpty());
+ EXPECT_FLOAT_EQ(italic_correction, -1000);
+ }
+
+ {
+ Font math = CreateMathFont(
+ "largeop-displayoperatorminheight7000-2AFF-italiccorrection5000.woff");
+ Glyph base_glyph =
+ math.PrimaryFont()->GlyphForCharacter(kNAryWhiteVerticalBarCodePoint);
+
+ // OpenTypeMathSupport::GetGlyphPartRecords sets italic correction.
+ float italic_correction = -1000;
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), base_glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical, &italic_correction);
+ EXPECT_EQ(parts.size(), 3u);
+ EXPECT_FLOAT_EQ(italic_correction, 5000);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h b/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h
index 61b2872c97b..17cc3ed89ec 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/platform/fonts/font_data.h"
#include "third_party/blink/renderer/platform/fonts/font_data_for_range_set.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
class SimpleFontData;
@@ -61,7 +62,12 @@ class PLATFORM_EXPORT SegmentedFontData : public FontData {
Vector<scoped_refptr<FontDataForRangeSet>, 1> faces_;
};
-DEFINE_FONT_DATA_TYPE_CASTS(SegmentedFontData, true);
+template <>
+struct DowncastTraits<SegmentedFontData> {
+ static bool AllowFrom(const FontData& fontData) {
+ return fontData.IsSegmented();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc
index 5b020364b1a..a9886bcd928 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc
@@ -13,8 +13,8 @@ scoped_refptr<const ShapeResult>
CachingWordShapeIterator::ShapeWordWithoutSpacing(const TextRun& word_run,
const Font* font) {
ShapeCacheEntry* cache_entry = shape_cache_->Add(word_run, ShapeCacheEntry());
- if (cache_entry && cache_entry->shape_result_)
- return cache_entry->shape_result_;
+ if (cache_entry && *cache_entry)
+ return *cache_entry;
const String word_text = word_run.NormalizedUTF16();
HarfBuzzShaper shaper(word_text);
@@ -25,7 +25,7 @@ CachingWordShapeIterator::ShapeWordWithoutSpacing(const TextRun& word_run,
shape_result->SetDeprecatedInkBounds(shape_result->ComputeInkBounds());
if (cache_entry)
- cache_entry->shape_result_ = shape_result;
+ *cache_entry = shape_result;
return shape_result;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
index 7e4e2bc6398..68972169da9 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
@@ -37,7 +37,7 @@
namespace blink {
ShapeCache* CachingWordShaper::GetShapeCache() const {
- return font_.font_fallback_list_->GetShapeCache(font_.font_description_);
+ return font_.GetShapeCache();
}
// Returns the total advance width of the TextRun run. If glyph_bounds
@@ -157,7 +157,7 @@ GlyphData CachingWordShaper::EmphasisMarkGlyphData(
ShapeResultBuffer buffer;
ShapeResultsForRun(GetShapeCache(), &font_, emphasis_mark_run, &buffer);
- return buffer.EmphasisMarkGlyphData(font_.font_description_);
+ return buffer.EmphasisMarkGlyphData(font_.GetFontDescription());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc
index 89fea7e10c3..46137b2efdd 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc
@@ -24,7 +24,6 @@ class CachingWordShaperTest : public testing::Test {
font_description.SetGenericFamily(FontDescription::kStandardFamily);
font = Font(font_description);
- font.Update(nullptr);
ASSERT_TRUE(font.CanShapeWordByWord());
fallback_fonts = nullptr;
cache = std::make_unique<ShapeCache>();
@@ -390,7 +389,6 @@ TEST_F(CachingWordShaperTest, TextOrientationFallbackShouldNotInFallbackList) {
font_description.SetOrientation(FontOrientation::kVerticalMixed);
Font vertical_mixed_font = Font(font_description);
- vertical_mixed_font.Update(nullptr);
ASSERT_TRUE(vertical_mixed_font.CanShapeWordByWord());
CachingWordShaper shaper(vertical_mixed_font);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
index 4d4a8227312..97fa173bb8b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
@@ -30,8 +30,10 @@
#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
-#include <hb-ot.h>
+// clang-format off
#include <hb.h>
+#include <hb-ot.h>
+// clang-format on
#include <memory>
@@ -50,6 +52,7 @@
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPoint.h"
@@ -59,34 +62,40 @@
namespace blink {
-void HbFontDeleter::operator()(hb_font_t* font) {
- if (font)
- hb_font_destroy(font);
-}
+namespace {
-void HbFaceDeleter::operator()(hb_face_t* face) {
- if (face)
- hb_face_destroy(face);
-}
+#if defined(OS_MACOSX)
+void DetermineTrakSbix(SkTypeface* typeface, bool* has_trak, bool* has_sbix) {
+ int num_tags = typeface->countTables();
+
+ SkFontTableTag tags[num_tags];
+
+ int returned_tags = typeface->getTableTags(tags);
+ DCHECK_EQ(num_tags, returned_tags);
-struct HbSetDeleter {
- void operator()(hb_set_t* set) {
- if (set)
- hb_set_destroy(set);
+ for (auto& tag : tags) {
+ if (tag == SkSetFourByteTag('t', 'r', 'a', 'k'))
+ *has_trak = true;
+ if (tag == SkSetFourByteTag('s', 'b', 'i', 'x'))
+ *has_sbix = true;
}
-};
+}
+#endif
-using HbSetUniquePtr = std::unique_ptr<hb_set_t, HbSetDeleter>;
+} // namespace
-static scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t*);
+static scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(
+ hb_face_t*,
+ SkTypeface* typefaces);
HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
: platform_data_(platform_data), unique_id_(unique_id) {
HarfBuzzFontCache::AddResult result =
- FontGlobalContext::GetHarfBuzzFontCache().insert(unique_id_, nullptr);
+ FontGlobalContext::GetHarfBuzzFontCache()->insert(unique_id_, nullptr);
if (result.is_new_entry) {
- HbFaceUniquePtr face(CreateFace());
- result.stored_value->value = CreateHbFontCacheEntry(face.get());
+ HbScoped<hb_face_t> face(CreateFace());
+ result.stored_value->value =
+ CreateHbFontCacheEntry(face.get(), platform_data->Typeface());
}
result.stored_value->value->AddRef();
unscaled_font_ = result.stored_value->value->HbFont();
@@ -94,13 +103,14 @@ HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
}
HarfBuzzFace::~HarfBuzzFace() {
- HarfBuzzFontCache::iterator result =
- FontGlobalContext::GetHarfBuzzFontCache().find(unique_id_);
- SECURITY_DCHECK(result != FontGlobalContext::GetHarfBuzzFontCache().end());
+ HarfBuzzFontCache* harfbuzz_font_cache =
+ FontGlobalContext::GetHarfBuzzFontCache();
+ HarfBuzzFontCache::iterator result = harfbuzz_font_cache->find(unique_id_);
+ SECURITY_DCHECK(result != harfbuzz_font_cache->end());
DCHECK(!result.Get()->value->HasOneRef());
result.Get()->value->Release();
if (result.Get()->value->HasOneRef())
- FontGlobalContext::GetHarfBuzzFontCache().erase(unique_id_);
+ harfbuzz_font_cache->erase(unique_id_);
}
static hb_bool_t HarfBuzzGetGlyph(hb_font_t* hb_font,
@@ -228,7 +238,7 @@ bool HarfBuzzFace::HasSpaceInLigaturesOrKerning(TypesettingFeatures features) {
const hb_codepoint_t kInvalidCodepoint = static_cast<hb_codepoint_t>(-1);
hb_codepoint_t space = kInvalidCodepoint;
- HbSetUniquePtr glyphs(hb_set_create());
+ HbScoped<hb_set_t> glyphs(hb_set_create());
// Check whether computing is needed and compute for gpos/gsub.
if (features & kKerning &&
@@ -280,31 +290,43 @@ bool HarfBuzzFace::ShouldSubpixelPosition() {
return harfbuzz_font_data_->font_.isSubpixel();
}
-static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs() {
- hb_font_funcs_t* funcs = FontGlobalContext::GetHarfBuzzFontFuncs();
+static hb_font_funcs_t* create_populated_hb_font_funcs(
+ FontGlobalContext::HorizontalAdvanceSource horizontal_advance_source) {
+ hb_font_funcs_t* funcs = hb_font_funcs_create();
- // We don't set callback functions which we can't support.
- // HarfBuzz will use the fallback implementation if they aren't set.
- if (!funcs) {
- funcs = hb_font_funcs_create();
- hb_font_funcs_set_variation_glyph_func(funcs, HarfBuzzGetGlyph, nullptr,
- nullptr);
- hb_font_funcs_set_nominal_glyph_func(funcs, HarfBuzzGetNominalGlyph,
- nullptr, nullptr);
+ if (horizontal_advance_source == FontGlobalContext::kSkiaHorizontalAdvances) {
hb_font_funcs_set_glyph_h_advance_func(
funcs, HarfBuzzGetGlyphHorizontalAdvance, nullptr, nullptr);
hb_font_funcs_set_glyph_h_advances_func(
funcs, HarfBuzzGetGlyphHorizontalAdvances, nullptr, nullptr);
- // TODO(https://crbug.com/899718): Replace vertical metrics callbacks with
- // HarfBuzz VORG/VMTX internal implementation by deregistering those.
- hb_font_funcs_set_glyph_v_advance_func(
- funcs, HarfBuzzGetGlyphVerticalAdvance, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_origin_func(funcs, HarfBuzzGetGlyphVerticalOrigin,
- nullptr, nullptr);
- hb_font_funcs_set_glyph_extents_func(funcs, HarfBuzzGetGlyphExtents,
+ }
+ hb_font_funcs_set_variation_glyph_func(funcs, HarfBuzzGetGlyph, nullptr,
+ nullptr);
+ hb_font_funcs_set_nominal_glyph_func(funcs, HarfBuzzGetNominalGlyph, nullptr,
+ nullptr);
+ // TODO(https://crbug.com/899718): Replace vertical metrics callbacks with
+ // HarfBuzz VORG/VMTX internal implementation by deregistering those.
+ hb_font_funcs_set_glyph_v_advance_func(funcs, HarfBuzzGetGlyphVerticalAdvance,
nullptr, nullptr);
- hb_font_funcs_make_immutable(funcs);
- FontGlobalContext::SetHarfBuzzFontFuncs(funcs);
+ hb_font_funcs_set_glyph_v_origin_func(funcs, HarfBuzzGetGlyphVerticalOrigin,
+ nullptr, nullptr);
+ hb_font_funcs_set_glyph_extents_func(funcs, HarfBuzzGetGlyphExtents, nullptr,
+ nullptr);
+
+ hb_font_funcs_make_immutable(funcs);
+ return funcs;
+}
+
+static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs(
+ FontGlobalContext::HorizontalAdvanceSource advance_source) {
+ hb_font_funcs_t* funcs =
+ FontGlobalContext::GetHarfBuzzFontFuncs(advance_source);
+
+ // We don't set callback functions which we can't support.
+ // HarfBuzz will use the fallback implementation if they aren't set.
+ if (!funcs) {
+ funcs = create_populated_hb_font_funcs(advance_source);
+ FontGlobalContext::SetHarfBuzzFontFuncs(advance_source, funcs);
}
DCHECK(funcs);
return funcs;
@@ -360,11 +382,10 @@ hb_face_t* HarfBuzzFace::CreateFace() {
if (tf_stream && tf_stream->getMemoryBase()) {
const void* tf_memory = tf_stream->getMemoryBase();
size_t tf_size = tf_stream->getLength();
- std::unique_ptr<hb_blob_t, void (*)(hb_blob_t*)> face_blob(
+ HbScoped<hb_blob_t> face_blob(
hb_blob_create(reinterpret_cast<const char*>(tf_memory),
SafeCast<unsigned int>(tf_size), HB_MEMORY_MODE_READONLY,
- tf_stream.release(), DeleteTypefaceStream),
- hb_blob_destroy);
+ tf_stream.release(), DeleteTypefaceStream));
face = hb_face_create(face_blob.get(), ttc_index);
}
#endif
@@ -382,15 +403,39 @@ hb_face_t* HarfBuzzFace::CreateFace() {
return face;
}
-scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t* face) {
- HbFontUniquePtr ot_font(hb_font_create(face));
+scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t* face,
+ SkTypeface* typeface) {
+ HbScoped<hb_font_t> ot_font(hb_font_create(face));
hb_ot_font_set_funcs(ot_font.get());
+
+ int axis_count = typeface->getVariationDesignPosition(nullptr, 0);
+ if (axis_count > 0) {
+ Vector<SkFontArguments::VariationPosition::Coordinate> axis_values;
+ axis_values.resize(axis_count);
+ if (typeface->getVariationDesignPosition(axis_values.data(),
+ axis_values.size()) > 0) {
+ hb_font_set_variations(
+ ot_font.get(), reinterpret_cast<hb_variation_t*>(axis_values.data()),
+ axis_values.size());
+ }
+ }
+
// Creating a sub font means that non-available functions
// are found from the parent.
hb_font_t* unscaled_font = hb_font_create_sub_font(ot_font.get());
scoped_refptr<HbFontCacheEntry> cache_entry =
HbFontCacheEntry::Create(unscaled_font);
- hb_font_set_funcs(unscaled_font, HarfBuzzSkiaGetFontFuncs(),
+
+ FontGlobalContext::HorizontalAdvanceSource advance_source =
+ FontGlobalContext::kSkiaHorizontalAdvances;
+#if defined(OS_MACOSX)
+ bool has_trak = false;
+ bool has_sbix = false;
+ DetermineTrakSbix(typeface, &has_trak, &has_sbix);
+ if (has_trak && !has_sbix)
+ advance_source = FontGlobalContext::kHarfBuzzHorizontalAdvances;
+#endif
+ hb_font_set_funcs(unscaled_font, HarfBuzzSkiaGetFontFuncs(advance_source),
cache_entry->HbFontData(), nullptr);
return cache_entry;
}
@@ -423,19 +468,6 @@ hb_font_t* HarfBuzzFace::GetScaledFont(
// equivalent of CSS pixels here.
hb_font_set_ptem(unscaled_font_, platform_data_->size());
- SkTypeface* typeface = harfbuzz_font_data_->font_.getTypeface();
- int axis_count = typeface->getVariationDesignPosition(nullptr, 0);
- if (axis_count > 0) {
- Vector<SkFontArguments::VariationPosition::Coordinate> axis_values;
- axis_values.resize(axis_count);
- if (typeface->getVariationDesignPosition(axis_values.data(),
- axis_values.size()) > 0) {
- hb_font_set_variations(
- unscaled_font_, reinterpret_cast<hb_variation_t*>(axis_values.data()),
- axis_values.size());
- }
- }
-
return unscaled_font_;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc
index 02690dd9854..40ad779aaed 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc
@@ -8,7 +8,7 @@
namespace blink {
HbFontCacheEntry::HbFontCacheEntry(hb_font_t* font)
- : hb_font_(HbFontUniquePtr(font)),
+ : hb_font_(HbScoped<hb_font_t>(font)),
hb_font_data_(std::make_unique<HarfBuzzFontData>()) {}
HbFontCacheEntry::~HbFontCacheEntry() = default;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
index 5826f0a6bba..d8526a9352a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
@@ -5,30 +5,18 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_HARFBUZZ_FONT_CACHE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_HARFBUZZ_FONT_CACHE_H_
+#include <hb.h>
+
#include <memory>
#include "third_party/blink/renderer/platform/fonts/font_metrics.h"
#include "third_party/blink/renderer/platform/fonts/unicode_range_set.h"
-
-struct hb_font_t;
-struct hb_face_t;
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
namespace blink {
struct HarfBuzzFontData;
-struct HbFontDeleter {
- void operator()(hb_font_t* font);
-};
-
-using HbFontUniquePtr = std::unique_ptr<hb_font_t, HbFontDeleter>;
-
-struct HbFaceDeleter {
- void operator()(hb_face_t* face);
-};
-
-using HbFaceUniquePtr = std::unique_ptr<hb_face_t, HbFaceDeleter>;
-
// Though we have FontCache class, which provides the cache mechanism for
// WebKit's font objects, we also need additional caching layer for HarfBuzz to
// reduce the number of hb_font_t objects created. Without it, we would create
@@ -50,15 +38,17 @@ class HbFontCacheEntry : public RefCounted<HbFontCacheEntry> {
private:
explicit HbFontCacheEntry(hb_font_t* font);
- HbFontUniquePtr hb_font_;
+ HbScoped<hb_font_t> hb_font_;
std::unique_ptr<HarfBuzzFontData> hb_font_data_;
};
-typedef HashMap<uint64_t,
- scoped_refptr<HbFontCacheEntry>,
- WTF::IntHash<uint64_t>,
- WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>
- HarfBuzzFontCache;
+// Declare as derived class in order to be able to forward-declare it as class
+// in FontGlobalContext.
+class HarfBuzzFontCache
+ : public HashMap<uint64_t,
+ scoped_refptr<HbFontCacheEntry>,
+ WTF::IntHash<uint64_t>,
+ WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> {};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc
index 186cb357c9c..b63c48d9513 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc
@@ -36,9 +36,8 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Font font(font_description);
// Set font size to something other than the default 0 size in
// FontDescription, 16 matches the default text size in HTML.
+ // We don't use a FontSelector here. Only look for system fonts for now.
font_description.SetComputedSize(16.0f);
- // Only look for system fonts for now.
- font.Update(nullptr);
HarfBuzzShaper shaper(String(converted_input_buffer, converted_length));
scoped_refptr<ShapeResult> result = shaper.Shape(&font, TextDirection::kLtr);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
index 9cca0e58d2b..6c03756d4c4 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
@@ -83,7 +83,6 @@ class HarfBuzzShaperTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
}
void TearDown() override {}
@@ -101,7 +100,6 @@ class HarfBuzzShaperTest : public testing::Test {
font_description.SetFamily(devanagari_family);
font = Font(font_description);
- font.Update(nullptr);
}
Font CreateAhem(float size) {
@@ -472,7 +470,6 @@ TEST_F(HarfBuzzShaperTest, ShapeTabulationCharacters) {
TEST_F(HarfBuzzShaperTest, ShapeVerticalUpright) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
// This string should create 2 runs, ideographic and Latin, both in upright.
String string(u"\u65E5\u65E5\u65E5lllll");
@@ -496,7 +493,6 @@ TEST_F(HarfBuzzShaperTest, ShapeVerticalUpright) {
TEST_F(HarfBuzzShaperTest, ShapeVerticalUprightIdeograph) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
// This string should create one ideograph run.
String string(u"\u65E5\u65E6\u65E0\u65D3\u65D0");
@@ -527,7 +523,6 @@ TEST_F(HarfBuzzShaperTest, RangeShapeSmallCaps) {
font_description.SetVariantCaps(FontDescription::kSmallCaps);
font_description.SetComputedSize(12.0);
Font font(font_description);
- font.Update(nullptr);
// Shaping index 2 to 3 means that case splitting for small caps splits before
// character index 2 since the initial 'a' needs to be uppercased, but the
@@ -563,7 +558,6 @@ TEST_F(HarfBuzzShaperTest, RangeShapeSmallCaps) {
TEST_F(HarfBuzzShaperTest, ShapeVerticalMixed) {
font_description.SetOrientation(FontOrientation::kVerticalMixed);
font = Font(font_description);
- font.Update(nullptr);
// This string should create 2 runs, ideographic in upright and Latin in
// rotated horizontal.
@@ -1634,10 +1628,7 @@ static bool KerningIsHappening(const FontDescription& font_description,
kern.SetKerning(FontDescription::kAutoKerning);
Font font_no_kern(no_kern);
- font_no_kern.Update(nullptr);
-
Font font_kern(kern);
- font_kern.Update(nullptr);
HarfBuzzShaper shaper(str);
@@ -1749,7 +1740,6 @@ TEST_F(HarfBuzzShaperTest, ShapeVerticalWithoutSubpixelPositionIsRounded) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
String string(u"\u65E5\u65E5\u65E5");
TextDirection direction = TextDirection::kLtr;
@@ -1769,7 +1759,6 @@ TEST_F(HarfBuzzShaperTest, ShapeVerticalWithSubpixelPositionIsRounded) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
String string(u"\u65E5\u65E5\u65E5");
TextDirection direction = TextDirection::kLtr;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
index b6a3ff992b0..9dfd507dd0b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
@@ -39,11 +39,7 @@
namespace blink {
-struct ShapeCacheEntry {
- DISALLOW_NEW();
- ShapeCacheEntry() { shape_result_ = nullptr; }
- scoped_refptr<const ShapeResult> shape_result_;
-};
+using ShapeCacheEntry = scoped_refptr<const ShapeResult>;
class ShapeCache {
USING_FAST_MALLOC(ShapeCache);
@@ -118,7 +114,7 @@ class ShapeCache {
if (run.length() > SmallStringKey::Capacity())
return nullptr;
- return AddSlowCase(run, entry);
+ return AddSlowCase(run, std::move(entry));
}
void ClearIfVersionChanged(unsigned version) {
@@ -140,10 +136,10 @@ class ShapeCache {
size_t ByteSize() const {
size_t self_byte_size = 0;
for (auto cache_entry : single_char_map_) {
- self_byte_size += cache_entry.value.shape_result_->ByteSize();
+ self_byte_size += cache_entry.value->ByteSize();
}
for (auto cache_entry : short_string_map_) {
- self_byte_size += cache_entry.value.shape_result_->ByteSize();
+ self_byte_size += cache_entry.value->ByteSize();
}
return self_byte_size;
}
@@ -160,7 +156,8 @@ class ShapeCache {
// as such use bit 31 (zero-based) to indicate direction.
if (run.Direction() == TextDirection::kRtl)
key |= (1u << 31);
- SingleCharMap::AddResult add_result = single_char_map_.insert(key, entry);
+ SingleCharMap::AddResult add_result =
+ single_char_map_.insert(key, std::move(entry));
is_new_entry = add_result.is_new_entry;
value = &add_result.stored_value->value;
} else {
@@ -170,9 +167,8 @@ class ShapeCache {
} else {
small_string_key = SmallStringKey(run.Span16(), run.Direction());
}
-
SmallStringMap::AddResult add_result =
- short_string_map_.insert(small_string_key, entry);
+ short_string_map_.insert(small_string_key, std::move(entry));
is_new_entry = add_result.is_new_entry;
value = &add_result.stored_value->value;
}
@@ -202,6 +198,7 @@ class ShapeCache {
struct SmallStringKeyHashTraits : WTF::SimpleClassHashTraits<SmallStringKey> {
STATIC_ONLY(SmallStringKeyHashTraits);
static const bool kHasIsEmptyValueFunction = true;
+ static const bool kEmptyValueIsZero = false;
static bool IsEmptyValue(const SmallStringKey& key) {
return key.IsHashTableEmptyValue();
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
index 3a73c9a9d8e..81864362264 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -565,7 +565,7 @@ unsigned ShapeResult::OffsetToFit(float x, TextDirection line_direction) const {
if (IsLtr(line_direction))
return result.left_character_index;
- if (x == result.origin_x && IsRtl(Direction()))
+ if (x == result.origin_x)
return result.left_character_index;
return result.right_character_index;
}
@@ -1450,6 +1450,96 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForSpaces(const Font* font,
return result;
}
+scoped_refptr<ShapeResult> ShapeResult::CreateForStretchyMathOperator(
+ const Font* font,
+ TextDirection direction,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ Glyph glyph_variant,
+ float stretch_size) {
+ bool is_horizontal_assembly =
+ stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal;
+ unsigned start_index = 0;
+ unsigned num_characters = 1;
+ scoped_refptr<ShapeResult> result =
+ ShapeResult::Create(font, start_index, num_characters, direction);
+
+ hb_direction_t hb_direction =
+ is_horizontal_assembly ? HB_DIRECTION_LTR : HB_DIRECTION_TTB;
+ unsigned glyph_index = 0;
+ scoped_refptr<ShapeResult::RunInfo> run = RunInfo::Create(
+ font->PrimaryFont(), hb_direction, CanvasRotationInVertical::kRegular,
+ HB_SCRIPT_COMMON, start_index, 1 /* num_glyph */, num_characters);
+ run->glyph_data_[glyph_index] = {glyph_variant, 0 /* character index */,
+ true /* IsSafeToBreakBefore */,
+ stretch_size};
+ run->width_ = std::max(0.0f, stretch_size);
+
+ result->width_ = run->width_;
+ result->num_glyphs_ = run->NumGlyphs();
+ result->runs_.push_back(std::move(run));
+
+ return result;
+}
+
+scoped_refptr<ShapeResult> ShapeResult::CreateForStretchyMathOperator(
+ const Font* font,
+ TextDirection direction,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ const OpenTypeMathStretchData::AssemblyParameters& assembly_parameters) {
+ DCHECK(!assembly_parameters.parts.IsEmpty());
+ DCHECK_LE(assembly_parameters.glyph_count, HarfBuzzRunGlyphData::kMaxGlyphs);
+
+ bool is_horizontal_assembly =
+ stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal;
+ unsigned start_index = 0;
+ unsigned num_characters = 1;
+ scoped_refptr<ShapeResult> result =
+ ShapeResult::Create(font, start_index, num_characters, direction);
+
+ hb_direction_t hb_direction =
+ is_horizontal_assembly ? HB_DIRECTION_LTR : HB_DIRECTION_TTB;
+ scoped_refptr<ShapeResult::RunInfo> run = RunInfo::Create(
+ font->PrimaryFont(), hb_direction, CanvasRotationInVertical::kRegular,
+ HB_SCRIPT_COMMON, start_index, assembly_parameters.glyph_count,
+ num_characters);
+
+ float overlap = assembly_parameters.connector_overlap;
+ unsigned part_index = 0;
+ for (const auto& part : assembly_parameters.parts) {
+ unsigned repetition_count =
+ part.is_extender ? assembly_parameters.repetition_count : 1;
+ if (!repetition_count)
+ continue;
+ DCHECK(part_index < assembly_parameters.glyph_count);
+ for (unsigned repetition_index = 0; repetition_index < repetition_count;
+ repetition_index++) {
+ unsigned glyph_index =
+ is_horizontal_assembly
+ ? part_index
+ : assembly_parameters.glyph_count - 1 - part_index;
+ float full_advance = glyph_index == assembly_parameters.glyph_count - 1
+ ? part.full_advance
+ : part.full_advance - overlap;
+ run->glyph_data_[glyph_index] = {part.glyph, 0 /* character index */,
+ !glyph_index /* IsSafeToBreakBefore */,
+ full_advance};
+ if (!is_horizontal_assembly) {
+ GlyphOffset glyph_offset(
+ 0, -assembly_parameters.stretch_size + part.full_advance);
+ run->glyph_data_.SetOffsetAt(glyph_index, glyph_offset);
+ result->has_vertical_offsets_ |= (glyph_offset.Height() != 0);
+ }
+ part_index++;
+ }
+ }
+ run->width_ = std::max(0.0f, assembly_parameters.stretch_size);
+
+ result->width_ = run->width_;
+ result->num_glyphs_ = run->NumGlyphs();
+ result->runs_.push_back(std::move(run));
+ return result;
+}
+
void ShapeResult::ToString(StringBuilder* output) const {
output->Append("#chars=");
output->AppendNumber(num_characters_);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
index eeb7e99b05f..d63fdd62f44 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
@@ -35,6 +35,7 @@
#include "base/containers/span.h"
#include "third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h"
#include "third_party/blink/renderer/platform/fonts/glyph.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
@@ -142,6 +143,17 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
unsigned start_index,
unsigned length,
float width);
+ static scoped_refptr<ShapeResult> CreateForStretchyMathOperator(
+ const Font*,
+ TextDirection,
+ OpenTypeMathStretchData::StretchAxis,
+ Glyph,
+ float stretch_size);
+ static scoped_refptr<ShapeResult> CreateForStretchyMathOperator(
+ const Font*,
+ TextDirection,
+ OpenTypeMathStretchData::StretchAxis,
+ const OpenTypeMathStretchData::AssemblyParameters&);
~ShapeResult();
// Returns a mutable unique instance. If |this| has more than 1 ref count,
@@ -495,6 +507,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
friend class ShapeResultBloberizer;
friend class ShapeResultView;
friend class ShapeResultTest;
+ friend class StretchyOperatorShaper;
template <bool has_non_zero_glyph_offsets>
float ForEachGlyphImpl(float initial_advance,
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc
index 17be9dacea0..91a4ccffadc 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc
@@ -39,7 +39,6 @@ class ShapeResultBloberizerTest : public testing::Test {
font_description.SetGenericFamily(FontDescription::kStandardFamily);
font = Font(font_description);
- font.Update(nullptr);
ASSERT_TRUE(font.CanShapeWordByWord());
fallback_fonts = nullptr;
cache = std::make_unique<ShapeCache>();
@@ -267,7 +266,6 @@ TEST_F(ShapeResultBloberizerTest, CommonAccentLeftToRightFillGlyphBuffer) {
bloberizer.FillGlyphs(run_info, buffer);
Font reference_font(font_description);
- reference_font.Update(nullptr);
reference_font.SetCanShapeWordByWordForTesting(false);
ShapeResultBloberizer reference_bloberizer(reference_font, 1);
@@ -305,7 +303,6 @@ TEST_F(ShapeResultBloberizerTest, CommonAccentRightToLeftFillGlyphBuffer) {
bloberizer.FillGlyphs(run_info, buffer);
Font reference_font(font_description);
- reference_font.Update(nullptr);
reference_font.SetCanShapeWordByWordForTesting(false);
ShapeResultBloberizer reference_bloberizer(reference_font, 1);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
index 73f8a4c0fe3..758065226be 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
@@ -130,7 +130,7 @@ Vector<CharacterRange> ShapeResultBuffer::IndividualCharacterRanges(
float total_width) const {
Vector<CharacterRange> ranges;
float current_x = direction == TextDirection::kRtl ? total_width : 0;
- for (const scoped_refptr<const ShapeResult> result : results_)
+ for (const scoped_refptr<const ShapeResult>& result : results_)
current_x = result->IndividualCharacterRanges(&ranges, current_x);
return ranges;
}
@@ -192,7 +192,7 @@ Vector<double> ShapeResultBuffer::IndividualCharacterAdvances(
Vector<double> advances;
double current_x = direction == TextDirection::kRtl ? total_width : 0;
- for (const scoped_refptr<const ShapeResult> result : results_) {
+ for (const scoped_refptr<const ShapeResult>& result : results_) {
unsigned run_count = result->runs_.size();
result->EnsureGraphemes(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
index a1a6708907c..32fa8f2ab73 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
@@ -211,7 +211,7 @@ struct ShapeResult::RunInfo : public RefCounted<ShapeResult::RunInfo> {
}
if (!Rtl())
- end = num_characters_;
+ end = offset + num_characters_;
else
end = start;
start = index;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc
index 3738a170f1d..8dac0939e7b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc
@@ -21,7 +21,6 @@ class ShapeResultTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
FontDescription::VariantLigatures ligatures;
arabic_font = blink::test::CreateTestFont(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
index 9e558346965..dd4998fb3c0 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
@@ -83,6 +83,15 @@ struct ShapeResultView::RunInfoPart {
// |base::span<RunInfoPart>|.
const RunInfoPart* get() const { return this; }
+ void ExpandRangeToIncludePartialGlyphs(unsigned offset,
+ unsigned* from,
+ unsigned* to) const {
+ DCHECK_GE(offset + start_index_, offset_);
+ unsigned part_offset = offset + start_index_ - offset_;
+ run_->ExpandRangeToIncludePartialGlyphs(
+ part_offset, reinterpret_cast<int*>(from), reinterpret_cast<int*>(to));
+ }
+
scoped_refptr<const ShapeResult::RunInfo> run_;
ShapeResult::RunInfo::GlyphDataRange range_;
@@ -633,4 +642,13 @@ FloatRect ShapeResultView::ComputeInkBounds() const {
return ink_bounds;
}
+void ShapeResultView::ExpandRangeToIncludePartialGlyphs(unsigned* from,
+ unsigned* to) const {
+ unsigned accumulated_offset = char_index_offset_;
+ for (const auto& part : Parts()) {
+ part.ExpandRangeToIncludePartialGlyphs(accumulated_offset, from, to);
+ accumulated_offset += part.NumCharacters();
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
index 591dff49962..05c7fa1563d 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
@@ -145,9 +145,11 @@ class PLATFORM_EXPORT ShapeResultView final
}
void GetRunFontData(Vector<ShapeResult::RunFontData>*) const;
+ void ExpandRangeToIncludePartialGlyphs(unsigned* from, unsigned* to) const;
+
private:
template <class ShapeResultType>
- ShapeResultView(const ShapeResultType*);
+ explicit ShapeResultView(const ShapeResultType*);
struct RunInfoPart;
template <class ShapeResultType>
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
index ce0f6ccb82b..85c46054789 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
@@ -21,7 +21,6 @@ class ShapeResultViewTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
}
void TearDown() override {}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc
index 82eeefad31b..b0296b7f786 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc
@@ -52,7 +52,6 @@ class ShapingLineBreakerTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
}
void TearDown() override {}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc
new file mode 100644
index 00000000000..99c80b364f4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc
@@ -0,0 +1,223 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h"
+
+#include <hb-ot.h>
+#include <hb.h>
+#include <unicode/uchar.h>
+
+#include "third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h"
+#include "third_party/blink/renderer/platform/fonts/font.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h"
+#include "third_party/blink/renderer/platform/geometry/float_rect.h"
+#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
+#include "ui/gfx/skia_util.h"
+
+namespace blink {
+
+namespace {
+
+// HarfBuzz' hb_position_t is a 16.16 fixed-point value.
+inline float HarfBuzzUnitsToFloat(hb_position_t value) {
+ static const float kFloatToHbRatio = 1.0f / (1 << 16);
+ return kFloatToHbRatio * value;
+}
+
+inline float GetGlyphStretchSize(
+ FloatRect bounds,
+ OpenTypeMathStretchData::StretchAxis stretch_axis) {
+ return stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? bounds.Width()
+ : bounds.Height();
+}
+
+inline StretchyOperatorShaper::Metrics ToMetrics(FloatRect bounds) {
+ return {bounds.Width(), -bounds.Y(), bounds.MaxY()};
+}
+
+base::Optional<OpenTypeMathStretchData::AssemblyParameters>
+GetAssemblyParameters(const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ float target_size) {
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ OpenTypeMathSupport::GetGlyphPartRecords(harfbuzz_face, base_glyph,
+ stretch_axis);
+ if (parts.IsEmpty())
+ return base::nullopt;
+
+ hb_font_t* hb_font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+
+ auto hb_stretch_axis =
+ stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? HB_DIRECTION_LTR
+ : HB_DIRECTION_BTT;
+
+ // Go over the assembly parts and determine parameters used below.
+ // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table
+ float min_connector_overlap = HarfBuzzUnitsToFloat(
+ hb_ot_math_get_min_connector_overlap(hb_font, hb_stretch_axis));
+ float max_connector_overlap = std::numeric_limits<float>::max();
+ float non_extender_advance_sum = 0, extender_advance_sum = 0;
+ unsigned non_extender_count = 0, extender_count = 0;
+
+ for (auto& part : parts) {
+ // Calculate the count and advance sums of extender and non-extender glyphs.
+ if (part.is_extender) {
+ extender_count++;
+ extender_advance_sum += part.full_advance;
+ } else {
+ non_extender_count++;
+ non_extender_advance_sum += part.full_advance;
+ }
+
+ // Take into account start connector length for all but the first glyph.
+ if (part.is_extender || &part != &parts.front()) {
+ max_connector_overlap =
+ std::min(max_connector_overlap, part.start_connector_length);
+ }
+
+ // Take into account end connector length for all but the last glyph.
+ if (part.is_extender || &part != &parts.back()) {
+ max_connector_overlap =
+ std::min(max_connector_overlap, part.end_connector_length);
+ }
+ }
+
+ // Check validity conditions indicated in MathML core.
+ float extender_non_overlapping_advance_sum =
+ extender_advance_sum - min_connector_overlap * extender_count;
+ if (extender_count == 0 || max_connector_overlap < min_connector_overlap ||
+ extender_non_overlapping_advance_sum <= 0)
+ return base::nullopt;
+
+ // Calculate the minimal number of repetitions needed to obtain an assembly
+ // size of size at least target size (r_min in MathML Core).
+ unsigned repetition_count = std::max<float>(
+ std::ceil((target_size - non_extender_advance_sum +
+ min_connector_overlap * (non_extender_count - 1)) /
+ extender_non_overlapping_advance_sum),
+ 0);
+
+ // Calculate the number of glyphs, limiting repetition_count to ensure the
+ // assembly does not have more than HarfBuzzRunGlyphData::kMaxGlyphs.
+ DCHECK_LE(non_extender_count, HarfBuzzRunGlyphData::kMaxGlyphs);
+ repetition_count = std::min<unsigned>(
+ repetition_count,
+ (HarfBuzzRunGlyphData::kMaxGlyphs - non_extender_count) / extender_count);
+ unsigned glyph_count = non_extender_count + repetition_count * extender_count;
+ DCHECK_LE(glyph_count, HarfBuzzRunGlyphData::kMaxGlyphs);
+
+ // Calculate the maximum overlap (called o_max in MathML Core) and the number
+ // of glyph in such an assembly (called N in MathML Core).
+ float connector_overlap = max_connector_overlap;
+ if (glyph_count > 1) {
+ float max_connector_overlap_theorical =
+ (non_extender_advance_sum + repetition_count * extender_advance_sum -
+ target_size) /
+ (glyph_count - 1);
+ connector_overlap =
+ std::max(min_connector_overlap,
+ std::min(connector_overlap, max_connector_overlap_theorical));
+ }
+
+ // Calculate the assembly size (called AssemblySize(o, r) in MathML Core).
+ float stretch_size = non_extender_advance_sum +
+ repetition_count * extender_advance_sum -
+ connector_overlap * (glyph_count - 1);
+
+ return base::Optional<OpenTypeMathStretchData::AssemblyParameters>(
+ {connector_overlap, repetition_count, glyph_count, stretch_size,
+ std::move(parts)});
+}
+
+} // namespace
+
+StretchyOperatorShaper::Metrics StretchyOperatorShaper::GetMetrics(
+ const Font* font,
+ float target_size) const {
+ const SimpleFontData* primary_font = font->PrimaryFont();
+ const HarfBuzzFace* harfbuzz_face =
+ primary_font->PlatformData().GetHarfBuzzFace();
+ Glyph base_glyph = primary_font->GlyphForCharacter(stretchy_character_);
+
+ FloatRect bounds;
+
+ // Try different glyph variants.
+ for (auto& variant : OpenTypeMathSupport::GetGlyphVariantRecords(
+ harfbuzz_face, base_glyph, stretch_axis_)) {
+ bounds = primary_font->BoundsForGlyph(variant);
+ if (GetGlyphStretchSize(bounds, stretch_axis_) >= target_size)
+ return ToMetrics(bounds);
+ }
+
+ // Try a glyph assembly.
+ auto params = GetAssemblyParameters(harfbuzz_face, base_glyph, stretch_axis_,
+ target_size);
+ if (!params)
+ return ToMetrics(bounds);
+
+ bounds = stretch_axis_ == OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? FloatRect(0, 0, params->stretch_size, 0)
+ : FloatRect(0, -params->stretch_size, 0, params->stretch_size);
+
+ for (auto& part : params->parts) {
+ // Include dimension of the part, orthogonal to the stretch axis.
+ auto glyph_bounds = primary_font->BoundsForGlyph(part.glyph);
+ if (stretch_axis_ == OpenTypeMathStretchData::StretchAxis::Horizontal) {
+ glyph_bounds.SetX(0);
+ glyph_bounds.SetWidth(0);
+ } else {
+ glyph_bounds.SetY(0);
+ glyph_bounds.SetHeight(0);
+ }
+ bounds.UniteEvenIfEmpty(glyph_bounds);
+ }
+
+ return ToMetrics(bounds);
+}
+
+scoped_refptr<ShapeResult> StretchyOperatorShaper::Shape(
+ const Font* font,
+ float target_size) const {
+ const SimpleFontData* primary_font = font->PrimaryFont();
+ const HarfBuzzFace* harfbuzz_face =
+ primary_font->PlatformData().GetHarfBuzzFace();
+ Glyph base_glyph = primary_font->GlyphForCharacter(stretchy_character_);
+
+ Glyph glyph_variant;
+ float glyph_variant_stretch_size;
+ TextDirection direction = TextDirection::kLtr;
+
+ // Try different glyph variants.
+ for (auto& variant : OpenTypeMathSupport::GetGlyphVariantRecords(
+ harfbuzz_face, base_glyph, stretch_axis_)) {
+ glyph_variant = variant;
+ auto bounds = primary_font->BoundsForGlyph(glyph_variant);
+ glyph_variant_stretch_size = GetGlyphStretchSize(bounds, stretch_axis_);
+ if (glyph_variant_stretch_size >= target_size) {
+ return ShapeResult::CreateForStretchyMathOperator(
+ font, direction, stretch_axis_, glyph_variant,
+ glyph_variant_stretch_size);
+ }
+ }
+
+ // Try a glyph assembly.
+ auto params = GetAssemblyParameters(harfbuzz_face, base_glyph, stretch_axis_,
+ target_size);
+ if (!params) {
+ return ShapeResult::CreateForStretchyMathOperator(
+ font, direction, stretch_axis_, glyph_variant,
+ glyph_variant_stretch_size);
+ }
+
+ return ShapeResult::CreateForStretchyMathOperator(
+ font, direction, stretch_axis_, std::move(*params));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h
new file mode 100644
index 00000000000..4df0edaed15
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h
@@ -0,0 +1,59 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_
+
+#include <base/memory/scoped_refptr.h>
+#include <unicode/uchar.h>
+#include "third_party/blink/renderer/platform/fonts/glyph.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class Font;
+class ShapeResult;
+class StretchyOperatorShaper;
+
+// TODO(https://crbug.com/1057589): Add a TextDirection parameter, so that it's
+// possible to perform glyph-level (rtlm feature) or character-level mirroring
+// before stretching.
+// https://mathml-refresh.github.io/mathml-core/#algorithms-for-glyph-stretching
+class PLATFORM_EXPORT StretchyOperatorShaper final {
+ DISALLOW_NEW();
+
+ public:
+ StretchyOperatorShaper(UChar stretchy_character,
+ OpenTypeMathStretchData::StretchAxis stretch_axis)
+ : stretchy_character_(stretchy_character), stretch_axis_(stretch_axis) {}
+
+ // Returns the metrics of the stretched operator for layout purpose.
+ // May be called multiple times; font and direction may vary between calls.
+ // https://mathml-refresh.github.io/mathml-core/#dfn-box-metrics-of-a-stretchy-glyph
+ struct Metrics {
+ float advance;
+ float ascent;
+ float descent;
+ // TODO(https://crbug.com/1057592): Add italic correction.
+ };
+ Metrics GetMetrics(const Font*, float target_size) const;
+
+ // Shape the stretched operator. The coordinates of the glyph(s) use the same
+ // origin as the rectangle returned by GetMetrics.
+ // May be called multiple times; font and direction may vary between calls.
+ // https://mathml-refresh.github.io/mathml-core/#dfn-shape-a-stretchy-glyph
+ scoped_refptr<ShapeResult> Shape(const Font*, float target_size) const;
+
+ ~StretchyOperatorShaper() = default;
+
+ private:
+ const UChar stretchy_character_;
+ const OpenTypeMathStretchData::StretchAxis stretch_axis_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
new file mode 100644
index 00000000000..1fd1aeaf8bb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
@@ -0,0 +1,264 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h"
+#include "base/memory/scoped_refptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/fonts/font.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_types.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.h"
+#include "third_party/blink/renderer/platform/testing/font_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+namespace {
+
+const UChar32 kLeftBraceCodePoint = '{';
+const UChar32 kOverBraceCodePoint = 0x23DE;
+const UChar32 kArabicMathOperatorHahWithDalCodePoint = 0x1EEF1;
+float kSizeError = .1;
+
+ShapeResultTestInfo* TestInfo(const scoped_refptr<ShapeResult>& result) {
+ return static_cast<ShapeResultTestInfo*>(result.get());
+}
+
+} // namespace
+
+class StretchyOperatorShaperTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ font_description.SetComputedSize(10.0);
+ font = Font(font_description);
+ }
+
+ void TearDown() override {}
+
+ Font CreateMathFont(const String& name, float size = 1000) {
+ FontDescription::VariantLigatures ligatures;
+ return blink::test::CreateTestFont(
+ "MathTestFont",
+ blink::test::BlinkWebTestsFontsTestDataPath(String("math/") + name),
+ size, &ligatures);
+ }
+
+ FontDescription font_description;
+ Font font;
+};
+
+// See createStretchy() in
+// third_party/blink/web_tests/external/wpt/mathml/tools/operator-dictionary.py
+TEST_F(StretchyOperatorShaperTest, GlyphVariants) {
+ Font math = CreateMathFont("operators.woff");
+
+ StretchyOperatorShaper vertical_shaper(
+ kLeftBraceCodePoint, OpenTypeMathStretchData::StretchAxis::Vertical);
+ StretchyOperatorShaper horizontal_shaper(
+ kOverBraceCodePoint, OpenTypeMathStretchData::StretchAxis::Horizontal);
+
+ auto left_brace = math.PrimaryFont()->GlyphForCharacter(kLeftBraceCodePoint);
+ auto over_brace = math.PrimaryFont()->GlyphForCharacter(kOverBraceCodePoint);
+
+ // Calculate glyph indices from the last unicode character in the font.
+ // TODO(https://crbug.com/1057596): Find a better way to access these glyph
+ // indices.
+ auto v0 = math.PrimaryFont()->GlyphForCharacter(
+ kArabicMathOperatorHahWithDalCodePoint) +
+ 1;
+ auto h0 = v0 + 1;
+ auto v1 = h0 + 1;
+ auto h1 = v1 + 1;
+ auto v2 = h1 + 1;
+ auto h2 = v2 + 1;
+
+ // Stretch operators to target sizes (in font units) 125, 250, 375, 500, 625,
+ // 750, 875, 1000, 1125, ..., 3750, 3875, 4000.
+ //
+ // Shaper tries glyphs over_brace/left_brace, h0/v0, h1/v1, h2/v2, h3/v3 of
+ // respective sizes 1000, 1000, 2000, 3000 and 4000. It returns the smallest
+ // glyph larger than the target size.
+ const unsigned size_count = 4;
+ const unsigned subdivision = 8;
+ for (unsigned i = 0; i < size_count; i++) {
+ for (unsigned j = 1; j <= subdivision; j++) {
+ // Due to floating-point errors, the actual metrics of the size variants
+ // might actually be slightly smaller than expected. Reduce the
+ // target_size by kSizeError to ensure that the shaper picks the desired
+ // size variant.
+ float target_size = i * 1000 + (j * 1000 / subdivision) - kSizeError;
+
+ // Metrics of horizontal size variants.
+ {
+ auto metrics = horizontal_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, (i + 1) * 1000, kSizeError);
+ EXPECT_NEAR(metrics.ascent, 1000, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Metrics of vertical size variants.
+
+ {
+ auto metrics = vertical_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, 1000, kSizeError);
+ EXPECT_NEAR(metrics.ascent, (i + 1) * 1000, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Shaping of horizontal size variants.
+ {
+ scoped_refptr<ShapeResult> result =
+ horizontal_shaper.Shape(&math, target_size);
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), 1u);
+ Glyph expected_variant = i ? h0 + 2 * i : over_brace;
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), expected_variant);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), (i + 1) * 1000,
+ kSizeError);
+ }
+
+ // Shaping of vertical size variants.
+ {
+ scoped_refptr<ShapeResult> result =
+ vertical_shaper.Shape(&math, target_size);
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), 1u);
+ Glyph expected_variant = i ? v0 + 2 * i : left_brace;
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), expected_variant);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), (i + 1) * 1000,
+ kSizeError);
+ }
+ }
+ }
+
+ // Stretch an operator to target sizes (in font units) much larger than 4000.
+ //
+ // This will force an assembly with the following parts:
+ // _____________________________________________________________
+ // Part | MaxStartOverlap | MaxEndOverlap | Advance | Extender |
+ // h2/v2 | 0 | 1000 | 3000 | false |
+ // h1/v1 | 1000 | 1000 | 2000 | true |
+ //
+ // For an assembly made of one non-extender glyph h2/v2 and repetition_count
+ // copies of extenders h1/v1, the size is
+ // advance(h2/v2) + repetition_count * (advance(h1/v1) - overlap).
+ //
+ // For repetition_count = k and overlap = 750, the size is X = 1250k + 3000.
+ //
+ // Since the font min overlap is 500, for repetition_count = k - 1 the size
+ // is at most Y = 1500k + 1500.
+ //
+ // Since the max overlap of parts is 1000, for repetition_count = k + 1 the
+ // size is at least Z = 1000k + 4000.
+ //
+ // { X - 4000 = 1250k - 1000 >= 250 >> kSizeError for k >= 1.
+ // { X - Y = 1500 - 250k >= 250 >> kSizeError for k <= 5.
+ // Hence setting the target size to 1250k + 3000 will ensure an assembly of
+ // k + 1 glyphs and overlap close to 750 for 1 <= k <= 5.
+ //
+ // Additionally, X - Z = 250k - 1000 = 250 >> kSizeError for k = 5 so this
+ // case also verifies that the minimal number of repetitions is actually used.
+ //
+ for (unsigned repetition_count = 1; repetition_count <= 5;
+ repetition_count++) {
+ // It is not necessary to decrease the target_size by kSizeError here. The
+ // shaper can just increase overlap by kSizeError / repetition_count to
+ // reduce the actual size of the assembly.
+ float overlap = 750;
+ float target_size = 3000 + repetition_count * (2000 - overlap);
+
+ // Metrics of horizontal assembly.
+ {
+ auto metrics = horizontal_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, target_size, kSizeError);
+ EXPECT_NEAR(metrics.ascent, 1000, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Metrics of vertical assembly.
+ {
+ auto metrics = vertical_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, 1000, kSizeError);
+ EXPECT_NEAR(metrics.ascent, target_size, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Shaping of horizontal assembly.
+ // From left to right: h2, h1, h1, h1, ...
+ {
+ scoped_refptr<ShapeResult> result =
+ horizontal_shaper.Shape(&math, target_size);
+
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(),
+ repetition_count + 1);
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), h2);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), 3000 - overlap,
+ kSizeError);
+ for (unsigned i = 0; i < repetition_count - 1; i++) {
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, i + 1), h1);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, i + 1),
+ 2000 - overlap, kSizeError);
+ }
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, repetition_count), h1);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, repetition_count),
+ 2000, kSizeError);
+ }
+
+ // Shaping of vertical assembly.
+ // From bottom to top: v2, v1, v1, v1, ...
+ {
+ scoped_refptr<ShapeResult> result =
+ vertical_shaper.Shape(&math, target_size);
+
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(),
+ repetition_count + 1);
+ for (unsigned i = 0; i < repetition_count; i++) {
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, i), v1);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, i), 2000 - overlap,
+ kSizeError);
+ }
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, repetition_count), v2);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, repetition_count),
+ 3000, kSizeError);
+ }
+ }
+
+ // Stretch an operator to edge target size values.
+ //
+ // These tests verify that it does not cause any assertion or crashes.
+ {
+ // Zero.
+ float target_size = 0;
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // Negative.
+ target_size = -5500;
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // Max limit.
+ target_size = std::numeric_limits<float>::max();
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // Min limit.
+ target_size = std::numeric_limits<float>::min();
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // More than the max number of glyphs.
+ // The size of an assembly with one non-extender v2/h2 and k - 1 extenders
+ // h1/v1 and minimal overlap 500 is Y = 1500k + 1500.
+ // So target_size - Y >= 250 >> kSizeError if the assembly does not have
+ // more than the max number of glyphs.
+ target_size = 1500 * HarfBuzzRunGlyphData::kMaxGlyphs + 1750;
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h
index 7c5e9561c83..070cde2e8ba 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/platform/fonts/typesetting_features.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/skia/include/core/SkFont.h"
@@ -245,7 +246,12 @@ ALWAYS_INLINE float SimpleFontData::WidthForGlyph(Glyph glyph) const {
#endif
}
-DEFINE_FONT_DATA_TYPE_CASTS(SimpleFontData, false);
+template <>
+struct DowncastTraits<SimpleFontData> {
+ static bool AllowFrom(const FontData& fontData) {
+ return !fontData.IsSegmented();
+ }
+};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SIMPLE_FONT_DATA_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc b/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
index 51bdbb7510c..7537fb4d036 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
@@ -33,6 +33,7 @@
#include <memory>
#include <utility>
+#include "base/logging.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/blink/public/platform/platform.h"
@@ -245,6 +246,13 @@ sk_sp<SkTypeface> FontCache::CreateTypeface(
name.c_str(), font_description.SkiaFontStyle());
}
+#if !defined(OS_MACOSX)
+std::vector<FontEnumerationEntry> FontCache::EnumeratePlatformAvailableFonts() {
+ NOTIMPLEMENTED();
+ return std::vector<FontEnumerationEntry>();
+}
+#endif // !defined(OS_MACOSX)
+
#if !defined(OS_WIN)
std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
const FontDescription& font_description,
diff --git a/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h b/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h
index 6a72122ee22..f638f1c8393 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h
@@ -15,6 +15,10 @@ class SkFont;
namespace blink {
+// TODO: Width functions are affected by issue
+// https://bugs.chromium.org/p/skia/issues/detail?id=10123 in Skia, which
+// currently does not return trak-free advances on Mac OS 10.15.
+
void SkFontGetGlyphWidthForHarfBuzz(const SkFont&,
hb_codepoint_t,
hb_position_t* width);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc b/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc
index 9b5a8ed881f..e72f801016a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc
@@ -30,15 +30,12 @@
#include "third_party/blink/renderer/platform/fonts/web_font_decoder.h"
-#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/ots/include/ots-memory-stream.h"
#include "third_party/skia/include/core/SkStream.h"
@@ -145,38 +142,6 @@ ots::TableAction BlinkOTSContext::GetTableAction(uint32_t tag) {
}
}
-void RecordDecodeSpeedHistogram(const char* data,
- size_t length,
- double decode_time,
- size_t decoded_size) {
- if (decode_time <= 0)
- return;
-
- double kb_per_second = decoded_size / (1000 * decode_time);
- if (length >= 4) {
- if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, woff_histogram,
- ("WebFont.DecodeSpeed.WOFF", 1000, 300000, 50));
- woff_histogram.Count(kb_per_second);
- return;
- }
-
- if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2') {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, woff2_histogram,
- ("WebFont.DecodeSpeed.WOFF2", 1000, 300000, 50));
- woff2_histogram.Count(kb_per_second);
- return;
- }
- }
-
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, sfnt_histogram,
- ("WebFont.DecodeSpeed.SFNT", 1000, 300000, 50));
- sfnt_histogram.Count(kb_per_second);
-}
-
} // namespace
sk_sp<SkTypeface> WebFontDecoder::Decode(SharedBuffer* buffer) {
@@ -196,14 +161,13 @@ sk_sp<SkTypeface> WebFontDecoder::Decode(SharedBuffer* buffer) {
// Most web fonts are compressed, so the result can be much larger than
// the original.
ots::ExpandingMemoryStream output(buffer->size(), kMaxWebFontSize);
- base::ElapsedTimer timer;
BlinkOTSContext ots_context;
SharedBuffer::DeprecatedFlatData flattened_buffer(buffer);
- const char* data = flattened_buffer.Data();
TRACE_EVENT_BEGIN0("blink", "DecodeFont");
- bool ok = ots_context.Process(&output, reinterpret_cast<const uint8_t*>(data),
- buffer->size());
+ bool ok = ots_context.Process(
+ &output, reinterpret_cast<const uint8_t*>(flattened_buffer.Data()),
+ buffer->size());
TRACE_EVENT_END0("blink", "DecodeFont");
if (!ok) {
@@ -212,9 +176,6 @@ sk_sp<SkTypeface> WebFontDecoder::Decode(SharedBuffer* buffer) {
}
const size_t decoded_length = SafeCast<size_t>(output.Tell());
- RecordDecodeSpeedHistogram(data, buffer->size(), timer.Elapsed().InSecondsF(),
- decoded_length);
-
sk_sp<SkData> sk_data = SkData::MakeWithCopy(output.get(), decoded_length);
sk_sp<SkTypeface> new_typeface;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc
index a563a80074d..9544a0ed0ab 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc
@@ -49,12 +49,11 @@ void FallbackFamilyStyleCache::Put(
String cache_key =
makeCacheKey(generic_family, bcp47_language_tag, fallback_priority);
- FallbackLruCache::TypefaceVector* existing_typefaces =
- recent_fallback_fonts_.Get(cache_key);
+ TypefaceVector* existing_typefaces = recent_fallback_fonts_.Get(cache_key);
if (existing_typefaces) {
existing_typefaces->insert(0, sk_ref_sp(typeface));
} else {
- FallbackLruCache::TypefaceVector typefaces;
+ TypefaceVector typefaces;
typefaces.push_back(sk_ref_sp(typeface));
recent_fallback_fonts_.Put(std::move(cache_key), std::move(typefaces));
}
@@ -67,7 +66,7 @@ void FallbackFamilyStyleCache::Get(
UChar32 character,
String* fallback_family,
SkFontStyle* fallback_style) {
- FallbackLruCache::TypefaceVector* typefaces = recent_fallback_fonts_.Get(
+ TypefaceVector* typefaces = recent_fallback_fonts_.Get(
makeCacheKey(generic_family, bcp47_language_tag, fallback_priority));
if (!typefaces)
return;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h
index 5e8f86ebcf9..770702feb39 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h
@@ -7,12 +7,15 @@
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h"
-#include "third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h"
+#include "third_party/blink/renderer/platform/wtf/lru_cache.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
namespace blink {
+using TypefaceVector = Vector<sk_sp<SkTypeface>>;
+using FallbackLruCache = WTF::LruCache<String, TypefaceVector>;
+
class FallbackFamilyStyleCache {
USING_FAST_MALLOC(FallbackFamilyStyleCache);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc
deleted file mode 100644
index 37b6a152785..00000000000
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h"
-
-#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-FallbackLruCache::FallbackLruCache(size_t max_size) : max_size_(max_size) {
- DCHECK_GT(max_size_, 0u);
-}
-
-FallbackLruCache::TypefaceVector* FallbackLruCache::Get(const String& key) {
- HashMapType::iterator find_result = map_.find(key);
- if (find_result == map_.end())
- return nullptr;
-
- // Move result to beginning of list.
- KeyListNode* node = find_result->value.ListNode();
- ordering_.Remove(node);
- ordering_.Push(node);
- return find_result->value.value();
-}
-
-void FallbackLruCache::Put(String&& key, TypefaceVector&& arg) {
- HashMapType::iterator find_result = map_.find(key);
- if (find_result != map_.end()) {
- ordering_.Remove(find_result->value.ListNode());
- map_.erase(find_result);
- }
-
- if (map_.size() >= max_size_) {
- RemoveLeastRecentlyUsed();
- }
-
- std::unique_ptr<KeyListNode> list_node = std::make_unique<KeyListNode>(key);
- HashMapType::AddResult add_result = map_.insert(
- std::move(key), MappedWithListNode(std::move(arg), std::move(list_node)));
- DCHECK(add_result.is_new_entry);
- ordering_.Push(add_result.stored_value->value.ListNode());
-}
-
-void FallbackLruCache::Clear() {
- map_.clear();
- ordering_.Clear();
-}
-
-void FallbackLruCache::RemoveLeastRecentlyUsed() {
- KeyListNode* tail = ordering_.Tail();
- ordering_.Remove(tail);
- map_.erase(tail->key());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h
deleted file mode 100644
index 90048e3319a..00000000000
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/doubly_linked_list.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FALLBACK_LRU_CACHE_WIN_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FALLBACK_LRU_CACHE_WIN_H_
-
-namespace blink {
-
-/* A LRU cache for storing a a vector of typefaces for a particular key string,
- * which would usually be a locale plus potential additional parameters. Uses a
- * HashMap for storage and access and a DoublyLinkedList for managing age of
- * entries. TODO(https://crbug.com/1010925): Potentially move this to a generic
- * LRU Cache implementation once we have such in WTF. */
-class PLATFORM_EXPORT FallbackLruCache {
- USING_FAST_MALLOC(FallbackLruCache);
-
- public:
- FallbackLruCache(size_t max_size);
-
- using TypefaceVector = Vector<sk_sp<SkTypeface>>;
-
- TypefaceVector* Get(const String& key);
- void Put(String&& key, TypefaceVector&& arg);
-
- void Clear();
-
- size_t size() const { return map_.size(); }
-
- private:
- class KeyListNode final : public DoublyLinkedListNode<KeyListNode> {
- USING_FAST_MALLOC(KeyListNode);
-
- public:
- friend class DoublyLinkedListNode<KeyListNode>;
- KeyListNode(const String& key) : key_(key) {}
-
- const String& key() const { return key_; }
-
- private:
- String key_;
- KeyListNode* prev_{nullptr};
- KeyListNode* next_{nullptr};
- };
-
- class MappedWithListNode {
- USING_FAST_MALLOC(MappedWithListNode);
-
- public:
- MappedWithListNode(TypefaceVector&& mapped_arg,
- std::unique_ptr<KeyListNode>&& list_node)
- : mapped_value_(std::move(mapped_arg)),
- list_node_(std::move(list_node)) {}
-
- MappedWithListNode(WTF::HashTableDeletedValueType) {
- list_node_.reset(reinterpret_cast<KeyListNode*>(-1));
- }
-
- TypefaceVector* value() { return &mapped_value_; }
- KeyListNode* ListNode() { return list_node_.get(); }
-
- private:
- TypefaceVector mapped_value_;
- std::unique_ptr<KeyListNode> list_node_;
- };
-
- void RemoveLeastRecentlyUsed();
-
- using HashMapType = HashMap<String,
- MappedWithListNode,
- DefaultHash<String>::Hash,
- HashTraits<String>,
- SimpleClassHashTraits<MappedWithListNode>>;
-
- HashMapType map_;
- DoublyLinkedList<KeyListNode> ordering_;
- size_t max_size_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FALLBACK_LRU_CACHE_WIN_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc
index 92f78aa9e38..917f0111235 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h"
+#include "third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
@@ -29,7 +32,7 @@ void fillCacheWithDummies(blink::FallbackLruCache& lru_cache,
const char* format_string,
size_t count) {
for (size_t i = 0; i < count; ++i) {
- blink::FallbackLruCache::TypefaceVector dummy_typefaces;
+ blink::TypefaceVector dummy_typefaces;
dummy_typefaces.push_back(
SkTypeface::MakeFromName(kFontFamilyNameArial, SkFontStyle()));
lru_cache.Put(String::Format(format_string, i), std::move(dummy_typefaces));
@@ -48,7 +51,7 @@ TEST(FallbackLruCacheTest, KeepChineseWhenFetched) {
// the Chinese font and ensure it's gone.
FallbackLruCache lru_cache(kLruCacheTestSize);
EXPECT_EQ(lru_cache.size(), 0u);
- FallbackLruCache::TypefaceVector fallback_typefaces_zh;
+ TypefaceVector fallback_typefaces_zh;
fallback_typefaces_zh.push_back(
fallbackForLocale(kHanSimplifiedLocale, kFirstCJKIdeograph));
lru_cache.Put(kHanSimplifiedLocale, std::move(fallback_typefaces_zh));
@@ -56,8 +59,7 @@ TEST(FallbackLruCacheTest, KeepChineseWhenFetched) {
EXPECT_EQ(lru_cache.size(), 1u);
fillCacheWithDummies(lru_cache, "dummy_locale_%zu", kLruCacheTestSize - 1);
- FallbackLruCache::TypefaceVector* chinese_typefaces =
- lru_cache.Get(kHanSimplifiedLocale);
+ TypefaceVector* chinese_typefaces = lru_cache.Get(kHanSimplifiedLocale);
EXPECT_TRUE(chinese_typefaces);
EXPECT_TRUE(chinese_typefaces->at(0)->unicharToGlyph(0x4E01));
EXPECT_EQ(lru_cache.size(), kLruCacheTestSize);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
index 821a6a7afc3..52427643b20 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
@@ -42,7 +42,7 @@
#include "base/debug/alias.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
-#include "third_party/blink/public/platform/interface_provider.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/fonts/bitmap_glyphs_block_list.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
@@ -229,7 +229,7 @@ void FontCache::SetStatusFontMetrics(const wchar_t* family_name,
void FontCache::EnsureServiceConnected() {
if (service_)
return;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
service_.BindNewPipeAndPassReceiver());
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
index 52555021f7b..13162712b2e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
@@ -9,8 +9,8 @@
#include "base/files/file_path.h"
#include "mojo/public/mojom/base/shared_memory.mojom-blink.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -165,7 +165,7 @@ bool FontUniqueNameLookupWin::IsFontUniqueNameLookupReadyForSyncLookup() {
void FontUniqueNameLookupWin::EnsureServiceConnected() {
if (service_)
return;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
service_.BindNewPipeAndPassReceiver());
}