diff --git a/Userland/Libraries/LibGfx/TextLayout.h b/Userland/Libraries/LibGfx/TextLayout.h index 5a4243840a..a4e24e108a 100644 --- a/Userland/Libraries/LibGfx/TextLayout.h +++ b/Userland/Libraries/LibGfx/TextLayout.h @@ -100,6 +100,23 @@ struct DrawEmoji { using DrawGlyphOrEmoji = Variant; +class GlyphRun : public RefCounted { +public: + GlyphRun() = default; + GlyphRun(Vector&& glyphs) + : m_glyphs(move(glyphs)) + { + } + + [[nodiscard]] Vector const& glyphs() const { return m_glyphs; } + [[nodiscard]] bool is_empty() const { return m_glyphs.is_empty(); } + + void append(Gfx::DrawGlyphOrEmoji glyph) { m_glyphs.append(glyph); } + +private: + Vector m_glyphs; +}; + Variant prepare_draw_glyph_or_emoji(FloatPoint point, Utf8CodePointIterator& it, Font const& font); template diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.cpp b/Userland/Libraries/LibWeb/Layout/LineBox.cpp index eed41f04e5..039cdc697e 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBox.cpp @@ -26,7 +26,7 @@ void LineBox::add_fragment(Node const& layout_node, int start, int length, CSSPi m_fragments.last().set_width(m_fragments.last().width() + content_width); for (auto glyph : glyph_run) { glyph.visit([&](auto& glyph) { glyph.position.translate_by(fragment_width.to_float(), 0); }); - m_fragments.last().m_glyph_run.append(glyph); + m_fragments.last().m_glyph_run->append(glyph); } } else { Vector glyph_run_copy { glyph_run }; diff --git a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h index f64a93006e..8cb4c12f9a 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h +++ b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h @@ -19,7 +19,7 @@ class LineBoxFragment { friend class LineBox; public: - LineBoxFragment(Node const& layout_node, int start, int length, CSSPixelPoint offset, CSSPixelSize size, CSSPixels border_box_top, CSSPixels border_box_bottom, Vector glyph_run = {}) + LineBoxFragment(Node const& layout_node, int start, int length, CSSPixelPoint offset, CSSPixelSize size, CSSPixels border_box_top, CSSPixels border_box_bottom, Vector glyphs) : m_layout_node(layout_node) , m_start(start) , m_length(length) @@ -27,7 +27,7 @@ public: , m_size(size) , m_border_box_top(border_box_top) , m_border_box_bottom(border_box_bottom) - , m_glyph_run(move(glyph_run)) + , m_glyph_run(adopt_ref(*new Gfx::GlyphRun(move(glyphs)))) { } @@ -60,7 +60,7 @@ public: bool is_atomic_inline() const; - Vector const& glyph_run() const { return m_glyph_run; } + Gfx::GlyphRun const& glyph_run() const { return *m_glyph_run; } private: JS::NonnullGCPtr m_layout_node; @@ -71,7 +71,7 @@ private: CSSPixels m_border_box_top { 0 }; CSSPixels m_border_box_bottom { 0 }; CSSPixels m_baseline { 0 }; - Vector m_glyph_run; + NonnullRefPtr m_glyph_run; }; } diff --git a/Userland/Libraries/LibWeb/Painting/Command.h b/Userland/Libraries/LibWeb/Painting/Command.h index e22faec80d..7bf45740b5 100644 --- a/Userland/Libraries/LibWeb/Painting/Command.h +++ b/Userland/Libraries/LibWeb/Painting/Command.h @@ -38,7 +38,7 @@ namespace Web::Painting { struct DrawGlyphRun { - Vector glyph_run; + NonnullRefPtr glyph_run; Color color; Gfx::IntRect rect; Gfx::FloatPoint translation; diff --git a/Userland/Libraries/LibWeb/Painting/CommandList.cpp b/Userland/Libraries/LibWeb/Painting/CommandList.cpp index a3763c5cb6..22f3b716b6 100644 --- a/Userland/Libraries/LibWeb/Painting/CommandList.cpp +++ b/Userland/Libraries/LibWeb/Painting/CommandList.cpp @@ -49,7 +49,7 @@ void CommandList::execute(CommandExecutor& executor) auto& command = command_with_scroll_id.command; if (command.has()) { auto scale = command.get().scale; - for (auto const& glyph_or_emoji : command.get().glyph_run) { + for (auto const& glyph_or_emoji : command.get().glyph_run->glyphs()) { if (glyph_or_emoji.has()) { auto const& glyph = glyph_or_emoji.get(); auto const& font = *glyph.font->with_size(glyph.font->point_size() * static_cast(scale)); @@ -89,7 +89,7 @@ void CommandList::execute(CommandExecutor& executor) auto result = command.visit( [&](DrawGlyphRun const& command) { - return executor.draw_glyph_run(command.glyph_run, command.color, command.translation, command.scale); + return executor.draw_glyph_run(command.glyph_run->glyphs(), command.color, command.translation, command.scale); }, [&](DrawText const& command) { return executor.draw_text(command.rect, command.raw_text, command.alignment, command.color, diff --git a/Userland/Libraries/LibWeb/Painting/PaintableFragment.h b/Userland/Libraries/LibWeb/Painting/PaintableFragment.h index e0813aaca4..96548932b5 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableFragment.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableFragment.h @@ -38,7 +38,7 @@ public: CSSPixelRect const absolute_rect() const; - Vector const& glyph_run() const { return m_glyph_run; } + Gfx::GlyphRun const& glyph_run() const { return *m_glyph_run; } CSSPixelRect selection_rect(Gfx::Font const&) const; @@ -55,7 +55,7 @@ private: int m_start; int m_length; Painting::BorderRadiiData m_border_radii_data; - Vector m_glyph_run; + NonnullRefPtr m_glyph_run; Vector m_shadows; bool m_contained_by_inline_node { false }; }; diff --git a/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp b/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp index dc57eedef3..3b6e9d446e 100644 --- a/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp +++ b/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp @@ -206,11 +206,11 @@ void RecordingPainter::draw_signed_distance_field(Gfx::IntRect const& dst_rect, }); } -void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Span glyph_run, Color color, Gfx::IntRect const& rect, double scale) +void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Gfx::GlyphRun const& glyph_run, Color color, Gfx::IntRect const& rect, double scale) { auto transformed_baseline_start = state().translation.map(baseline_start).to_type(); append(DrawGlyphRun { - .glyph_run = Vector { glyph_run }, + .glyph_run = glyph_run, .color = color, .rect = state().translation.map(rect), .translation = transformed_baseline_start, diff --git a/Userland/Libraries/LibWeb/Painting/RecordingPainter.h b/Userland/Libraries/LibWeb/Painting/RecordingPainter.h index 7229a1752f..a1cf69317d 100644 --- a/Userland/Libraries/LibWeb/Painting/RecordingPainter.h +++ b/Userland/Libraries/LibWeb/Painting/RecordingPainter.h @@ -100,7 +100,7 @@ public: void draw_signed_distance_field(Gfx::IntRect const& dst_rect, Color color, Gfx::GrayscaleBitmap const& sdf, float smoothing); // Streamlined text drawing routine that does no wrapping/elision/alignment. - void draw_text_run(Gfx::IntPoint baseline_start, Span glyph_run, Color color, Gfx::IntRect const& rect, double scale); + void draw_text_run(Gfx::IntPoint baseline_start, Gfx::GlyphRun const& glyph_run, Color color, Gfx::IntRect const& rect, double scale); void add_clip_rect(Gfx::IntRect const& rect); diff --git a/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp b/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp index 8fd3338e46..32fba6bdf7 100644 --- a/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp @@ -590,8 +590,8 @@ void paint_text_shadow(PaintContext& context, PaintableFragment const& fragment, auto fragment_baseline = context.rounded_device_pixels(fragment.baseline()).value(); Vector scaled_glyph_run; - scaled_glyph_run.ensure_capacity(fragment.glyph_run().size()); - for (auto glyph : fragment.glyph_run()) { + scaled_glyph_run.ensure_capacity(fragment.glyph_run().glyphs().size()); + for (auto glyph : fragment.glyph_run().glyphs()) { glyph.visit([&](auto& glyph) { glyph.font = *glyph.font->with_size(glyph.font->point_size() * static_cast(context.device_pixels_per_css_pixel())); glyph.position = glyph.position.scaled(context.device_pixels_per_css_pixel());