summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc')
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc156
1 files changed, 94 insertions, 62 deletions
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
index 4d4a8227312..97fa173bb8b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
@@ -30,8 +30,10 @@
#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
-#include <hb-ot.h>
+// clang-format off
#include <hb.h>
+#include <hb-ot.h>
+// clang-format on
#include <memory>
@@ -50,6 +52,7 @@
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPoint.h"
@@ -59,34 +62,40 @@
namespace blink {
-void HbFontDeleter::operator()(hb_font_t* font) {
- if (font)
- hb_font_destroy(font);
-}
+namespace {
-void HbFaceDeleter::operator()(hb_face_t* face) {
- if (face)
- hb_face_destroy(face);
-}
+#if defined(OS_MACOSX)
+void DetermineTrakSbix(SkTypeface* typeface, bool* has_trak, bool* has_sbix) {
+ int num_tags = typeface->countTables();
+
+ SkFontTableTag tags[num_tags];
+
+ int returned_tags = typeface->getTableTags(tags);
+ DCHECK_EQ(num_tags, returned_tags);
-struct HbSetDeleter {
- void operator()(hb_set_t* set) {
- if (set)
- hb_set_destroy(set);
+ for (auto& tag : tags) {
+ if (tag == SkSetFourByteTag('t', 'r', 'a', 'k'))
+ *has_trak = true;
+ if (tag == SkSetFourByteTag('s', 'b', 'i', 'x'))
+ *has_sbix = true;
}
-};
+}
+#endif
-using HbSetUniquePtr = std::unique_ptr<hb_set_t, HbSetDeleter>;
+} // namespace
-static scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t*);
+static scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(
+ hb_face_t*,
+ SkTypeface* typefaces);
HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
: platform_data_(platform_data), unique_id_(unique_id) {
HarfBuzzFontCache::AddResult result =
- FontGlobalContext::GetHarfBuzzFontCache().insert(unique_id_, nullptr);
+ FontGlobalContext::GetHarfBuzzFontCache()->insert(unique_id_, nullptr);
if (result.is_new_entry) {
- HbFaceUniquePtr face(CreateFace());
- result.stored_value->value = CreateHbFontCacheEntry(face.get());
+ HbScoped<hb_face_t> face(CreateFace());
+ result.stored_value->value =
+ CreateHbFontCacheEntry(face.get(), platform_data->Typeface());
}
result.stored_value->value->AddRef();
unscaled_font_ = result.stored_value->value->HbFont();
@@ -94,13 +103,14 @@ HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
}
HarfBuzzFace::~HarfBuzzFace() {
- HarfBuzzFontCache::iterator result =
- FontGlobalContext::GetHarfBuzzFontCache().find(unique_id_);
- SECURITY_DCHECK(result != FontGlobalContext::GetHarfBuzzFontCache().end());
+ HarfBuzzFontCache* harfbuzz_font_cache =
+ FontGlobalContext::GetHarfBuzzFontCache();
+ HarfBuzzFontCache::iterator result = harfbuzz_font_cache->find(unique_id_);
+ SECURITY_DCHECK(result != harfbuzz_font_cache->end());
DCHECK(!result.Get()->value->HasOneRef());
result.Get()->value->Release();
if (result.Get()->value->HasOneRef())
- FontGlobalContext::GetHarfBuzzFontCache().erase(unique_id_);
+ harfbuzz_font_cache->erase(unique_id_);
}
static hb_bool_t HarfBuzzGetGlyph(hb_font_t* hb_font,
@@ -228,7 +238,7 @@ bool HarfBuzzFace::HasSpaceInLigaturesOrKerning(TypesettingFeatures features) {
const hb_codepoint_t kInvalidCodepoint = static_cast<hb_codepoint_t>(-1);
hb_codepoint_t space = kInvalidCodepoint;
- HbSetUniquePtr glyphs(hb_set_create());
+ HbScoped<hb_set_t> glyphs(hb_set_create());
// Check whether computing is needed and compute for gpos/gsub.
if (features & kKerning &&
@@ -280,31 +290,43 @@ bool HarfBuzzFace::ShouldSubpixelPosition() {
return harfbuzz_font_data_->font_.isSubpixel();
}
-static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs() {
- hb_font_funcs_t* funcs = FontGlobalContext::GetHarfBuzzFontFuncs();
+static hb_font_funcs_t* create_populated_hb_font_funcs(
+ FontGlobalContext::HorizontalAdvanceSource horizontal_advance_source) {
+ hb_font_funcs_t* funcs = hb_font_funcs_create();
- // We don't set callback functions which we can't support.
- // HarfBuzz will use the fallback implementation if they aren't set.
- if (!funcs) {
- funcs = hb_font_funcs_create();
- hb_font_funcs_set_variation_glyph_func(funcs, HarfBuzzGetGlyph, nullptr,
- nullptr);
- hb_font_funcs_set_nominal_glyph_func(funcs, HarfBuzzGetNominalGlyph,
- nullptr, nullptr);
+ if (horizontal_advance_source == FontGlobalContext::kSkiaHorizontalAdvances) {
hb_font_funcs_set_glyph_h_advance_func(
funcs, HarfBuzzGetGlyphHorizontalAdvance, nullptr, nullptr);
hb_font_funcs_set_glyph_h_advances_func(
funcs, HarfBuzzGetGlyphHorizontalAdvances, nullptr, nullptr);
- // TODO(https://crbug.com/899718): Replace vertical metrics callbacks with
- // HarfBuzz VORG/VMTX internal implementation by deregistering those.
- hb_font_funcs_set_glyph_v_advance_func(
- funcs, HarfBuzzGetGlyphVerticalAdvance, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_origin_func(funcs, HarfBuzzGetGlyphVerticalOrigin,
- nullptr, nullptr);
- hb_font_funcs_set_glyph_extents_func(funcs, HarfBuzzGetGlyphExtents,
+ }
+ hb_font_funcs_set_variation_glyph_func(funcs, HarfBuzzGetGlyph, nullptr,
+ nullptr);
+ hb_font_funcs_set_nominal_glyph_func(funcs, HarfBuzzGetNominalGlyph, nullptr,
+ nullptr);
+ // TODO(https://crbug.com/899718): Replace vertical metrics callbacks with
+ // HarfBuzz VORG/VMTX internal implementation by deregistering those.
+ hb_font_funcs_set_glyph_v_advance_func(funcs, HarfBuzzGetGlyphVerticalAdvance,
nullptr, nullptr);
- hb_font_funcs_make_immutable(funcs);
- FontGlobalContext::SetHarfBuzzFontFuncs(funcs);
+ hb_font_funcs_set_glyph_v_origin_func(funcs, HarfBuzzGetGlyphVerticalOrigin,
+ nullptr, nullptr);
+ hb_font_funcs_set_glyph_extents_func(funcs, HarfBuzzGetGlyphExtents, nullptr,
+ nullptr);
+
+ hb_font_funcs_make_immutable(funcs);
+ return funcs;
+}
+
+static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs(
+ FontGlobalContext::HorizontalAdvanceSource advance_source) {
+ hb_font_funcs_t* funcs =
+ FontGlobalContext::GetHarfBuzzFontFuncs(advance_source);
+
+ // We don't set callback functions which we can't support.
+ // HarfBuzz will use the fallback implementation if they aren't set.
+ if (!funcs) {
+ funcs = create_populated_hb_font_funcs(advance_source);
+ FontGlobalContext::SetHarfBuzzFontFuncs(advance_source, funcs);
}
DCHECK(funcs);
return funcs;
@@ -360,11 +382,10 @@ hb_face_t* HarfBuzzFace::CreateFace() {
if (tf_stream && tf_stream->getMemoryBase()) {
const void* tf_memory = tf_stream->getMemoryBase();
size_t tf_size = tf_stream->getLength();
- std::unique_ptr<hb_blob_t, void (*)(hb_blob_t*)> face_blob(
+ HbScoped<hb_blob_t> face_blob(
hb_blob_create(reinterpret_cast<const char*>(tf_memory),
SafeCast<unsigned int>(tf_size), HB_MEMORY_MODE_READONLY,
- tf_stream.release(), DeleteTypefaceStream),
- hb_blob_destroy);
+ tf_stream.release(), DeleteTypefaceStream));
face = hb_face_create(face_blob.get(), ttc_index);
}
#endif
@@ -382,15 +403,39 @@ hb_face_t* HarfBuzzFace::CreateFace() {
return face;
}
-scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t* face) {
- HbFontUniquePtr ot_font(hb_font_create(face));
+scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t* face,
+ SkTypeface* typeface) {
+ HbScoped<hb_font_t> ot_font(hb_font_create(face));
hb_ot_font_set_funcs(ot_font.get());
+
+ int axis_count = typeface->getVariationDesignPosition(nullptr, 0);
+ if (axis_count > 0) {
+ Vector<SkFontArguments::VariationPosition::Coordinate> axis_values;
+ axis_values.resize(axis_count);
+ if (typeface->getVariationDesignPosition(axis_values.data(),
+ axis_values.size()) > 0) {
+ hb_font_set_variations(
+ ot_font.get(), reinterpret_cast<hb_variation_t*>(axis_values.data()),
+ axis_values.size());
+ }
+ }
+
// Creating a sub font means that non-available functions
// are found from the parent.
hb_font_t* unscaled_font = hb_font_create_sub_font(ot_font.get());
scoped_refptr<HbFontCacheEntry> cache_entry =
HbFontCacheEntry::Create(unscaled_font);
- hb_font_set_funcs(unscaled_font, HarfBuzzSkiaGetFontFuncs(),
+
+ FontGlobalContext::HorizontalAdvanceSource advance_source =
+ FontGlobalContext::kSkiaHorizontalAdvances;
+#if defined(OS_MACOSX)
+ bool has_trak = false;
+ bool has_sbix = false;
+ DetermineTrakSbix(typeface, &has_trak, &has_sbix);
+ if (has_trak && !has_sbix)
+ advance_source = FontGlobalContext::kHarfBuzzHorizontalAdvances;
+#endif
+ hb_font_set_funcs(unscaled_font, HarfBuzzSkiaGetFontFuncs(advance_source),
cache_entry->HbFontData(), nullptr);
return cache_entry;
}
@@ -423,19 +468,6 @@ hb_font_t* HarfBuzzFace::GetScaledFont(
// equivalent of CSS pixels here.
hb_font_set_ptem(unscaled_font_, platform_data_->size());
- SkTypeface* typeface = harfbuzz_font_data_->font_.getTypeface();
- int axis_count = typeface->getVariationDesignPosition(nullptr, 0);
- if (axis_count > 0) {
- Vector<SkFontArguments::VariationPosition::Coordinate> axis_values;
- axis_values.resize(axis_count);
- if (typeface->getVariationDesignPosition(axis_values.data(),
- axis_values.size()) > 0) {
- hb_font_set_variations(
- unscaled_font_, reinterpret_cast<hb_variation_t*>(axis_values.data()),
- axis_values.size());
- }
- }
-
return unscaled_font_;
}