LibWeb/LibGfx: Add ShapeFeatures argument to shape_text()

This commit is contained in:
Johan Dahlin 2024-11-07 16:36:11 +01:00
parent 0a3193f0b6
commit 98183c7164
7 changed files with 16 additions and 12 deletions

View file

@ -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> ScaledFont::scaled_with_size(float point_size) const

View file

@ -12,7 +12,7 @@
namespace Gfx {
RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf8View string, Gfx::Font const& font, GlyphRun::TextType text_type)
RefPtr<GlyphRun> 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<GlyphRun> shape_text(FloatPoint baseline_start, float letter_spacing, Utf
Vector<hb_glyph_info_t> 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<GlyphRun> 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();
}

View file

@ -74,7 +74,7 @@ private:
float m_width { 0 };
};
RefPtr<GlyphRun> 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<GlyphRun> 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);
}

View file

@ -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<int>(glyph_run->width()), static_cast<int>(height) } };

View file

@ -293,7 +293,8 @@ Optional<InlineLevelIterator::Item> 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());

View file

@ -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);

View file

@ -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();