diff --git a/Userland/Libraries/LibWeb/Painting/Command.cpp b/Userland/Libraries/LibWeb/Painting/Command.cpp index 731514100e..23bc1970ad 100644 --- a/Userland/Libraries/LibWeb/Painting/Command.cpp +++ b/Userland/Libraries/LibWeb/Painting/Command.cpp @@ -11,12 +11,8 @@ namespace Web::Painting { void DrawGlyphRun::translate_by(Gfx::IntPoint const& offset) { - for (auto& glyph : glyph_run) { - glyph.visit([&](auto& glyph) { - glyph.translate_by(offset.to_type()); - }); - } rect.translate_by(offset); + translation.translate_by(offset.to_type()); } Gfx::IntRect PaintOuterBoxShadow::bounding_rect() const diff --git a/Userland/Libraries/LibWeb/Painting/Command.h b/Userland/Libraries/LibWeb/Painting/Command.h index 3175e7f126..e22faec80d 100644 --- a/Userland/Libraries/LibWeb/Painting/Command.h +++ b/Userland/Libraries/LibWeb/Painting/Command.h @@ -42,6 +42,7 @@ struct DrawGlyphRun { Color color; Gfx::IntRect rect; Gfx::FloatPoint translation; + double scale { 1 }; [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; } diff --git a/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp b/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp index fa774b5cd1..40e3e5cabe 100644 --- a/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp +++ b/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp @@ -24,12 +24,15 @@ CommandExecutorCPU::CommandExecutorCPU(Gfx::Bitmap& bitmap) .scaling_mode = {} }); } -CommandResult CommandExecutorCPU::draw_glyph_run(Vector const& glyph_run, Color const& color, Gfx::FloatPoint translation) +CommandResult CommandExecutorCPU::draw_glyph_run(Vector const& glyph_run, Color const& color, Gfx::FloatPoint translation, double scale) { auto& painter = this->painter(); for (auto& glyph_or_emoji : glyph_run) { auto transformed_glyph = glyph_or_emoji; - transformed_glyph.visit([&](auto& glyph) { glyph.position.translate_by(translation); }); + transformed_glyph.visit([&](auto& glyph) { + glyph.position = glyph.position.scaled(scale).translated(translation); + glyph.font = *glyph.font->with_size(glyph.font->point_size() * static_cast(scale)); + }); if (glyph_or_emoji.has()) { auto& glyph = transformed_glyph.get(); painter.draw_glyph(glyph.position, glyph.code_point, *glyph.font, color); diff --git a/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.h b/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.h index a6806d7f3a..1e7b01385d 100644 --- a/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.h +++ b/Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.h @@ -13,7 +13,7 @@ namespace Web::Painting { class CommandExecutorCPU : public CommandExecutor { public: - CommandResult draw_glyph_run(Vector const& glyph_run, Color const&, Gfx::FloatPoint translation) override; + CommandResult draw_glyph_run(Vector const& glyph_run, Color const&, Gfx::FloatPoint translation, double scale) override; CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional> const&) override; CommandResult fill_rect(Gfx::IntRect const& rect, Color const&) override; CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) override; diff --git a/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.cpp b/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.cpp index d1ca02f10f..2b90fb1541 100644 --- a/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.cpp +++ b/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.cpp @@ -31,13 +31,16 @@ CommandExecutorGPU::~CommandExecutorGPU() painter().flush(m_target_bitmap); } -CommandResult CommandExecutorGPU::draw_glyph_run(Vector const& glyph_run, Color const& color, Gfx::FloatPoint translation) +CommandResult CommandExecutorGPU::draw_glyph_run(Vector const& glyph_run, Color const& color, Gfx::FloatPoint translation, double scale) { Vector transformed_glyph_run; transformed_glyph_run.ensure_capacity(glyph_run.size()); for (auto& glyph : glyph_run) { auto transformed_glyph = glyph; - transformed_glyph.visit([&](auto& glyph) { glyph.position.translate_by(translation); }); + transformed_glyph.visit([&](auto& glyph) { + glyph.position = glyph.position.scaled(scale).translated(translation); + glyph.font = *glyph.font->with_size(glyph.font->point_size() * static_cast(scale)); + }); transformed_glyph_run.append(transformed_glyph); } painter().draw_glyph_run(transformed_glyph_run, color); diff --git a/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.h b/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.h index a2a938d2f3..e78344fb7e 100644 --- a/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.h +++ b/Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.h @@ -14,7 +14,7 @@ namespace Web::Painting { class CommandExecutorGPU : public CommandExecutor { public: - CommandResult draw_glyph_run(Vector const& glyph_run, Color const&, Gfx::FloatPoint translation) override; + CommandResult draw_glyph_run(Vector const& glyph_run, Color const&, Gfx::FloatPoint translation, double scale) override; CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional> const&) override; CommandResult fill_rect(Gfx::IntRect const& rect, Color const&) override; CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) override; diff --git a/Userland/Libraries/LibWeb/Painting/CommandList.cpp b/Userland/Libraries/LibWeb/Painting/CommandList.cpp index e9779ba650..a3763c5cb6 100644 --- a/Userland/Libraries/LibWeb/Painting/CommandList.cpp +++ b/Userland/Libraries/LibWeb/Painting/CommandList.cpp @@ -48,10 +48,12 @@ void CommandList::execute(CommandExecutor& executor) for (auto& command_with_scroll_id : m_commands) { 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) { if (glyph_or_emoji.has()) { auto const& glyph = glyph_or_emoji.get(); - unique_glyphs.ensure(glyph.font, [] { return HashTable {}; }).set(glyph.code_point); + auto const& font = *glyph.font->with_size(glyph.font->point_size() * static_cast(scale)); + unique_glyphs.ensure(&font, [] { return HashTable {}; }).set(glyph.code_point); } } } @@ -87,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); + return executor.draw_glyph_run(command.glyph_run, 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/CommandList.h b/Userland/Libraries/LibWeb/Painting/CommandList.h index 06dd915520..849f9c142b 100644 --- a/Userland/Libraries/LibWeb/Painting/CommandList.h +++ b/Userland/Libraries/LibWeb/Painting/CommandList.h @@ -47,7 +47,7 @@ class CommandExecutor { public: virtual ~CommandExecutor() = default; - virtual CommandResult draw_glyph_run(Vector const& glyph_run, Color const&, Gfx::FloatPoint translation) = 0; + virtual CommandResult draw_glyph_run(Vector const& glyph_run, Color const&, Gfx::FloatPoint translation, double scale) = 0; virtual CommandResult draw_text(Gfx::IntRect const&, String const&, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional> const&) = 0; virtual CommandResult fill_rect(Gfx::IntRect const&, Color const&) = 0; virtual CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) = 0; diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index 8ff2a3efb9..0a3f8cd5b0 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -668,23 +668,15 @@ void paint_text_fragment(PaintContext& context, Layout::TextNode const& text_nod auto text = text_node.text_for_rendering(); DevicePixelPoint baseline_start { fragment_absolute_device_rect.x(), fragment_absolute_device_rect.y() + context.rounded_device_pixels(fragment.baseline()) }; - Vector scaled_glyph_run; - scaled_glyph_run.ensure_capacity(fragment.glyph_run().size()); - for (auto glyph : fragment.glyph_run()) { - 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()); - }); - scaled_glyph_run.append(move(glyph)); - } - painter.draw_text_run(baseline_start.to_type(), scaled_glyph_run, text_node.computed_values().color(), fragment_absolute_device_rect.to_type()); + auto scale = context.device_pixels_per_css_pixel(); + painter.draw_text_run(baseline_start.to_type(), fragment.glyph_run(), text_node.computed_values().color(), fragment_absolute_device_rect.to_type(), scale); auto selection_rect = context.enclosing_device_rect(fragment.selection_rect(text_node.first_available_font())).to_type(); if (!selection_rect.is_empty()) { painter.fill_rect(selection_rect, CSS::SystemColor::highlight()); RecordingPainterStateSaver saver(painter); painter.add_clip_rect(selection_rect); - painter.draw_text_run(baseline_start.to_type(), scaled_glyph_run, CSS::SystemColor::highlight_text(), fragment_absolute_device_rect.to_type()); + painter.draw_text_run(baseline_start.to_type(), fragment.glyph_run(), CSS::SystemColor::highlight_text(), fragment_absolute_device_rect.to_type(), scale); } paint_text_decoration(context, text_node, fragment); diff --git a/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp b/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp index a0757da515..dc57eedef3 100644 --- a/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp +++ b/Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp @@ -206,7 +206,7 @@ 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) +void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Span glyph_run, Color color, Gfx::IntRect const& rect, double scale) { auto transformed_baseline_start = state().translation.map(baseline_start).to_type(); append(DrawGlyphRun { @@ -214,6 +214,7 @@ void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Span glyph_run, Color color, Gfx::IntRect const& rect); + void draw_text_run(Gfx::IntPoint baseline_start, Span glyph_run, Color color, Gfx::IntRect const& rect, double scale); void add_clip_rect(Gfx::IntRect const& rect);