summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/fonts
diff options
context:
space:
mode:
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.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h22
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_metrics.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_platform_data.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_platform_data.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selection_types.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm58
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc149
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support_test.cc59
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc78
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc69
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc105
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/web_font_render_style.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc160
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc60
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc75
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.h25
41 files changed, 795 insertions, 490 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 0b211881222..be4552bc788 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,39 +4,15 @@
#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/platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom-blink.h"
-#include "third_party/blink/public/platform/platform.h"
namespace blink {
FontUniqueNameLookupAndroid::~FontUniqueNameLookupAndroid() = default;
-bool FontUniqueNameLookupAndroid::EnsureMatchingServiceConnected() {
- if (font_table_matcher_)
- return true;
-
- mojom::blink::FontUniqueNameLookupPtr service;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
- mojo::MakeRequest(&service));
-
- base::ReadOnlySharedMemoryRegion region_ptr;
- if (!service->GetUniqueNameLookupTable(&region_ptr)) {
- // Tests like StyleEngineTest do not set up a full browser where Blink can
- // connect to a browser side service for font lookups. Placing a DCHECK here
- // is too strict for such a case.
- LOG(ERROR) << "Unable to connect to browser side service for src: local() "
- "font lookup.";
- return false;
- }
-
- font_table_matcher_ = std::make_unique<FontTableMatcher>(region_ptr.Map());
- return true;
-}
-
sk_sp<SkTypeface> FontUniqueNameLookupAndroid::MatchUniqueName(
const String& font_unique_name) {
- if (!EnsureMatchingServiceConnected())
+ if (!EnsureMatchingServiceConnected<mojom::blink::FontUniqueNameLookupPtr>())
return nullptr;
base::Optional<FontTableMatcher::MatchResult> match_result =
font_table_matcher_->MatchName(font_unique_name.Utf8().data());
diff --git a/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h
index 54b1cc7c177..4447709a405 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h
@@ -19,8 +19,6 @@ class FontUniqueNameLookupAndroid : public FontUniqueNameLookup {
sk_sp<SkTypeface> MatchUniqueName(const String& font_unique_name) override;
private:
- bool EnsureMatchingServiceConnected();
- std::unique_ptr<FontTableMatcher> font_table_matcher_;
DISALLOW_COPY_AND_ASSIGN(FontUniqueNameLookupAndroid);
};
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 b72da9f7015..92d453b5a84 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/platform/fonts/font_global_context.h"
#include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
#include "third_party/blink/renderer/platform/fonts/font_smoothing_mode.h"
+#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
#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/fonts/text_rendering_mode.h"
@@ -117,7 +118,10 @@ FontPlatformData* FontCache::GetFontPlatformData(
float size = font_description.EffectiveFontSize();
unsigned rounded_size = size * FontCacheKey::PrecisionMultiplier();
- FontCacheKey key = font_description.CacheKey(creation_params);
+ bool is_unique_match =
+ alternate_font_name == AlternateFontName::kLocalUniqueFace;
+ FontCacheKey key =
+ font_description.CacheKey(creation_params, is_unique_match);
// Remove the font size from the cache key, and handle the font size
// separately in the inner HashMap. So that different size of FontPlatformData
@@ -440,4 +444,18 @@ void FontCache::DumpShapeResultCache(
WTF::Partitions::kAllocatedObjectPoolName);
}
+sk_sp<SkTypeface> FontCache::CreateTypefaceFromUniqueName(
+ const FontFaceCreationParams& creation_params,
+ CString& name) {
+ FontUniqueNameLookup* unique_name_lookup =
+ FontGlobalContext::Get()->GetFontUniqueNameLookup();
+ DCHECK(unique_name_lookup);
+ sk_sp<SkTypeface> uniquely_identified_font =
+ unique_name_lookup->MatchUniqueName(creation_params.Family());
+ if (uniquely_identified_font) {
+ return uniquely_identified_font;
+ }
+ return nullptr;
+}
+
} // 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 f32563d2997..589e0baf11a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
@@ -253,6 +253,9 @@ class PLATFORM_EXPORT FontCache {
UChar32,
const SimpleFontData* font_data_to_substitute,
FontFallbackPriority = FontFallbackPriority::kText);
+ sk_sp<SkTypeface> CreateTypefaceFromUniqueName(
+ const FontFaceCreationParams& creation_params,
+ CString& name);
friend class FontGlobalContext;
FontCache();
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 a7823cbb3e2..f9d07ff2efa 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
@@ -53,17 +53,20 @@ struct FontCacheKey {
: creation_params_(),
font_size_(0),
options_(0),
- device_scale_factor_(0) {}
+ device_scale_factor_(0),
+ is_unique_match_(false) {}
FontCacheKey(FontFaceCreationParams creation_params,
float font_size,
unsigned options,
float device_scale_factor,
- scoped_refptr<FontVariationSettings> variation_settings)
+ scoped_refptr<FontVariationSettings> variation_settings,
+ bool is_unique_match)
: creation_params_(creation_params),
font_size_(font_size * kFontSizePrecisionMultiplier),
options_(options),
device_scale_factor_(device_scale_factor),
- variation_settings_(std::move(variation_settings)) {}
+ variation_settings_(std::move(variation_settings)),
+ is_unique_match_(is_unique_match) {}
FontCacheKey(WTF::HashTableDeletedValueType)
: font_size_(HashTableDeletedSize()) {}
@@ -71,10 +74,13 @@ struct FontCacheKey {
unsigned GetHash() const {
// Convert from float with 3 digit precision before hashing.
unsigned device_scale_factor_hash = device_scale_factor_ * 1000;
- unsigned hash_codes[5] = {
- creation_params_.GetHash(), font_size_, options_,
+ unsigned hash_codes[6] = {
+ creation_params_.GetHash(),
+ font_size_,
+ options_,
device_scale_factor_hash,
- variation_settings_ ? variation_settings_->GetHash() : 0};
+ variation_settings_ ? variation_settings_->GetHash() : 0,
+ is_unique_match_};
return StringHasher::HashMemory<sizeof(hash_codes)>(hash_codes);
}
@@ -82,7 +88,8 @@ struct FontCacheKey {
return creation_params_ == other.creation_params_ &&
font_size_ == other.font_size_ && options_ == other.options_ &&
device_scale_factor_ == other.device_scale_factor_ &&
- variation_settings_ == other.variation_settings_;
+ variation_settings_ == other.variation_settings_ &&
+ is_unique_match_ == other.is_unique_match_;
}
bool IsHashTableDeletedValue() const {
@@ -105,6 +112,7 @@ struct FontCacheKey {
// device_scale_factor_ to be a part of computing the cache key.
float device_scale_factor_;
scoped_refptr<FontVariationSettings> variation_settings_;
+ bool is_unique_match_;
};
struct FontCacheKeyHash {
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description.cc b/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
index 32d2a97d5a2..63eff2f4e24 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
@@ -214,6 +214,7 @@ float FontDescription::EffectiveFontSize() const {
FontCacheKey FontDescription::CacheKey(
const FontFaceCreationParams& creation_params,
+ bool is_unique_match,
const FontSelectionRequest& font_selection_request) const {
unsigned options =
static_cast<unsigned>(fields_.synthetic_italic_) << 6 | // bit 7
@@ -229,7 +230,8 @@ FontCacheKey FontDescription::CacheKey(
#endif
FontCacheKey cache_key(creation_params, EffectiveFontSize(),
options | font_selection_request_.GetHash() << 8,
- device_scale_factor_for_key, variation_settings_);
+ device_scale_factor_for_key, variation_settings_,
+ is_unique_match);
return cache_key;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description.h b/chromium/third_party/blink/renderer/platform/fonts/font_description.h
index 925923d8ff1..f97284d0220 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.h
@@ -252,6 +252,7 @@ class PLATFORM_EXPORT FontDescription {
const; // Returns either the computedSize or the computedPixelSize
FontCacheKey CacheKey(
const FontFaceCreationParams&,
+ bool is_unique_match,
const FontSelectionRequest& = FontSelectionRequest()) const;
void SetFamily(const FontFamily& family) { family_list_ = family; }
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc b/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc
index e573d634fb5..c5935c6bfb4 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/platform/fonts/font_description.h"
+#include "base/stl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -48,11 +49,11 @@ TEST(FontDescriptionTest, TestHashCollision) {
FontDescription source;
WTF::Vector<unsigned> hashes;
- for (size_t i = 0; i < arraysize(weights); i++) {
+ for (size_t i = 0; i < base::size(weights); i++) {
source.SetWeight(weights[i]);
- for (size_t j = 0; j < arraysize(stretches); j++) {
+ for (size_t j = 0; j < base::size(stretches); j++) {
source.SetStretch(stretches[j]);
- for (size_t k = 0; k < arraysize(slopes); k++) {
+ for (size_t k = 0; k < base::size(slopes); k++) {
source.SetStyle(slopes[k]);
unsigned hash = source.StyleHashWithoutFamilyList();
ASSERT_FALSE(hashes.Contains(hash));
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 85e8fbc134c..be346f33c16 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
@@ -202,7 +202,8 @@ FallbackListCompositeKey FontFallbackList::CompositeKey(
platform_data);
}
if (result) {
- key.Add(font_description.CacheKey(params));
+ bool is_unique_match = false;
+ key.Add(font_description.CacheKey(params, is_unique_match));
if (!result->IsSegmented() && !result->IsCustomFont())
FontCache::GetFontCache()->ReleaseFontData(ToSimpleFontData(result));
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_metrics.cc b/chromium/third_party/blink/renderer/platform/fonts/font_metrics.cc
index abc03f40a1b..b4ed950174e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_metrics.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_metrics.cc
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/platform/fonts/vdmx_parser.h"
#include <SkFont.h>
+#include <SkFontMetrics.h>
#include <SkTypeface.h>
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.cc b/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.cc
index 64dd8218e9a..77b09a33375 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.cc
@@ -51,7 +51,7 @@ FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
is_hash_table_deleted_value_(true)
#if defined(OS_WIN)
,
- paint_text_flags_(0)
+ font_flags_(0)
#endif
{
}
@@ -65,7 +65,7 @@ FontPlatformData::FontPlatformData()
is_hash_table_deleted_value_(false)
#if defined(OS_WIN)
,
- paint_text_flags_(0)
+ font_flags_(0)
#endif
{
}
@@ -82,7 +82,7 @@ FontPlatformData::FontPlatformData(float size,
is_hash_table_deleted_value_(false)
#if defined(OS_WIN)
,
- paint_text_flags_(0)
+ font_flags_(0)
#endif
{
}
@@ -104,7 +104,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& source)
is_hash_table_deleted_value_(false)
#if defined(OS_WIN)
,
- paint_text_flags_(source.paint_text_flags_)
+ font_flags_(source.font_flags_)
#endif
{
}
@@ -140,7 +140,7 @@ FontPlatformData::FontPlatformData(sk_sp<SkTypeface> typeface,
is_hash_table_deleted_value_(false)
#if defined(OS_WIN)
,
- paint_text_flags_(0)
+ font_flags_(0)
#endif
{
#if !defined(OS_WIN) && !defined(OS_MACOSX)
@@ -200,7 +200,7 @@ const FontPlatformData& FontPlatformData::operator=(
#endif
#if defined(OS_WIN)
- paint_text_flags_ = 0;
+ font_flags_ = 0;
#endif
return *this;
@@ -311,20 +311,6 @@ WebFontRenderStyle FontPlatformData::QuerySystemRenderStyle(
return result;
}
-void FontPlatformData::SetupSkPaint(SkPaint* font,
- float device_scale_factor,
- const Font*) const {
- style_.ApplyToSkPaint(*font, device_scale_factor);
-
- const float ts = text_size_ >= 0 ? text_size_ : 12;
- font->setTextSize(SkFloatToScalar(ts));
- font->setTypeface(typeface_);
- font->setFakeBoldText(synthetic_bold_);
- font->setTextSkewX(synthetic_italic_ ? -SK_Scalar1 / 4 : 0);
-
- font->setEmbeddedBitmapText(!avoid_embedded_bitmaps_);
-}
-
void FontPlatformData::SetupSkFont(SkFont* font,
float device_scale_factor,
const Font*) const {
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.h b/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.h
index 7c6939331e2..e2e018ff469 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_platform_data.h
@@ -31,8 +31,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_PLATFORM_DATA_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_PLATFORM_DATA_H_
-#include "SkPaint.h"
-#include "SkTypeface.h"
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/web_font_render_style.h"
@@ -46,6 +44,7 @@
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
@@ -154,17 +153,17 @@ class PLATFORM_EXPORT FontPlatformData {
const WebFontRenderStyle& GetFontRenderStyle() const { return style_; }
#endif
- // TODO(reed): SetupSkPaint is deprecated. Remove this once all call sites
- // are moved to SetupSkFont.
- void SetupSkPaint(SkPaint*,
- float device_scale_factor = 1,
- const Font* = nullptr) const;
void SetupSkFont(SkFont*,
float device_scale_factor = 1,
const Font* = nullptr) const;
#if defined(OS_WIN)
- int PaintTextFlags() const { return paint_text_flags_; }
+ enum Flags {
+ kAntiAlias = 1 << 0,
+ kSubpixelsAntiAlias = 1 << 1,
+ kSubpixelMetrics = 1 << 2,
+ };
+ int FontFlags() const { return font_flags_; }
#endif
private:
@@ -199,8 +198,8 @@ class PLATFORM_EXPORT FontPlatformData {
mutable scoped_refptr<HarfBuzzFace> harfbuzz_face_;
bool is_hash_table_deleted_value_;
#if defined(OS_WIN)
- // TODO(https://crbug.com/808221): Replace |paint_text_flags_| with |style_|.
- int paint_text_flags_;
+ // TODO(https://crbug.com/808221): Replace |font_flags_| with |style_|.
+ int font_flags_;
#endif
};
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selection_types.h b/chromium/third_party/blink/renderer/platform/fonts/font_selection_types.h
index 5fb1723e2fe..85d2cb47c23 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selection_types.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selection_types.h
@@ -185,6 +185,18 @@ static inline const FontSelectionValue& ItalicSlopeValue() {
return italicValue;
}
+static inline const FontSelectionValue& MaxObliqueValue() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, maxObliqueValue,
+ (90));
+ return maxObliqueValue;
+}
+
+static inline const FontSelectionValue& MinObliqueValue() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, minObliqueValue,
+ (-90));
+ return minObliqueValue;
+}
+
static inline const FontSelectionValue& BoldThreshold() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, boldThreshold,
(600));
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc
index 1a084984c34..ef45e9929b1 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc
@@ -4,12 +4,17 @@
#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
#include "base/macros.h"
-#include "build/build_config.h"
+#include "third_party/blink/public/platform/interface_provider.h"
+#include "third_party/blink/public/platform/platform.h"
#if defined(OS_ANDROID)
+#include "third_party/blink/public/platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom-blink.h"
#include "third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h"
#elif defined(OS_LINUX)
#include "third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.h"
+#elif defined(OS_WIN)
+#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h"
+#include "third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.h"
#endif
namespace blink {
@@ -23,10 +28,45 @@ FontUniqueNameLookup::GetPlatformUniqueNameLookup() {
return std::make_unique<FontUniqueNameLookupAndroid>();
#elif defined(OS_LINUX)
return std::make_unique<FontUniqueNameLookupLinux>();
+#elif defined(OS_WIN)
+ return std::make_unique<FontUniqueNameLookupWin>();
#else
NOTREACHED();
return nullptr;
#endif
}
+#if defined(OS_WIN) || defined(OS_ANDROID)
+template <class ServicePtrType>
+bool FontUniqueNameLookup::EnsureMatchingServiceConnected() {
+ if (font_table_matcher_)
+ return true;
+
+ ServicePtrType service;
+ Platform::Current()->GetInterfaceProvider()->GetInterface(
+ mojo::MakeRequest(&service));
+
+ base::ReadOnlySharedMemoryRegion region_ptr;
+ if (!service->GetUniqueNameLookupTable(&region_ptr)) {
+ // Tests like StyleEngineTest do not set up a full browser where Blink can
+ // connect to a browser side service for font lookups. Placing a DCHECK here
+ // is too strict for such a case.
+ LOG(ERROR) << "Unable to connect to browser side service for src: local() "
+ "font lookup.";
+ return false;
+ }
+
+ font_table_matcher_ = std::make_unique<FontTableMatcher>(region_ptr.Map());
+ return true;
+}
+#endif
+
+#if defined(OS_ANDROID)
+template bool FontUniqueNameLookup::EnsureMatchingServiceConnected<
+ mojom::blink::FontUniqueNameLookupPtr>();
+#elif defined(OS_WIN)
+template bool FontUniqueNameLookup::EnsureMatchingServiceConnected<
+ mojom::blink::DWriteFontProxyPtr>();
+#endif
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h
index 38428c7a9dc..58f5390436b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h
@@ -6,14 +6,21 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_UNIQUE_NAME_LOOKUP_H_
#include "base/macros.h"
+#include "build/build_config.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#if defined(OS_ANDROID) || defined(OS_WIN)
+#include "third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h"
+#endif
+
#include <SkRefCnt.h>
#include <SkTypeface.h>
#include <memory>
namespace blink {
+class FontTableMatcher;
+
class FontUniqueNameLookup {
public:
// Factory function to construct a platform specific font unique name lookup
@@ -28,6 +35,14 @@ class FontUniqueNameLookup {
protected:
FontUniqueNameLookup();
+ // Windows and Android share the concept of connecting to a Mojo service for
+ // retrieving a ReadOnlySharedMemoryRegion with the lookup table in it.
+#if defined(OS_WIN) || defined(OS_ANDROID)
+ template <class ServicePtrType>
+ bool EnsureMatchingServiceConnected();
+ std::unique_ptr<FontTableMatcher> font_table_matcher_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(FontUniqueNameLookup);
};
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 97bebbdb53a..1fcd34ea515 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
@@ -25,6 +25,8 @@
#import <AppKit/NSFont.h>
#import <AvailabilityMacros.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"
@@ -59,13 +61,13 @@ static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
const void* descriptors[] = {last_resort.Get()};
RetainPtr<CFArrayRef> values_array(
kAdoptCF, CFArrayCreate(kCFAllocatorDefault, descriptors,
- arraysize(descriptors), &kCFTypeArrayCallBacks));
+ base::size(descriptors), &kCFTypeArrayCallBacks));
const void* keys[] = {kCTFontCascadeListAttribute};
const void* values[] = {values_array.Get()};
RetainPtr<CFDictionaryRef> attributes(
kAdoptCF,
- CFDictionaryCreate(kCFAllocatorDefault, keys, values, arraysize(keys),
+ CFDictionaryCreate(kCFAllocatorDefault, keys, values, base::size(keys),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
@@ -112,58 +114,6 @@ static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
return return_font;
}
-void FontPlatformData::SetupSkPaint(SkPaint* paint,
- float,
- const Font* font) const {
- bool should_smooth_fonts = true;
- bool should_antialias = true;
- bool should_subpixel_position = true;
-
- if (font) {
- switch (font->GetFontDescription().FontSmoothing()) {
- case kAntialiased:
- should_smooth_fonts = false;
- break;
- case kSubpixelAntialiased:
- break;
- case kNoSmoothing:
- should_antialias = false;
- should_smooth_fonts = false;
- break;
- case kAutoSmoothing:
- // For the AutoSmooth case, don't do anything! Keep the default
- // settings.
- break;
- }
- }
-
- if (WebTestSupport::IsRunningWebTest()) {
- should_smooth_fonts = false;
- should_antialias =
- should_antialias && WebTestSupport::IsFontAntialiasingEnabledForTest();
- should_subpixel_position =
- WebTestSupport::IsTextSubpixelPositioningAllowedForTest();
- }
-
- paint->setAntiAlias(should_antialias);
- paint->setEmbeddedBitmapText(false);
- const float ts = text_size_ >= 0 ? text_size_ : 12;
- paint->setTextSize(SkFloatToScalar(ts));
- paint->setTypeface(typeface_);
- paint->setFakeBoldText(synthetic_bold_);
- paint->setTextSkewX(synthetic_italic_ ? -SK_Scalar1 / 4 : 0);
- paint->setLCDRenderText(should_smooth_fonts);
- paint->setSubpixelText(should_subpixel_position);
-
- // When rendering using CoreGraphics, disable hinting when
- // webkit-font-smoothing:antialiased or text-rendering:geometricPrecision is
- // used. See crbug.com/152304
- if (font &&
- (font->GetFontDescription().FontSmoothing() == kAntialiased ||
- font->GetFontDescription().TextRendering() == kGeometricPrecision))
- paint->setHinting(SkFontHinting::kNone);
-}
-
void FontPlatformData::SetupSkFont(SkFont* skfont,
float,
const Font* font) const {
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 3365749c759..4c18c37138f 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
@@ -4,13 +4,43 @@
#include "third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h"
+#include <hb-aat.h>
+#include <hb.h>
+
namespace blink {
+namespace {
+
+bool activationSelectorPresent(
+ hb_face_t* hb_face,
+ const hb_aat_layout_feature_type_t feature_type,
+ const hb_aat_layout_feature_selector_t enabled_selector_expectation) {
+ Vector<hb_aat_layout_feature_selector_info_t> feature_selectors;
+ unsigned num_feature_selectors = 0;
+ unsigned default_index = 0;
+ num_feature_selectors = hb_aat_layout_feature_type_get_selector_infos(
+ hb_face, feature_type, 0, nullptr, nullptr, nullptr);
+ feature_selectors.resize(num_feature_selectors);
+ if (!hb_aat_layout_feature_type_get_selector_infos(
+ hb_face, feature_type, 0, &num_feature_selectors,
+ feature_selectors.data(), &default_index)) {
+ return false;
+ }
+ for (hb_aat_layout_feature_selector_info_t selector_info :
+ feature_selectors) {
+ if (selector_info.enable == enabled_selector_expectation)
+ return true;
+ }
+ return false;
+}
+} // namespace
+
OpenTypeCapsSupport::OpenTypeCapsSupport()
: harfbuzz_face_(nullptr),
requested_caps_(FontDescription::kCapsNormal),
font_support_(FontSupport::kFull),
- caps_synthesis_(CapsSynthesis::kNone) {}
+ caps_synthesis_(CapsSynthesis::kNone),
+ font_format_(FontFormat::kUndetermined) {}
OpenTypeCapsSupport::OpenTypeCapsSupport(
const HarfBuzzFace* harfbuzz_face,
@@ -19,7 +49,8 @@ OpenTypeCapsSupport::OpenTypeCapsSupport(
: harfbuzz_face_(harfbuzz_face),
requested_caps_(requested_caps),
font_support_(FontSupport::kFull),
- caps_synthesis_(CapsSynthesis::kNone) {
+ caps_synthesis_(CapsSynthesis::kNone),
+ font_format_(FontFormat::kUndetermined) {
if (requested_caps != FontDescription::kCapsNormal)
DetermineFontSupport(script);
}
@@ -102,24 +133,114 @@ CaseMapIntend OpenTypeCapsSupport::NeedsCaseChange(
return case_map_intend;
}
+OpenTypeCapsSupport::FontFormat OpenTypeCapsSupport::GetFontFormat() const {
+ if (font_format_ == FontFormat::kUndetermined) {
+ 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);
+
+ // 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
+ // exposed in HarfBuzz.
+ bool has_morx_or_mort = hb_blob_get_length(morx_blob.get()) ||
+ hb_blob_get_length(mort_blob.get());
+ bool has_gsub = hb_ot_layout_has_substitution(hb_face);
+ font_format_ = has_morx_or_mort&& !has_gsub
+ ? font_format_ = FontFormat::kAat
+ : font_format_ = FontFormat::kOpenType;
+ }
+ return font_format_;
+}
+
+bool OpenTypeCapsSupport::SupportsFeature(hb_script_t script,
+ uint32_t tag) const {
+ if (GetFontFormat() == FontFormat::kAat)
+ return SupportsAatFeature(tag);
+ return SupportsOpenTypeFeature(script, tag);
+}
+
+bool OpenTypeCapsSupport::SupportsAatFeature(uint32_t tag) const {
+ // We only want to detect small-caps and capitals-to-small-capitals features
+ // for aat-fonts, any other requests are returned as not supported.
+ if (tag != HB_TAG('s', 'm', 'c', 'p') && tag != HB_TAG('c', '2', 's', 'c')) {
+ return false;
+ }
+
+ hb_face_t* hb_face = hb_font_get_face(
+ harfbuzz_face_->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout));
+
+ Vector<hb_aat_layout_feature_type_t> aat_features;
+ unsigned feature_count =
+ hb_aat_layout_get_feature_types(hb_face, 0, nullptr, nullptr);
+ aat_features.resize(feature_count);
+ if (!hb_aat_layout_get_feature_types(hb_face, 0, &feature_count,
+ aat_features.data()))
+ return false;
+
+ if (tag == HB_TAG('s', 'm', 'c', 'p')) {
+ // Check for presence of new style (feature id 38) or old style (letter
+ // case, feature id 3) small caps feature presence, then check for the
+ // specific required activation selectors.
+ if (!aat_features.Contains(HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE) &&
+ !aat_features.Contains(HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE))
+ return false;
+
+ // Check for new style small caps, feature id 38.
+ if (aat_features.Contains(HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE)) {
+ if (activationSelectorPresent(
+ hb_face, HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE,
+ HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS))
+ return true;
+ }
+
+ // Check for old style small caps enabling selector, feature id 3.
+ if (aat_features.Contains(HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE)) {
+ if (activationSelectorPresent(hb_face,
+ HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE,
+ HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS))
+ return true;
+ }
+
+ // Neither old or new style small caps present.
+ return false;
+ }
+
+ if (tag == HB_TAG('c', '2', 's', 'c')) {
+ if (!aat_features.Contains(HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE))
+ return false;
+
+ return activationSelectorPresent(
+ hb_face, HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE,
+ HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS);
+ }
+
+ return false;
+}
+
void OpenTypeCapsSupport::DetermineFontSupport(hb_script_t script) {
switch (requested_caps_) {
case FontDescription::kSmallCaps:
- if (!SupportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p'))) {
+ if (!SupportsFeature(script, HB_TAG('s', 'm', 'c', 'p'))) {
font_support_ = FontSupport::kNone;
caps_synthesis_ = CapsSynthesis::kLowerToSmallCaps;
}
break;
case FontDescription::kAllSmallCaps:
- if (!(SupportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p')) &&
- SupportsOpenTypeFeature(script, HB_TAG('c', '2', 's', 'c')))) {
+ if (!(SupportsFeature(script, HB_TAG('s', 'm', 'c', 'p')) &&
+ SupportsFeature(script, HB_TAG('c', '2', 's', 'c')))) {
font_support_ = FontSupport::kNone;
caps_synthesis_ = CapsSynthesis::kBothToSmallCaps;
}
break;
case FontDescription::kPetiteCaps:
- if (!SupportsOpenTypeFeature(script, HB_TAG('p', 'c', 'a', 'p'))) {
- if (SupportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p'))) {
+ if (!SupportsFeature(script, HB_TAG('p', 'c', 'a', 'p'))) {
+ if (SupportsFeature(script, HB_TAG('s', 'm', 'c', 'p'))) {
font_support_ = FontSupport::kFallback;
} else {
font_support_ = FontSupport::kNone;
@@ -128,10 +249,10 @@ void OpenTypeCapsSupport::DetermineFontSupport(hb_script_t script) {
}
break;
case FontDescription::kAllPetiteCaps:
- if (!(SupportsOpenTypeFeature(script, HB_TAG('p', 'c', 'a', 'p')) &&
- SupportsOpenTypeFeature(script, HB_TAG('c', '2', 'p', 'c')))) {
- if (SupportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p')) &&
- SupportsOpenTypeFeature(script, HB_TAG('c', '2', 's', 'c'))) {
+ if (!(SupportsFeature(script, HB_TAG('p', 'c', 'a', 'p')) &&
+ SupportsFeature(script, HB_TAG('c', '2', 'p', 'c')))) {
+ if (SupportsFeature(script, HB_TAG('s', 'm', 'c', 'p')) &&
+ SupportsFeature(script, HB_TAG('c', '2', 's', 'c'))) {
font_support_ = FontSupport::kFallback;
} else {
font_support_ = FontSupport::kNone;
@@ -140,9 +261,9 @@ void OpenTypeCapsSupport::DetermineFontSupport(hb_script_t script) {
}
break;
case FontDescription::kUnicase:
- if (!SupportsOpenTypeFeature(script, HB_TAG('u', 'n', 'i', 'c'))) {
+ if (!SupportsFeature(script, HB_TAG('u', 'n', 'i', 'c'))) {
caps_synthesis_ = CapsSynthesis::kUpperToSmallCaps;
- if (SupportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p'))) {
+ if (SupportsFeature(script, HB_TAG('s', 'm', 'c', 'p'))) {
font_support_ = FontSupport::kFallback;
} else {
font_support_ = FontSupport::kNone;
@@ -150,7 +271,7 @@ void OpenTypeCapsSupport::DetermineFontSupport(hb_script_t script) {
}
break;
case FontDescription::kTitlingCaps:
- if (!SupportsOpenTypeFeature(script, HB_TAG('t', 'i', 't', 'l'))) {
+ if (!SupportsFeature(script, HB_TAG('t', 'i', 't', 'l'))) {
font_support_ = FontSupport::kNone;
}
break;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h
index 841e465c8a1..4f53191116f 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h
@@ -29,7 +29,13 @@ class PLATFORM_EXPORT OpenTypeCapsSupport {
CaseMapIntend NeedsCaseChange(SmallCapsIterator::SmallCapsBehavior run_case);
private:
+ enum class FontFormat { kUndetermined, kOpenType, kAat };
+ // Lazily intializes font_format_ when needed and returns the format of the
+ // underlying HarfBuzzFace/Font.
+ FontFormat GetFontFormat() const;
void DetermineFontSupport(hb_script_t);
+ bool SupportsFeature(hb_script_t, uint32_t tag) const;
+ bool SupportsAatFeature(uint32_t tag) const;
bool SupportsOpenTypeFeature(hb_script_t, uint32_t tag) const;
const HarfBuzzFace* harfbuzz_face_;
@@ -50,6 +56,7 @@ class PLATFORM_EXPORT OpenTypeCapsSupport {
FontSupport font_support_;
CapsSynthesis caps_synthesis_;
+ mutable FontFormat font_format_;
};
}; // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support_test.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support_test.cc
new file mode 100644
index 00000000000..f0097556ae1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support_test.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2018 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_caps_support.h"
+
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/fonts/font_description.h"
+#include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
+
+#include "third_party/skia/include/core/SkRefCnt.h"
+#include "third_party/skia/include/core/SkTypeface.h"
+
+#if defined(OS_MACOSX)
+#include "base/mac/mac_util.h"
+#endif
+
+namespace blink {
+
+void ensureHasNativeSmallCaps(const std::string& font_family_name) {
+ sk_sp<SkTypeface> test_typeface =
+ SkTypeface::MakeFromName(font_family_name.c_str(), SkFontStyle());
+ FontPlatformData font_platform_data(test_typeface, font_family_name.c_str(),
+ 16, false, false);
+ ASSERT_EQ(font_platform_data.FontFamilyName(), font_family_name.c_str());
+
+ OpenTypeCapsSupport caps_support(font_platform_data.GetHarfBuzzFace(),
+ FontDescription::FontVariantCaps::kSmallCaps,
+ HB_SCRIPT_LATIN);
+ // If caps_support.NeedsRunCaseSplitting() is true, this means that synthetic
+ // upper-casing / lower-casing is required and the run needs to be segmented
+ // by upper-case, lower-case properties. If it is false, it means that the
+ // font feature can be used and no synthetic case-changing is needed.
+ ASSERT_FALSE(caps_support.NeedsRunCaseSplitting());
+}
+
+// The AAT fonts for testing are only available on Mac OS X 10.13.
+#if defined(OS_MACOSX)
+#define MAYBE_SmallCapsForSFNSText SmallCapsForSFNSText
+#else
+#define MAYBE_SmallCapsForSFNSText DISABLED_SmallCapsForSFNSText
+#endif
+TEST(OpenTypeCapsSupportTest, MAYBE_SmallCapsForSFNSText) {
+#if defined(OS_MACOSX)
+ if (!base::mac::IsAtLeastOS10_13())
+ return;
+#endif
+ std::vector<std::string> test_fonts = {
+ ".SF NS Text", // has OpenType small-caps
+ "Apple Chancery", // has old-style (feature id 3,"Letter Case")
+ // small-caps
+ "Baskerville"}; // has new-style (feature id 38, "Upper Case")
+ // small-case.
+ for (auto& test_font : test_fonts)
+ ensureHasNativeSmallCaps(test_font);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc
index 012238f1901..cf3bf20955d 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc
@@ -168,7 +168,7 @@ ScriptRunIterator::ScriptRunIterator(const UChar* text,
ScriptRunIterator::ScriptRunIterator(const UChar* text, wtf_size_t length)
: ScriptRunIterator(text, length, ICUScriptData::Instance()) {}
-bool ScriptRunIterator::Consume(unsigned& limit, UScriptCode& script) {
+bool ScriptRunIterator::Consume(unsigned* limit, UScriptCode* script) {
if (current_set_.IsEmpty()) {
return false;
}
@@ -188,16 +188,16 @@ bool ScriptRunIterator::Consume(unsigned& limit, UScriptCode& script) {
break;
}
if (!MergeSets()) {
- limit = pos;
- script = ResolveCurrentScript();
- FixupStack(script);
+ *limit = pos;
+ *script = ResolveCurrentScript();
+ FixupStack(*script);
current_set_ = *next_set_;
return true;
}
}
- limit = length_;
- script = ResolveCurrentScript();
+ *limit = length_;
+ *script = ResolveCurrentScript();
current_set_.clear();
return true;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.h b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.h
index 6f3f16aead4..39d23e3b64f 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.h
@@ -31,7 +31,7 @@ class PLATFORM_EXPORT ScriptRunIterator {
// the process.
ScriptRunIterator(const UChar* text, wtf_size_t length, const ScriptData*);
- bool Consume(unsigned& limit, UScriptCode&);
+ bool Consume(unsigned* limit, UScriptCode*);
static constexpr int kMaxScriptCount = 20;
using UScriptCodeList = Vector<UScriptCode, kMaxScriptCount>;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc
index a792bdfb5c8..0432f686457 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc
@@ -316,7 +316,7 @@ class ScriptRunIteratorTest : public testing::Test {
unsigned limit;
UScriptCode code;
unsigned long run_count = 0;
- while (script_run_iterator->Consume(limit, code)) {
+ while (script_run_iterator->Consume(&limit, &code)) {
ASSERT_LT(run_count, expect.size());
ASSERT_EQ(expect[run_count].limit, limit);
ASSERT_EQ(expect[run_count].code, code);
@@ -331,7 +331,7 @@ TEST_F(ScriptRunIteratorTest, Empty) {
ScriptRunIterator script_run_iterator(empty.Characters16(), empty.length());
unsigned limit = 0;
UScriptCode code = USCRIPT_INVALID_CODE;
- DCHECK(!script_run_iterator.Consume(limit, code));
+ DCHECK(!script_run_iterator.Consume(&limit, &code));
ASSERT_EQ(limit, 0u);
ASSERT_EQ(code, USCRIPT_INVALID_CODE);
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
index 3cef0162ce7..6e239ed1d33 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
@@ -553,7 +553,7 @@ void SplitUntilNextCaseChange(
}
}
-hb_feature_t CreateFeature(hb_tag_t tag, uint32_t value = 0) {
+constexpr hb_feature_t CreateFeature(hb_tag_t tag, uint32_t value = 0) {
return {tag, value, 0 /* start */, static_cast<unsigned>(-1) /* end */};
}
@@ -562,11 +562,11 @@ hb_feature_t CreateFeature(hb_tag_t tag, uint32_t value = 0) {
void SetFontFeatures(const Font* font, FeaturesVector* features) {
const FontDescription& description = font->GetFontDescription();
- static hb_feature_t no_kern = CreateFeature(HB_TAG('k', 'e', 'r', 'n'));
- static hb_feature_t no_vkrn = CreateFeature(HB_TAG('v', 'k', 'r', 'n'));
+ constexpr hb_feature_t no_kern = CreateFeature(HB_TAG('k', 'e', 'r', 'n'));
+ constexpr hb_feature_t no_vkrn = CreateFeature(HB_TAG('v', 'k', 'r', 'n'));
switch (description.GetKerning()) {
case FontDescription::kNormalKerning:
- // kern/vkrn are enabled by default
+ // kern/vkrn are enabled by default in HarfBuzz
break;
case FontDescription::kNoneKerning:
features->push_back(description.IsVerticalAnyUpright() ? no_vkrn
@@ -576,51 +576,41 @@ void SetFontFeatures(const Font* font, FeaturesVector* features) {
break;
}
- static hb_feature_t no_clig = CreateFeature(HB_TAG('c', 'l', 'i', 'g'));
- static hb_feature_t no_liga = CreateFeature(HB_TAG('l', 'i', 'g', 'a'));
- switch (description.CommonLigaturesState()) {
- case FontDescription::kDisabledLigaturesState:
+ {
+ bool default_is_off = description.TextRendering() == blink::kOptimizeSpeed;
+ bool letter_spacing = description.LetterSpacing() != 0;
+ constexpr auto normal = FontDescription::kNormalLigaturesState;
+ constexpr auto enabled = FontDescription::kEnabledLigaturesState;
+ constexpr auto disabled = FontDescription::kDisabledLigaturesState;
+
+ // clig and liga are on by default in HarfBuzz
+ constexpr hb_feature_t no_clig = CreateFeature(HB_TAG('c', 'l', 'i', 'g'));
+ constexpr hb_feature_t no_liga = CreateFeature(HB_TAG('l', 'i', 'g', 'a'));
+ auto common = description.CommonLigaturesState();
+ if (letter_spacing ||
+ (common == disabled || (common == normal && default_is_off))) {
features->push_back(no_liga);
features->push_back(no_clig);
- break;
- case FontDescription::kEnabledLigaturesState:
- // liga and clig are on by default
- break;
- case FontDescription::kNormalLigaturesState:
- break;
- }
- static hb_feature_t dlig = CreateFeature(HB_TAG('d', 'l', 'i', 'g'), 1);
- switch (description.DiscretionaryLigaturesState()) {
- case FontDescription::kDisabledLigaturesState:
- // dlig is off by default
- break;
- case FontDescription::kEnabledLigaturesState:
+ }
+ // dlig is off by default in HarfBuzz
+ constexpr hb_feature_t dlig = CreateFeature(HB_TAG('d', 'l', 'i', 'g'), 1);
+ auto discretionary = description.DiscretionaryLigaturesState();
+ if (!letter_spacing && discretionary == enabled) {
features->push_back(dlig);
- break;
- case FontDescription::kNormalLigaturesState:
- break;
- }
- static hb_feature_t hlig = CreateFeature(HB_TAG('h', 'l', 'i', 'g'), 1);
- switch (description.HistoricalLigaturesState()) {
- case FontDescription::kDisabledLigaturesState:
- // hlig is off by default
- break;
- case FontDescription::kEnabledLigaturesState:
+ }
+ // hlig is off by default in HarfBuzz
+ constexpr hb_feature_t hlig = CreateFeature(HB_TAG('h', 'l', 'i', 'g'), 1);
+ auto historical = description.HistoricalLigaturesState();
+ if (!letter_spacing && historical == enabled) {
features->push_back(hlig);
- break;
- case FontDescription::kNormalLigaturesState:
- break;
- }
- static hb_feature_t no_calt = CreateFeature(HB_TAG('c', 'a', 'l', 't'));
- switch (description.ContextualLigaturesState()) {
- case FontDescription::kDisabledLigaturesState:
+ }
+ // calt is on by default in HarfBuzz
+ constexpr hb_feature_t no_calt = CreateFeature(HB_TAG('c', 'a', 'l', 't'));
+ auto contextual = description.ContextualLigaturesState();
+ if (letter_spacing ||
+ (contextual == disabled || (contextual == normal && default_is_off))) {
features->push_back(no_calt);
- break;
- case FontDescription::kEnabledLigaturesState:
- // calt is on by default
- break;
- case FontDescription::kNormalLigaturesState:
- break;
+ }
}
static hb_feature_t hwid = CreateFeature(HB_TAG('h', 'w', 'i', 'd'), 1);
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 35e0d66e541..8767c55f3cc 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
@@ -114,7 +114,7 @@ class HarfBuzzShaperTest : public testing::Test {
class ScopedSubpixelOverride {
public:
ScopedSubpixelOverride(bool b) {
- prev_layout_test_ = WebTestSupport::IsRunningWebTest();
+ prev_web_test_ = WebTestSupport::IsRunningWebTest();
prev_subpixel_allowed_ =
WebTestSupport::IsTextSubpixelPositioningAllowedForTest();
prev_antialias_ = WebTestSupport::IsFontAntialiasingEnabledForTest();
@@ -147,7 +147,7 @@ class ScopedSubpixelOverride {
WebTestSupport::SetFontAntialiasingEnabledForTest(prev_antialias_);
WebTestSupport::SetTextSubpixelPositioningAllowedForTest(
prev_subpixel_allowed_);
- WebTestSupport::SetIsRunningWebTest(prev_layout_test_);
+ WebTestSupport::SetIsRunningWebTest(prev_web_test_);
// Fonts cached with a different subpixel positioning state are not
// automatically invalidated and need to be cleared between test
@@ -156,7 +156,7 @@ class ScopedSubpixelOverride {
}
private:
- bool prev_layout_test_;
+ bool prev_web_test_;
bool prev_subpixel_allowed_;
bool prev_antialias_;
bool prev_fd_subpixel_;
@@ -1232,13 +1232,13 @@ TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeIntoArabicThaiHanLatin) {
composite_result->SnappedStartPositionForOffset(8));
}
-TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeAcrossRuns) {
+TEST_P(ShapeParameterTest, ShapeResultCopyRangeAcrossRuns) {
// Create 3 runs:
// [0]: 1 character.
// [1]: 5 characters.
// [2]: 2 character.
String mixed_string(u"\u65E5Hello\u65E5\u65E5");
- TextDirection direction = TextDirection::kLtr;
+ TextDirection direction = GetParam();
HarfBuzzShaper shaper(mixed_string);
scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction);
@@ -1251,6 +1251,23 @@ TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeAcrossRuns) {
EXPECT_EQ(2u, target->NumCharacters());
}
+TEST_P(ShapeParameterTest, ShapeResultCopyRangeContextMultiRuns) {
+ // Create 2 runs:
+ // [0]: 5 characters.
+ // [1]: 4 character.
+ String mixed_string(u"Hello\u65E5\u65E5\u65E5\u65E5");
+ TextDirection direction = GetParam();
+ HarfBuzzShaper shaper(mixed_string);
+ scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction);
+
+ // Copy multiple times using |context| from multiple runs
+ unsigned context = 0;
+ scoped_refptr<ShapeResult> sub2to4 = result->SubRange(2, 4, &context);
+ EXPECT_EQ(2u, sub2to4->NumCharacters());
+ scoped_refptr<ShapeResult> sub5to9 = result->SubRange(5, 9, &context);
+ EXPECT_EQ(4u, sub5to9->NumCharacters());
+}
+
TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeSegmentGlyphBoundingBox) {
String string(u"THello worldL");
TextDirection direction = TextDirection::kLtr;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc
index b6c634c08be..910b4ba8516 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h"
+#include <algorithm>
#include <memory>
#include "third_party/blink/renderer/platform/fonts/script_run_iterator.h"
@@ -37,38 +38,14 @@ RunSegmenter::RunSegmenter(const UChar* buffer,
symbols_iterator_position_(0),
at_end_(!buffer_size_) {}
-void RunSegmenter::ConsumeScriptIteratorPastLastSplit() {
- DCHECK(script_run_iterator_);
- if (script_run_iterator_position_ <= last_split_ &&
- script_run_iterator_position_ < buffer_size_) {
- while (script_run_iterator_->Consume(script_run_iterator_position_,
- candidate_range_.script)) {
- if (script_run_iterator_position_ > last_split_)
- return;
- }
- }
-}
-
-void RunSegmenter::ConsumeOrientationIteratorPastLastSplit() {
- if (orientation_iterator_ && orientation_iterator_position_ <= last_split_ &&
- orientation_iterator_position_ < buffer_size_) {
- while (
- orientation_iterator_->Consume(&orientation_iterator_position_,
- &candidate_range_.render_orientation)) {
- if (orientation_iterator_position_ > last_split_)
- return;
- }
- }
-}
-
-void RunSegmenter::ConsumeSymbolsIteratorPastLastSplit() {
- DCHECK(symbols_iterator_);
- if (symbols_iterator_position_ <= last_split_ &&
- symbols_iterator_position_ < buffer_size_) {
- while (
- symbols_iterator_->Consume(&symbols_iterator_position_,
- &candidate_range_.font_fallback_priority)) {
- if (symbols_iterator_position_ > last_split_)
+template <class Iterator, typename SegmentationCategory>
+void RunSegmenter::ConsumeIteratorPastLastSplit(
+ std::unique_ptr<Iterator>& iterator,
+ unsigned* iterator_position,
+ SegmentationCategory* segmentation_category) {
+ if (*iterator_position <= last_split_ && *iterator_position < buffer_size_) {
+ while (iterator->Consume(iterator_position, segmentation_category)) {
+ if (*iterator_position > last_split_)
return;
}
}
@@ -80,24 +57,20 @@ bool RunSegmenter::Consume(RunSegmenterRange* next_range) {
if (at_end_)
return false;
- ConsumeScriptIteratorPastLastSplit();
- ConsumeOrientationIteratorPastLastSplit();
- ConsumeSymbolsIteratorPastLastSplit();
+ ConsumeIteratorPastLastSplit(script_run_iterator_,
+ &script_run_iterator_position_,
+ &candidate_range_.script);
+ ConsumeIteratorPastLastSplit(orientation_iterator_,
+ &orientation_iterator_position_,
+ &candidate_range_.render_orientation);
+ ConsumeIteratorPastLastSplit(symbols_iterator_, &symbols_iterator_position_,
+ &candidate_range_.font_fallback_priority);
- if (script_run_iterator_position_ <= orientation_iterator_position_ &&
- script_run_iterator_position_ <= symbols_iterator_position_) {
- last_split_ = script_run_iterator_position_;
- }
+ unsigned positions[] = {script_run_iterator_position_,
+ orientation_iterator_position_,
+ symbols_iterator_position_};
- if (orientation_iterator_position_ <= script_run_iterator_position_ &&
- orientation_iterator_position_ <= symbols_iterator_position_) {
- last_split_ = orientation_iterator_position_;
- }
-
- if (symbols_iterator_position_ <= script_run_iterator_position_ &&
- symbols_iterator_position_ <= orientation_iterator_position_) {
- last_split_ = symbols_iterator_position_;
- }
+ last_split_ = *std::min_element(std::begin(positions), std::end(positions));
candidate_range_.start = candidate_range_.end;
candidate_range_.end = last_split_;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h
index 86bfc774f28..84647cae75b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h
@@ -47,9 +47,11 @@ class PLATFORM_EXPORT RunSegmenter {
}
private:
- void ConsumeOrientationIteratorPastLastSplit();
- void ConsumeScriptIteratorPastLastSplit();
- void ConsumeSymbolsIteratorPastLastSplit();
+ template <class Iterator, typename SegmentationCategory>
+ void ConsumeIteratorPastLastSplit(
+ std::unique_ptr<Iterator>& iterator,
+ unsigned* iterator_position,
+ SegmentationCategory* segmentation_category);
unsigned buffer_size_;
RunSegmenterRange candidate_range_;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.cc
index 664b1fcf3fa..ccf3942cc92 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.cc
@@ -39,7 +39,8 @@ namespace blink {
void ShapeCache::SmallStringKey::HashString() {
// TODO(cavalcanti): next add xxhash.
#if defined(USE_FUNCTION_CITYHASH)
- hash_ = CityHash64((const char*)characters_, length_ * sizeof(UChar));
+ hash_ = static_cast<unsigned>(
+ CityHash64((const char*)characters_, length_ * sizeof(UChar)));
#endif
}
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 11ca1595552..42a823029a7 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
@@ -122,13 +122,14 @@ unsigned ShapeResult::RunInfo::NumGraphemes(unsigned start,
unsigned end) const {
if (graphemes_.size() == 0 || start >= num_characters_)
return 0;
- DCHECK_LT(start, end);
- DCHECK_LE(end, num_characters_);
+ CHECK_LT(start, end);
+ CHECK_LE(end, num_characters_);
+ CHECK_EQ(num_characters_, graphemes_.size());
return graphemes_[end - 1] - graphemes_[start] + 1;
}
void ShapeResult::EnsureGraphemes(const StringView& text) const {
- DCHECK_EQ(NumCharacters(), text.length());
+ CHECK_EQ(NumCharacters(), text.length());
// Hit-testing, canvas, etc. may still call this function for 0-length text,
// or glyphs may be missing at all.
@@ -144,7 +145,7 @@ void ShapeResult::EnsureGraphemes(const StringView& text) const {
return;
unsigned result_start_index = StartIndex();
- for (const auto& run : runs_) {
+ for (const scoped_refptr<RunInfo>& run : runs_) {
if (!run)
continue;
DCHECK_GE(run->start_index_, result_start_index);
@@ -289,7 +290,6 @@ void ShapeResult::RunInfo::CharacterIndexForXPosition(
BreakGlyphsOption break_glyphs_option,
GlyphIndexResult* result) const {
DCHECK(target_x >= 0 && target_x <= width_);
- const unsigned num_glyphs = glyph_data_.size();
result->origin_x = 0;
unsigned glyph_sequence_start = 0;
@@ -301,12 +301,12 @@ void ShapeResult::RunInfo::CharacterIndexForXPosition(
glyph_sequence_start = glyph_sequence_end = num_characters_;
}
- for (unsigned i = 0; i < num_glyphs; ++i) {
- unsigned current_glyph_char_index = glyph_data_[i].character_index;
+ for (const HarfBuzzRunGlyphData& glyph_data : glyph_data_) {
+ unsigned current_glyph_char_index = glyph_data.character_index;
// If the glyph is part of the same sequence, we just accumulate the
// advance.
if (glyph_sequence_start == current_glyph_char_index) {
- result->advance += glyph_data_[i].advance;
+ result->advance += glyph_data.advance;
continue;
}
@@ -328,7 +328,7 @@ void ShapeResult::RunInfo::CharacterIndexForXPosition(
}
glyph_sequence_start = current_glyph_char_index;
result->origin_x += result->advance;
- result->advance = glyph_data_[i].advance;
+ result->advance = glyph_data.advance;
}
// At this point, we have [glyph_sequence_start, glyph_sequence_end)
@@ -512,19 +512,18 @@ void ShapeResult::OffsetForPosition(float target_x,
unsigned characters_so_far = Rtl() ? NumCharacters() : 0;
float current_x = 0;
- for (unsigned i = 0; i < runs_.size(); ++i) {
- const RunInfo* run = runs_[i].get();
+ for (const scoped_refptr<RunInfo>& run_ptr : runs_) {
+ const RunInfo* run = run_ptr.get();
if (!run)
continue;
if (Rtl())
- characters_so_far -= runs_[i]->num_characters_;
+ characters_so_far -= run->num_characters_;
float next_x = current_x + run->width_;
float offset_for_run = target_x - current_x;
if (offset_for_run >= 0 && offset_for_run < run->width_) {
// The x value in question is within this script run.
run->CharacterIndexForXPosition(offset_for_run, break_glyphs_option,
result);
- result->run_index = i;
result->characters_on_left_runs = characters_so_far;
if (Rtl()) {
result->left_character_index =
@@ -555,7 +554,6 @@ void ShapeResult::OffsetForPosition(float target_x,
result->right_character_index += characters_so_far;
}
- result->run_index = runs_.size() - 1;
result->characters_on_left_runs = characters_so_far;
DCHECK_LE(result->left_character_index, NumCharacters());
@@ -971,38 +969,67 @@ unsigned ShapeResult::RunInfo::LimitNumGlyphs(
const bool is_ltr,
const hb_glyph_info_t* glyph_infos) {
unsigned num_glyphs = *num_glyphs_in_out;
+ CHECK_GT(num_glyphs, 0u);
// If there were larger character indexes than kMaxCharacterIndex, reduce
// num_glyphs so that all character indexes can fit to kMaxCharacterIndex.
// Because code points and glyphs are not always 1:1, we need to check the
// first and the last cluster.
+ const hb_glyph_info_t* left_glyph_info = &glyph_infos[start_glyph];
+ const hb_glyph_info_t* right_glyph_info = &left_glyph_info[num_glyphs - 1];
unsigned start_cluster;
if (is_ltr) {
- start_cluster = glyph_infos[start_glyph].cluster;
- unsigned last_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
- unsigned last_character_index = last_cluster - start_cluster;
- if (UNLIKELY(last_character_index >
- HarfBuzzRunGlyphData::kMaxCharacterIndex)) {
- // Make sure the end is a cluster boundary.
- do {
- num_glyphs--;
- num_characters_ = last_character_index;
- last_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
- last_character_index = last_cluster - start_cluster;
- } while (last_character_index > HarfBuzzRunGlyphData::kMaxCharacterIndex);
+ start_cluster = left_glyph_info->cluster;
+ unsigned last_cluster = right_glyph_info->cluster;
+ unsigned max_cluster =
+ start_cluster + HarfBuzzRunGlyphData::kMaxCharacterIndex;
+ if (UNLIKELY(last_cluster > max_cluster)) {
+ // Limit at |max_cluster| in LTR. If |max_cluster| is 100:
+ // 0 1 2 ... 98 99 99 101 101 103 ...
+ // ^ limit here.
+ // Find |glyph_info| where |cluster| <= |max_cluster|.
+ const hb_glyph_info_t* limit_glyph_info = std::upper_bound(
+ left_glyph_info, right_glyph_info + 1, max_cluster,
+ [](unsigned cluster, const hb_glyph_info_t& glyph_info) {
+ return cluster < glyph_info.cluster;
+ });
+ --limit_glyph_info;
+ CHECK_GT(limit_glyph_info, left_glyph_info);
+ CHECK_LT(limit_glyph_info, right_glyph_info);
+ DCHECK_LE(limit_glyph_info->cluster, max_cluster);
+ // Adjust |right_glyph_info| and recompute dependent variables.
+ right_glyph_info = limit_glyph_info;
+ num_glyphs = right_glyph_info - left_glyph_info + 1;
+ num_characters_ = right_glyph_info[1].cluster - start_cluster;
}
} else {
- start_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
- const unsigned last_cluster = glyph_infos[start_glyph].cluster;
- unsigned last_character_index = last_cluster - start_cluster;
- if (UNLIKELY(last_character_index >
- HarfBuzzRunGlyphData::kMaxCharacterIndex)) {
- do {
- num_glyphs--;
- num_characters_ = last_character_index;
- start_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
- last_character_index = last_cluster - start_cluster;
- } while (last_character_index > HarfBuzzRunGlyphData::kMaxCharacterIndex);
+ start_cluster = right_glyph_info->cluster;
+ unsigned last_cluster = left_glyph_info->cluster;
+ unsigned max_cluster =
+ start_cluster + HarfBuzzRunGlyphData::kMaxCharacterIndex;
+ if (UNLIKELY(last_cluster > max_cluster)) {
+ // Limit the right edge, which is in the reverse order in RTL.
+ // If |min_cluster| is 3:
+ // 103 102 ... 4 4 2 2 ...
+ // ^ limit here.
+ // Find |glyph_info| where |cluster| >= |min_cluster|.
+ unsigned min_cluster =
+ last_cluster - HarfBuzzRunGlyphData::kMaxCharacterIndex;
+ DCHECK_LT(start_cluster, min_cluster);
+ const hb_glyph_info_t* limit_glyph_info = std::upper_bound(
+ left_glyph_info, right_glyph_info + 1, min_cluster,
+ [](unsigned cluster, const hb_glyph_info_t& glyph_info) {
+ return cluster > glyph_info.cluster;
+ });
+ --limit_glyph_info;
+ CHECK_GT(limit_glyph_info, left_glyph_info);
+ CHECK_LT(limit_glyph_info, right_glyph_info);
+ DCHECK_GE(limit_glyph_info->cluster, min_cluster);
+ // Adjust |right_glyph_info| and recompute dependent variables.
+ right_glyph_info = limit_glyph_info;
+ start_cluster = right_glyph_info->cluster;
+ num_glyphs = right_glyph_info - left_glyph_info + 1;
+ num_characters_ = last_cluster - right_glyph_info[1].cluster;
}
}
@@ -1331,7 +1358,9 @@ void ShapeResult::CopyRange(unsigned start_offset,
// No need to process runs after the end of the range.
if ((!Rtl() && end_offset <= run_end) ||
(Rtl() && start_offset > run_start)) {
- if (start_run_index)
+ // RTL cannot use |start_run_index| because runs are in the descending
+ // order.
+ if (!Rtl() && start_run_index)
*start_run_index = run_index;
break;
}
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 72e7d4ee9f9..05ff17be9dc 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
@@ -342,7 +342,6 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
STACK_ALLOCATED();
public:
- unsigned run_index = 0;
// The total number of characters of runs_[0..run_index - 1].
unsigned characters_on_left_runs = 0;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
index 22198066fef..d6864da1866 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
@@ -4,35 +4,24 @@
#include "third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h"
-#include "third_party/blink/renderer/platform/fonts/font.h"
-#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h"
-#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h"
#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
namespace blink {
ShapingLineBreaker::ShapingLineBreaker(
- const HarfBuzzShaper* shaper,
- const Font* font,
scoped_refptr<const ShapeResult> result,
const LazyLineBreakIterator* break_iterator,
- const RunSegmenter::RunSegmenterRange* pre_segmented,
- ShapeResultSpacing<String>* spacing,
- const Hyphenation* hyphenation)
- : shaper_(shaper),
- font_(font),
+ const Hyphenation* hyphenation,
+ ShapeCallback shape_callback,
+ void* shape_callback_context)
+ : shape_callback_(shape_callback),
+ shape_callback_context_(shape_callback_context),
result_(result),
- pre_segmented_(pre_segmented),
break_iterator_(break_iterator),
- spacing_(spacing),
hyphenation_(hyphenation),
is_soft_hyphen_enabled_(true) {
- // ShapeResultSpacing is stateful when it has expansions. We may use it in
- // arbitrary order that it cannot have expansions.
- DCHECK(!spacing_ || !spacing_->HasExpansion());
-
// Line breaking performance relies on high-performance x-position to
// character offset lookup. Ensure that the desired cache has been computed.
DCHECK(result_);
@@ -175,18 +164,6 @@ ShapingLineBreaker::BreakOpportunity ShapingLineBreaker::NextBreakOpportunity(
return {break_iterator_->NextBreakOpportunity(offset, len), false};
}
-inline scoped_refptr<ShapeResult> ShapingLineBreaker::Shape(TextDirection direction,
- unsigned start,
- unsigned end) {
- if (!spacing_ || !spacing_->HasSpacing())
- return shaper_->Shape(font_, direction, start, end, pre_segmented_);
-
- scoped_refptr<ShapeResult> result =
- shaper_->Shape(font_, direction, start, end, pre_segmented_);
- result->ApplySpacing(*spacing_);
- return result;
-}
-
// Shapes a line of text by finding a valid and appropriate break opportunity
// based on the shaping results for the entire paragraph. Re-shapes the start
// and end of the line as needed.
@@ -289,14 +266,14 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine(
// There is no safe-to-break, reshape the whole range.
result_out->break_offset = break_opportunity.offset;
return ShapeResultView::Create(
- Shape(direction, start, break_opportunity.offset).get());
+ Shape(start, break_opportunity.offset).get());
}
LayoutUnit original_width = FlipRtl(
SnapEnd(result_->CachedPositionForOffset(first_safe - range_start),
direction) -
start_position,
direction);
- line_start_result = Shape(direction, start, first_safe);
+ line_start_result = Shape(start, first_safe);
available_space += line_start_result->SnappedWidth() - original_width;
}
DCHECK_GE(first_safe, start);
@@ -320,12 +297,12 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine(
break;
DCHECK_LE(break_opportunity.offset, range_end);
if (is_overflow) {
- line_end_result = Shape(direction, last_safe, break_opportunity.offset);
+ line_end_result = Shape(last_safe, break_opportunity.offset);
break;
}
LayoutUnit safe_position = SnapStart(
result_->CachedPositionForOffset(last_safe - range_start), direction);
- line_end_result = Shape(direction, last_safe, break_opportunity.offset);
+ line_end_result = Shape(last_safe, break_opportunity.offset);
if (line_end_result->SnappedWidth() <=
FlipRtl(end_position - safe_position, direction))
break;
@@ -402,14 +379,13 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeToEnd(
return ShapeResultView::Create(result_.get(), start, range_end);
// If no safe-to-break offset is found in range, reshape the entire range.
- TextDirection direction = result_->Direction();
if (first_safe >= range_end) {
- scoped_refptr<ShapeResult> line_result = Shape(direction, start, range_end);
+ scoped_refptr<ShapeResult> line_result = Shape(start, range_end);
return ShapeResultView::Create(line_result.get());
}
// Otherwise reshape to |first_safe|, then copy the rest.
- scoped_refptr<ShapeResult> line_start = Shape(direction, start, first_safe);
+ scoped_refptr<ShapeResult> line_start = Shape(start, first_safe);
ShapeResultView::Segment segments[2] = {
{line_start.get(), 0, std::numeric_limits<unsigned>::max()},
{result_.get(), first_safe, range_end}};
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h
index 159cd3e4068..14ed982839e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h
@@ -13,15 +13,11 @@
namespace blink {
-class Font;
class ShapeResult;
class ShapeResultView;
-class HarfBuzzShaper;
class Hyphenation;
class LazyLineBreakIterator;
enum class LineBreakType;
-template <typename TextContainerType>
-class ShapeResultSpacing;
// Shapes a line of text by finding the ideal break position as indicated by the
// available space and the shape results for the entire paragraph. Once an ideal
@@ -37,18 +33,20 @@ class PLATFORM_EXPORT ShapingLineBreaker final {
STACK_ALLOCATED();
public:
- // Construct a ShapingLineBreaker.
+ // Callback function to reshape line edges.
//
- // When the ShapeResult is from a RunSegmenterRange, giving it can skip
- // running RunSegmenter for much better performance.
- ShapingLineBreaker(const HarfBuzzShaper*,
- const Font*,
- scoped_refptr<const ShapeResult>,
- const LazyLineBreakIterator*,
- const RunSegmenter::RunSegmenterRange* = nullptr,
- ShapeResultSpacing<String>* = nullptr,
- const Hyphenation* = nullptr);
- ~ShapingLineBreaker() = default;
+ // std::function is forbidden in Chromium and base::Callback is way too
+ // expensive so we resort to a good old function pointer instead.
+ using ShapeCallback = scoped_refptr<ShapeResult> (*)(void* context,
+ unsigned start,
+ unsigned end);
+
+ // Construct a ShapingLineBreaker.
+ ShapingLineBreaker(scoped_refptr<const ShapeResult> result,
+ const LazyLineBreakIterator* break_iterator,
+ const Hyphenation* hyphenation,
+ ShapeCallback shape_callback,
+ void* shape_callback_context);
// Represents details of the result of |ShapeLine()|.
struct Result {
@@ -116,20 +114,18 @@ class PLATFORM_EXPORT ShapingLineBreaker final {
unsigned word_end,
bool backwards) const;
- scoped_refptr<ShapeResult> Shape(TextDirection, unsigned start, unsigned end);
+ scoped_refptr<ShapeResult> Shape(unsigned start, unsigned end) {
+ return (*shape_callback_)(shape_callback_context_, start, end);
+ }
scoped_refptr<const ShapeResultView> ShapeToEnd(unsigned start,
unsigned first_safe,
unsigned range_start,
unsigned range_end);
- const HarfBuzzShaper* shaper_;
- const Font* font_;
+ const ShapeCallback shape_callback_;
+ void* shape_callback_context_;
scoped_refptr<const ShapeResult> result_;
- const RunSegmenter::RunSegmenterRange* pre_segmented_;
const LazyLineBreakIterator* break_iterator_;
- // TODO(kojii): ShapeResultSpacing is not const because it's stateful when it
- // has expansions. Split spacing and expansions to make this const.
- ShapeResultSpacing<String>* spacing_;
const Hyphenation* hyphenation_;
bool is_soft_hyphen_enabled_;
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 25ba3d14546..2e05f3302cc 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
@@ -20,6 +20,20 @@ namespace blink {
namespace {
+struct HarfBuzzShaperCallbackContext {
+ const HarfBuzzShaper* shaper;
+ const Font* font;
+ TextDirection direction;
+};
+
+scoped_refptr<ShapeResult> HarfBuzzShaperCallback(void* untyped_context,
+ unsigned start,
+ unsigned end) {
+ HarfBuzzShaperCallbackContext* context =
+ static_cast<HarfBuzzShaperCallbackContext*>(untyped_context);
+ return context->shaper->Shape(context->font, context->direction, start, end);
+}
+
scoped_refptr<const ShapeResultView> ShapeLine(ShapingLineBreaker* breaker,
unsigned start_offset,
LayoutUnit available_space,
@@ -109,7 +123,9 @@ TEST_F(ShapingLineBreakerTest, ShapeLineLatin) {
shaper.Shape(&font, direction, 0, 4);
ASSERT_LT(first1->SnappedWidth(), first2->SnappedWidth());
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
scoped_refptr<const ShapeResultView> line;
unsigned break_offset = 0;
@@ -168,7 +184,9 @@ TEST_F(ShapingLineBreakerTest, ShapeLineLatinMultiLine) {
scoped_refptr<const ShapeResult> mid_third =
shaper.Shape(&font, direction, 0, 16);
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
unsigned break_offset = 0;
ShapeLine(&breaker, 0, result->SnappedWidth() - 1, &break_offset);
@@ -195,7 +213,9 @@ TEST_F(ShapingLineBreakerTest, ShapeLineLatinBreakAll) {
scoped_refptr<const ShapeResult> midpoint =
shaper.Shape(&font, direction, 0, 16);
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
scoped_refptr<const ShapeResultView> line;
unsigned break_offset = 0;
@@ -216,7 +236,9 @@ TEST_F(ShapingLineBreakerTest, ShapeLineZeroAvailableWidth) {
HarfBuzzShaper shaper(string);
scoped_refptr<const ShapeResult> result = shaper.Shape(&font, direction);
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
scoped_refptr<const ShapeResultView> line;
unsigned break_offset = 0;
LayoutUnit zero(0);
@@ -259,7 +281,9 @@ TEST_F(ShapingLineBreakerTest, DISABLED_ShapeLineArabicThaiHanLatin) {
});
LayoutUnit longest_word_width = (*longest_word)->SnappedWidth();
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
scoped_refptr<const ShapeResult> line;
unsigned break_offset = 0;
@@ -288,7 +312,9 @@ TEST_F(ShapingLineBreakerTest, ShapeLineRangeEndMidWord) {
scoped_refptr<const ShapeResult> result =
shaper.Shape(&font, direction, 0, 2);
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
scoped_refptr<const ShapeResultView> line;
unsigned break_offset = 0;
@@ -325,7 +351,9 @@ TEST_P(BreakOpportunityTest, Next) {
scoped_refptr<const ShapeResult> result =
shaper.Shape(&font, TextDirection::kLtr);
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
EXPECT_THAT(BreakPositionsByNext(breaker, string),
testing::ElementsAreArray(data.break_positions));
@@ -345,7 +373,9 @@ TEST_P(BreakOpportunityTest, Previous) {
scoped_refptr<const ShapeResult> result =
shaper.Shape(&font, TextDirection::kLtr);
- ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator);
+ HarfBuzzShaperCallbackContext context{&shaper, &font, result->Direction()};
+ ShapingLineBreaker breaker(result, &break_iterator, nullptr,
+ HarfBuzzShaperCallback, &context);
EXPECT_THAT(BreakPositionsByPrevious(breaker, string),
testing::ElementsAreArray(data.break_positions));
diff --git a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc
index d742599579d..144c2272df3 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc
@@ -35,6 +35,7 @@
#include <memory>
#include <utility>
+#include "SkFontMetrics.h"
#include "SkPath.h"
#include "SkTypeface.h"
#include "SkTypes.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 90898dbc4a8..3eb56e5f013 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
@@ -43,7 +43,6 @@
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h"
#include "third_party/blink/renderer/platform/fonts/font_global_context.h"
-#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/fonts/skia/sktypeface_factory.h"
#include "third_party/blink/renderer/platform/language.h"
@@ -57,25 +56,6 @@
namespace blink {
-#if defined(OS_ANDROID) || defined(OS_LINUX)
-namespace {
-
-static sk_sp<SkTypeface> CreateTypefaceFromUniqueName(
- const FontFaceCreationParams& creation_params,
- CString& name) {
- FontUniqueNameLookup* unique_name_lookup =
- FontGlobalContext::Get()->GetFontUniqueNameLookup();
- DCHECK(unique_name_lookup);
- sk_sp<SkTypeface> uniquely_identified_font =
- unique_name_lookup->MatchUniqueName(creation_params.Family());
- if (uniquely_identified_font) {
- return uniquely_identified_font;
- }
- return nullptr;
-}
-} // namespace
-#endif
-
AtomicString ToAtomicString(const SkString& str) {
return AtomicString::FromUTF8(str.c_str(), str.size());
}
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 bc300449603..dad31d2a64d 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
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
#include "third_party/ots/include/ots-memory-stream.h"
#include "third_party/skia/include/core/SkStream.h"
@@ -209,7 +210,7 @@ sk_sp<SkTypeface> WebFontDecoder::Decode(SharedBuffer* buffer) {
return nullptr;
}
- const size_t decoded_length = output.Tell();
+ const size_t decoded_length = SafeCast<size_t>(output.Tell());
RecordDecodeSpeedHistogram(data, buffer->size(), CurrentTime() - start,
decoded_length);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/web_font_render_style.cc b/chromium/third_party/blink/renderer/platform/fonts/web_font_render_style.cc
index b63f8a2051d..e78ea8c04c4 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/web_font_render_style.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/web_font_render_style.cc
@@ -97,25 +97,6 @@ void WebFontRenderStyle::OverrideWith(const WebFontRenderStyle& other) {
use_subpixel_positioning = other.use_subpixel_positioning;
}
-void WebFontRenderStyle::ApplyToSkPaint(SkPaint& font,
- float device_scale_factor) const {
- auto sk_hint_style = static_cast<SkFontHinting>(hint_style);
- font.setAntiAlias(use_anti_alias);
- font.setHinting(sk_hint_style);
- font.setEmbeddedBitmapText(use_bitmaps);
- font.setAutohinted(use_auto_hint);
- if (use_anti_alias)
- font.setLCDRenderText(use_subpixel_rendering);
-
- // Force-enable subpixel positioning, except when full hinting is requested on
- // low-dpi screen or when running web tests.
- bool force_subpixel_positioning =
- !WebTestSupport::IsRunningWebTest() &&
- (sk_hint_style != SkFontHinting::kFull || device_scale_factor > 1.0f);
-
- font.setSubpixelText(force_subpixel_positioning || use_subpixel_positioning);
-}
-
void WebFontRenderStyle::ApplyToSkFont(SkFont* font,
float device_scale_factor) const {
auto sk_hint_style = static_cast<SkFontHinting>(hint_style);
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 b3e09a38bc1..99641e3d337 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
@@ -35,6 +35,7 @@
#include <utility>
#include "base/debug/alias.h"
+#include "base/stl_util.h"
#include "third_party/blink/renderer/platform/fonts/bitmap_glyphs_blacklist.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h"
@@ -42,9 +43,14 @@
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/fonts/win/font_fallback_win.h"
#include "third_party/blink/renderer/platform/language.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/skia/include/core/SkFontMgr.h"
+#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/ports/SkTypeface_win.h"
+#include <ft2build.h>
+#include <freetype/freetype.h>
+
namespace blink {
HashMap<String, sk_sp<SkTypeface>, CaseFoldingHash>*
@@ -67,6 +73,44 @@ int32_t EnsureMinimumFontHeightIfNeeded(int32_t font_height) {
return (font_height < 12.0f) && (GetACP() == 936) ? 12.0f : font_height;
}
+// Test-only code for matching sideloaded fonts by postscript name. This
+// implementation is incomplete, as it does not match the full font name and
+// only uses FT_Get_Postscript_Name, which returns an ASCII font name. This is
+// intended to pass tests on Windows, where for example src: local(Ahem) is used
+// in @font-face CSS declarations. Skia does not expose getAdvancedMetrics, so
+// we use FreeType here to parse the font's postscript name.
+sk_sp<SkTypeface> FindUniqueFontNameFromSideloadedFonts(
+ const String& font_name,
+ HashMap<String, sk_sp<SkTypeface>, CaseFoldingHash>* sideloaded_fonts) {
+ CHECK(sideloaded_fonts);
+ FT_Library library;
+ FT_Init_FreeType(&library);
+
+ sk_sp<SkTypeface> return_typeface(nullptr);
+ for (auto& sideloaded_font : sideloaded_fonts->Values()) {
+ // Open ttc index zero as we can assume that we do not sideload TrueType
+ // collections.
+ SkStreamAsset* typeface_stream = sideloaded_font->openStream(0);
+ CHECK(typeface_stream->getMemoryBase());
+ std::string font_family_name;
+ FT_Face font_face;
+ FT_Open_Args open_args = {
+ FT_OPEN_MEMORY,
+ reinterpret_cast<const FT_Byte*>(typeface_stream->getMemoryBase()),
+ typeface_stream->getLength()};
+ CHECK_EQ(FT_Err_Ok, FT_Open_Face(library, &open_args, 0, &font_face));
+ font_family_name = FT_Get_Postscript_Name(font_face);
+ FT_Done_Face(font_face);
+
+ if (font_name.FoldCase() == String(font_family_name.c_str()).FoldCase()) {
+ return_typeface = sideloaded_font;
+ break;
+ }
+ }
+ FT_Done_FreeType(library);
+ return return_typeface;
+}
+
} // namespace
// static
@@ -215,10 +259,10 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
int num_fonts = 0;
if (script == USCRIPT_HAN) {
pan_uni_fonts = kCjkFonts;
- num_fonts = arraysize(kCjkFonts);
+ num_fonts = base::size(kCjkFonts);
} else {
pan_uni_fonts = kCommonFonts;
- num_fonts = arraysize(kCommonFonts);
+ num_fonts = base::size(kCommonFonts);
}
// Font returned from getFallbackFamily may not cover |character|
// because it's based on script to font mapping. This problem is
@@ -294,7 +338,7 @@ static bool TypefacesHasWeightSuffix(const AtomicString& family,
{L" ultrabold", 10, FontSelectionValue(800)},
{L" black", 6, FontSelectionValue(900)},
{L" heavy", 6, FontSelectionValue(900)}};
- size_t num_variants = arraysize(kVariantForSuffix);
+ size_t num_variants = base::size(kVariantForSuffix);
for (size_t i = 0; i < num_variants; i++) {
const FamilyWeightSuffix& entry = kVariantForSuffix[i];
if (family.EndsWith(entry.suffix, kTextCaseUnicodeInsensitive)) {
@@ -331,7 +375,7 @@ static bool TypefacesHasStretchSuffix(const AtomicString& family,
{L" expanded", 9, ExpandedWidthValue()},
{L" extraexpanded", 14, ExtraExpandedWidthValue()},
{L" ultraexpanded", 14, UltraExpandedWidthValue()}};
- size_t num_variants = arraysize(kVariantForSuffix);
+ size_t num_variants = base::size(kVariantForSuffix);
for (size_t i = 0; i < num_variants; i++) {
const FamilyStretchSuffix& entry = kVariantForSuffix[i];
if (family.EndsWith(entry.suffix, kTextCaseUnicodeInsensitive)) {
@@ -352,59 +396,79 @@ std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
float font_size,
AlternateFontName alternate_font_name) {
DCHECK_EQ(creation_params.CreationType(), kCreateFontByFamily);
+ sk_sp<SkTypeface> typeface;
CString name;
- sk_sp<SkTypeface> typeface =
- CreateTypeface(font_description, creation_params, name);
- // Windows will always give us a valid pointer here, even if the face name
- // is non-existent. We have to double-check and see if the family name was
- // really used.
- if (!typeface ||
- !TypefacesMatchesFamily(typeface.get(), creation_params.Family())) {
- AtomicString adjusted_name;
- FontSelectionValue variant_weight;
- FontSelectionValue variant_stretch;
-
- // TODO: crbug.com/627143 LocalFontFaceSource.cpp, which implements
- // retrieving src: local() font data uses getFontData, which in turn comes
- // here, to retrieve fonts from the cache and specifies the argument to
- // local() as family name. So we do not match by full font name or
- // postscript name as the spec says:
- // https://drafts.csswg.org/css-fonts-3/#src-desc
-
- // Prevent one side effect of the suffix translation below where when
- // matching local("Roboto Regular") it tries to find the closest match even
- // though that can be a bold font in case of Roboto Bold.
- if (alternate_font_name == AlternateFontName::kLocalUniqueFace) {
- return nullptr;
+
+ if (alternate_font_name == AlternateFontName::kLocalUniqueFace &&
+ RuntimeEnabledFeatures::FontSrcLocalMatchingEnabled()) {
+ typeface = CreateTypefaceFromUniqueName(creation_params, name);
+
+ if (!typeface && sideloaded_fonts_) {
+ typeface = FindUniqueFontNameFromSideloadedFonts(creation_params.Family(),
+ sideloaded_fonts_);
}
- if (alternate_font_name == AlternateFontName::kLastResort) {
- if (!typeface)
- return nullptr;
- } else if (TypefacesHasWeightSuffix(creation_params.Family(), adjusted_name,
- variant_weight)) {
- FontFaceCreationParams adjusted_params(adjusted_name);
- FontDescription adjusted_font_description = font_description;
- adjusted_font_description.SetWeight(variant_weight);
- typeface =
- CreateTypeface(adjusted_font_description, adjusted_params, name);
- if (!typeface || !TypefacesMatchesFamily(typeface.get(), adjusted_name)) {
+ // We do not need to try any heuristic around the font name, as below, for
+ // family matching.
+ if (!typeface)
+ return nullptr;
+
+ } else {
+ typeface = CreateTypeface(font_description, creation_params, name);
+
+ // For a family match, Windows will always give us a valid pointer here,
+ // even if the face name is non-existent. We have to double-check and see if
+ // the family name was really used.
+ if (!typeface ||
+ !TypefacesMatchesFamily(typeface.get(), creation_params.Family())) {
+ AtomicString adjusted_name;
+ FontSelectionValue variant_weight;
+ FontSelectionValue variant_stretch;
+
+ // TODO: crbug.com/627143 LocalFontFaceSource.cpp, which implements
+ // retrieving src: local() font data uses getFontData, which in turn comes
+ // here, to retrieve fonts from the cache and specifies the argument to
+ // local() as family name. So we do not match by full font name or
+ // postscript name as the spec says:
+ // https://drafts.csswg.org/css-fonts-3/#src-desc
+
+ // Prevent one side effect of the suffix translation below where when
+ // matching local("Roboto Regular") it tries to find the closest match
+ // even though that can be a bold font in case of Roboto Bold.
+ if (alternate_font_name == AlternateFontName::kLocalUniqueFace) {
return nullptr;
}
- } else if (TypefacesHasStretchSuffix(creation_params.Family(),
- adjusted_name, variant_stretch)) {
- FontFaceCreationParams adjusted_params(adjusted_name);
- FontDescription adjusted_font_description = font_description;
- adjusted_font_description.SetStretch(variant_stretch);
- typeface =
- CreateTypeface(adjusted_font_description, adjusted_params, name);
- if (!typeface || !TypefacesMatchesFamily(typeface.get(), adjusted_name)) {
+ if (alternate_font_name == AlternateFontName::kLastResort) {
+ if (!typeface)
+ return nullptr;
+ } else if (TypefacesHasWeightSuffix(creation_params.Family(),
+ adjusted_name, variant_weight)) {
+ FontFaceCreationParams adjusted_params(adjusted_name);
+ FontDescription adjusted_font_description = font_description;
+ adjusted_font_description.SetWeight(variant_weight);
+ typeface =
+ CreateTypeface(adjusted_font_description, adjusted_params, name);
+ if (!typeface ||
+ !TypefacesMatchesFamily(typeface.get(), adjusted_name)) {
+ return nullptr;
+ }
+
+ } else if (TypefacesHasStretchSuffix(creation_params.Family(),
+ adjusted_name, variant_stretch)) {
+ FontFaceCreationParams adjusted_params(adjusted_name);
+ FontDescription adjusted_font_description = font_description;
+ adjusted_font_description.SetStretch(variant_stretch);
+ typeface =
+ CreateTypeface(adjusted_font_description, adjusted_params, name);
+ if (!typeface ||
+ !TypefacesMatchesFamily(typeface.get(), adjusted_name)) {
+ return nullptr;
+ }
+ } else {
return nullptr;
}
- } else {
- return nullptr;
}
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
index ecb970bdd70..1c4ad7ccb81 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
@@ -34,6 +34,7 @@
#include <unicode/uchar.h>
#include <limits>
+#include "base/stl_util.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/text/icu_error.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -376,13 +377,13 @@ const UChar* GetFontBasedOnUnicodeBlock(UBlockCode block_code,
static const UChar* math_font = 0;
static bool initialized = false;
if (!initialized) {
- for (size_t i = 0; i < arraysize(kEmojiFonts); i++) {
+ for (size_t i = 0; i < base::size(kEmojiFonts); i++) {
if (IsFontPresent(kEmojiFonts[i], font_manager)) {
emoji_font = kEmojiFonts[i];
break;
}
}
- for (size_t i = 0; i < arraysize(kMathFonts); i++) {
+ for (size_t i = 0; i < base::size(kMathFonts); i++) {
if (IsFontPresent(kMathFonts[i], font_manager)) {
math_font = kMathFonts[i];
break;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc
index 4fc4b20ddfa..e5cc3293961 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_platform_data_win.cc
@@ -39,55 +39,21 @@
namespace blink {
-void FontPlatformData::SetupSkPaint(SkPaint* font, float, const Font*) const {
- font->setTextSize(SkFloatToScalar(text_size_));
- font->setTypeface(typeface_);
- font->setFakeBoldText(synthetic_bold_);
- font->setTextSkewX(synthetic_italic_ ? -SK_Scalar1 / 4 : 0);
-
- uint32_t text_flags = PaintTextFlags();
- uint32_t flags = font->getFlags();
- static const uint32_t kTextFlagsMask =
- SkPaint::kAntiAlias_Flag | SkPaint::kLCDRenderText_Flag |
- SkPaint::kEmbeddedBitmapText_Flag | SkPaint::kSubpixelText_Flag;
- flags &= ~kTextFlagsMask;
-
- // Only use sub-pixel positioning if anti aliasing is enabled. Otherwise,
- // without font smoothing, subpixel text positioning leads to uneven spacing
- // since subpixel test placement coordinates would be passed to Skia, which
- // only has non-antialiased glyphs to draw, so they necessarily get clamped at
- // pixel positions, which leads to uneven spacing, either too close or too far
- // away from adjacent glyphs. We avoid this by linking the two flags.
- if (text_flags & SkPaint::kAntiAlias_Flag)
- flags |= SkPaint::kSubpixelText_Flag;
-
- if (WebTestSupport::IsRunningWebTest() &&
- !WebTestSupport::IsTextSubpixelPositioningAllowedForTest())
- flags &= ~SkPaint::kSubpixelText_Flag;
-
- SkASSERT(!(text_flags & ~kTextFlagsMask));
- flags |= text_flags;
-
- font->setFlags(flags);
-
- font->setEmbeddedBitmapText(!avoid_embedded_bitmaps_);
-}
-
void FontPlatformData::SetupSkFont(SkFont* font, float, const Font*) const {
font->setSize(SkFloatToScalar(text_size_));
font->setTypeface(typeface_);
font->setEmbolden(synthetic_bold_);
font->setSkewX(synthetic_italic_ ? -SK_Scalar1 / 4 : 0);
- uint32_t text_flags = PaintTextFlags();
- if (text_flags & SkPaint::kLCDRenderText_Flag) {
+ uint32_t font_flags = FontFlags();
+ if (font_flags & kSubpixelsAntiAlias) {
font->setEdging(SkFont::Edging::kSubpixelAntiAlias);
- } else if (text_flags & SkPaint::kAntiAlias_Flag) {
+ } else if (font_flags & kAntiAlias) {
font->setEdging(SkFont::Edging::kAntiAlias);
} else {
font->setEdging(SkFont::Edging::kAlias);
}
- font->setSubpixel(SkToBool(text_flags & SkPaint::kSubpixelText_Flag));
+ font->setSubpixel(SkToBool(font_flags & kSubpixelMetrics));
// Only use sub-pixel positioning if anti aliasing is enabled. Otherwise,
// without font smoothing, subpixel text positioning leads to uneven spacing
@@ -95,7 +61,7 @@ void FontPlatformData::SetupSkFont(SkFont* font, float, const Font*) const {
// only has non-antialiased glyphs to draw, so they necessarily get clamped at
// pixel positions, which leads to uneven spacing, either too close or too far
// away from adjacent glyphs. We avoid this by linking the two flags.
- if (text_flags & SkPaint::kAntiAlias_Flag)
+ if (font_flags & kAntiAlias)
font->setSubpixel(true);
if (WebTestSupport::IsRunningWebTest() &&
@@ -113,18 +79,18 @@ static bool IsWebFont(const String& family_name) {
'=' == family_name[23];
}
-static int ComputePaintTextFlags(String font_family_name) {
+static int ComputeFontFlags(String font_family_name) {
if (WebTestSupport::IsRunningWebTest())
return WebTestSupport::IsFontAntialiasingEnabledForTest()
- ? SkPaint::kAntiAlias_Flag
+ ? FontPlatformData::kAntiAlias
: 0;
- int text_flags = 0;
+ int font_flags = 0;
if (FontCache::GetFontCache()->AntialiasedTextEnabled()) {
int lcd_flag = FontCache::GetFontCache()->LcdTextEnabled()
- ? SkPaint::kLCDRenderText_Flag
+ ? FontPlatformData::kSubpixelsAntiAlias
: 0;
- text_flags = SkPaint::kAntiAlias_Flag | lcd_flag;
+ font_flags = FontPlatformData::kAntiAlias | lcd_flag;
}
// Many web-fonts are so poorly hinted that they are terrible to read when
@@ -132,13 +98,13 @@ static int ComputePaintTextFlags(String font_family_name) {
// drawn with at least grayscale AA, even when the System (getSystemTextFlags)
// tells us to draw only in BW.
if (IsWebFont(font_family_name))
- text_flags |= SkPaint::kAntiAlias_Flag;
+ font_flags |= FontPlatformData::kAntiAlias;
- return text_flags;
+ return font_flags;
}
void FontPlatformData::QuerySystemForRenderStyle() {
- paint_text_flags_ = ComputePaintTextFlags(FontFamilyName());
+ font_flags_ = ComputeFontFlags(FontFamilyName());
}
} // namespace blink
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
new file mode 100644
index 00000000000..715ce8996a0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
@@ -0,0 +1,75 @@
+// Copyright 2018 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/font_unique_name_lookup_win.h"
+
+#include "base/files/file_path.h"
+#include "mojo/public/mojom/base/shared_memory.mojom-blink.h"
+#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h"
+#include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/skia/include/ports/SkTypeface_win.h"
+
+namespace {
+
+// These enum values correspond to the
+// "Blink.Fonts.WindowsUniqueLocalFontInstantiationResult" histogram, new values
+// can be added, but old values should never be reused.
+enum WindowsUniqueLocalFontInstantiationResult {
+ kSuccess = 0,
+ kErrorOutsideWindowsFontsDirectory = 1,
+ kErrorOther = 2,
+ kMaxWindowsUniqueLocalFontInstantiationResult = 3
+};
+
+} // namespace
+
+namespace blink {
+
+FontUniqueNameLookupWin::FontUniqueNameLookupWin() = default;
+
+FontUniqueNameLookupWin::~FontUniqueNameLookupWin() = default;
+
+sk_sp<SkTypeface> FontUniqueNameLookupWin::MatchUniqueName(
+ const String& font_unique_name) {
+ if (!EnsureMatchingServiceConnected<mojom::blink::DWriteFontProxyPtr>())
+ return nullptr;
+
+ base::Optional<FontTableMatcher::MatchResult> match_result =
+ font_table_matcher_->MatchName(font_unique_name.Utf8().data());
+ if (!match_result)
+ return nullptr;
+ // Record here when a locally uniquely matched font could not be
+ // instantiated. One reason could be that the font was outside the
+ // C:\Windows\Fonts directory and thus not accessible due to sandbox
+ // restrictions.
+ sk_sp<SkTypeface> local_typeface = SkTypeface::MakeFromFile(
+ match_result->font_path.c_str(), match_result->ttc_index);
+
+ WindowsUniqueLocalFontInstantiationResult result = kSuccess;
+
+ // There is a chance that some systems have managed to register fonts into the
+ // Windows system font collection outside the C:\Windows\Fonts directory. For
+ // sandboxing reasons, we are unable to access them here. This histogram
+ // serves to quantify how often this case occurs and whether we need and
+ // additional sandbox helper to open the file handle on the browser process
+ // side.
+ if (!local_typeface) {
+ base::FilePath windows_fonts_path(L"C:\\WINDOWS\\FONTS");
+ if (!windows_fonts_path.IsParent(
+ base::FilePath::FromUTF8Unsafe(match_result->font_path.c_str())))
+ result = kErrorOutsideWindowsFontsDirectory;
+ else
+ result = kErrorOther;
+ }
+
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(
+ EnumerationHistogram, windows_unique_local_font_instantiation_histogram,
+ ("Blink.Fonts.WindowsUniqueLocalFontInstantiationResult",
+ kMaxWindowsUniqueLocalFontInstantiationResult));
+ windows_unique_local_font_instantiation_histogram.Count(result);
+
+ return local_typeface;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.h b/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.h
new file mode 100644
index 00000000000..4593b9c5fee
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.h
@@ -0,0 +1,25 @@
+// Copyright 2018 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_WIN_FONT_UNIQUE_NAME_LOOKUP_WIN_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FONT_UNIQUE_NAME_LOOKUP_WIN_H_
+
+#include "third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h"
+#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
+
+namespace blink {
+
+class FontUniqueNameLookupWin : public FontUniqueNameLookup {
+ public:
+ FontUniqueNameLookupWin();
+ ~FontUniqueNameLookupWin() override;
+ sk_sp<SkTypeface> MatchUniqueName(const String& font_unique_name) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FontUniqueNameLookupWin);
+};
+
+} // namespace blink
+
+#endif