From 98183c716498d6d36c48981677f350f4667971e8 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 7 Nov 2024 16:36:11 +0100 Subject: [PATCH] LibWeb/LibGfx: Add ShapeFeatures argument to shape_text() --- Libraries/LibGfx/Font/ScaledFont.cpp | 6 +++--- Libraries/LibGfx/TextLayout.cpp | 10 ++++++---- Libraries/LibGfx/TextLayout.h | 4 ++-- Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp | 2 +- Libraries/LibWeb/Layout/InlineLevelIterator.cpp | 3 ++- Libraries/LibWeb/Layout/InlineLevelIterator.h | 1 + Libraries/LibWeb/Painting/DisplayListRecorder.cpp | 2 +- 7 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Libraries/LibGfx/Font/ScaledFont.cpp b/Libraries/LibGfx/Font/ScaledFont.cpp index 8569d3fc14c..06f34ec04ff 100644 --- a/Libraries/LibGfx/Font/ScaledFont.cpp +++ b/Libraries/LibGfx/Font/ScaledFont.cpp @@ -58,13 +58,13 @@ ScaledFontMetrics ScaledFont::metrics() const return metrics; } -float ScaledFont::width(StringView view) const { return measure_text_width(Utf8View(view), *this); } -float ScaledFont::width(Utf8View const& view) const { return measure_text_width(view, *this); } +float ScaledFont::width(StringView view) const { return measure_text_width(Utf8View(view), *this, {}); } +float ScaledFont::width(Utf8View const& view) const { return measure_text_width(view, *this, {}); } float ScaledFont::glyph_width(u32 code_point) const { auto string = String::from_code_point(code_point); - return measure_text_width(Utf8View(string), *this); + return measure_text_width(Utf8View(string), *this, {}); } NonnullRefPtr ScaledFont::scaled_with_size(float point_size) const diff --git a/Libraries/LibGfx/TextLayout.cpp b/Libraries/LibGfx/TextLayout.cpp index c1ad71a4939..a1a067210e1 100644 --- a/Libraries/LibGfx/TextLayout.cpp +++ b/Libraries/LibGfx/TextLayout.cpp @@ -12,7 +12,7 @@ namespace Gfx { -RefPtr shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType text_type) +RefPtr shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType text_type, ShapeFeatures const& features) { hb_buffer_t* buffer = hb_buffer_create(); ScopeGuard destroy_buffer = [&]() { hb_buffer_destroy(buffer); }; @@ -24,7 +24,7 @@ RefPtr shape_text(FloatPoint baseline_start, float letter_spacing, Utf Vector const input_glyph_info({ glyph_info, glyph_count }); auto* hb_font = font.harfbuzz_font(); - hb_shape(hb_font, buffer, nullptr, 0); + hb_shape(hb_font, buffer, features.is_empty() ? nullptr : (hb_feature_t const*)features.data(), features.size()); glyph_info = hb_buffer_get_glyph_infos(buffer, &glyph_count); auto* positions = hb_buffer_get_glyph_positions(buffer, &glyph_count); @@ -45,12 +45,14 @@ RefPtr shape_text(FloatPoint baseline_start, float letter_spacing, Utf point.translate_by(letter_spacing, 0); } + hb_buffer_reset(buffer); + return adopt_ref(*new Gfx::GlyphRun(move(glyph_run), font, text_type, point.x())); } -float measure_text_width(Utf8View const& string, Gfx::Font const& font) +float measure_text_width(Utf8View const& string, Gfx::Font const& font, ShapeFeatures const& features) { - auto glyph_run = shape_text({}, 0, string, font, GlyphRun::TextType::Common); + auto glyph_run = shape_text({}, 0, string, font, GlyphRun::TextType::Common, features); return glyph_run->width(); } diff --git a/Libraries/LibGfx/TextLayout.h b/Libraries/LibGfx/TextLayout.h index 3ca2a4c792d..e67d4e4fe1b 100644 --- a/Libraries/LibGfx/TextLayout.h +++ b/Libraries/LibGfx/TextLayout.h @@ -74,7 +74,7 @@ private: float m_width { 0 }; }; -RefPtr shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType); -float measure_text_width(Utf8View const& string, Gfx::Font const& font); +RefPtr shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType, ShapeFeatures const& features); +float measure_text_width(Utf8View const& string, Gfx::Font const& font, ShapeFeatures const& features); } diff --git a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index c8e169f4d29..93fd8982fbf 100644 --- a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -575,7 +575,7 @@ CanvasRenderingContext2D::PreparedText CanvasRenderingContext2D::prepare_text(By Gfx::FloatPoint anchor { 0, 0 }; auto physical_alignment = Gfx::TextAlignment::CenterLeft; - auto glyph_run = Gfx::shape_text(anchor, 0, replaced_text.code_points(), *font, Gfx::GlyphRun::TextType::Ltr); + auto glyph_run = Gfx::shape_text(anchor, 0, replaced_text.code_points(), *font, Gfx::GlyphRun::TextType::Ltr, {}); // 8. Let result be an array constructed by iterating over each glyph in the inline box from left to right (if any), adding to the array, for each glyph, the shape of the glyph as it is in the inline box, positioned on a coordinate space using CSS pixels with its origin is at the anchor point. PreparedText prepared_text { glyph_run, physical_alignment, { 0, 0, static_cast(glyph_run->width()), static_cast(height) } }; diff --git a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index 333423e8f77..702f7e94363 100644 --- a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp +++ b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp @@ -293,7 +293,8 @@ Optional InlineLevelIterator::next_without_lookahead( x = tab_stop_dist.to_float(); } - auto glyph_run = Gfx::shape_text({ x, 0 }, letter_spacing.to_float(), chunk.view, chunk.font, text_type); + auto shape_features = create_and_merge_font_features(); + auto glyph_run = Gfx::shape_text({ x, 0 }, letter_spacing.to_float(), chunk.view, chunk.font, text_type, shape_features); CSSPixels chunk_width = CSSPixels::nearest_value_for(glyph_run->width()); diff --git a/Libraries/LibWeb/Layout/InlineLevelIterator.h b/Libraries/LibWeb/Layout/InlineLevelIterator.h index de345215932..1bfd90c4a37 100644 --- a/Libraries/LibWeb/Layout/InlineLevelIterator.h +++ b/Libraries/LibWeb/Layout/InlineLevelIterator.h @@ -67,6 +67,7 @@ private: void exit_node_with_box_model_metrics(); void add_extra_box_model_metrics_to_item(Item&, bool add_leading_metrics, bool add_trailing_metrics); + Gfx::ShapeFeatures create_and_merge_font_features(); Layout::Node const* next_inline_node_in_pre_order(Layout::Node const& current, Layout::Node const* stay_within); diff --git a/Libraries/LibWeb/Painting/DisplayListRecorder.cpp b/Libraries/LibWeb/Painting/DisplayListRecorder.cpp index 44385334af5..f259efcae8b 100644 --- a/Libraries/LibWeb/Painting/DisplayListRecorder.cpp +++ b/Libraries/LibWeb/Painting/DisplayListRecorder.cpp @@ -220,7 +220,7 @@ void DisplayListRecorder::draw_text(Gfx::IntRect const& rect, String raw_text, G if (rect.is_empty()) return; - auto glyph_run = Gfx::shape_text({}, 0, raw_text.code_points(), font, Gfx::GlyphRun::TextType::Ltr); + auto glyph_run = Gfx::shape_text({}, 0, raw_text.code_points(), font, Gfx::GlyphRun::TextType::Ltr, {}); float baseline_x = 0; if (alignment == Gfx::TextAlignment::CenterLeft) { baseline_x = rect.x();