mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:27:44 +00:00
LibWeb: Remove glyph run allocation in RecordingPainter::draw_text_run
Instead of allocating a new glyph run solely to shift each glyph by the painter's offset, this offset could be encoded in a paint command and applied later during command execution.
This commit is contained in:
parent
79fd8eb28d
commit
aeb5a0d9e8
8 changed files with 21 additions and 16 deletions
|
@ -41,6 +41,7 @@ struct DrawGlyphRun {
|
||||||
Vector<Gfx::DrawGlyphOrEmoji> glyph_run;
|
Vector<Gfx::DrawGlyphOrEmoji> glyph_run;
|
||||||
Color color;
|
Color color;
|
||||||
Gfx::IntRect rect;
|
Gfx::IntRect rect;
|
||||||
|
Gfx::FloatPoint translation;
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,17 @@ CommandExecutorCPU::CommandExecutorCPU(Gfx::Bitmap& bitmap)
|
||||||
.scaling_mode = {} });
|
.scaling_mode = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandResult CommandExecutorCPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color)
|
CommandResult CommandExecutorCPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color, Gfx::FloatPoint translation)
|
||||||
{
|
{
|
||||||
auto& painter = this->painter();
|
auto& painter = this->painter();
|
||||||
for (auto& glyph_or_emoji : glyph_run) {
|
for (auto& glyph_or_emoji : glyph_run) {
|
||||||
|
auto transformed_glyph = glyph_or_emoji;
|
||||||
|
transformed_glyph.visit([&](auto& glyph) { glyph.position.translate_by(translation); });
|
||||||
if (glyph_or_emoji.has<Gfx::DrawGlyph>()) {
|
if (glyph_or_emoji.has<Gfx::DrawGlyph>()) {
|
||||||
auto& glyph = glyph_or_emoji.get<Gfx::DrawGlyph>();
|
auto& glyph = transformed_glyph.get<Gfx::DrawGlyph>();
|
||||||
painter.draw_glyph(glyph.position, glyph.code_point, *glyph.font, color);
|
painter.draw_glyph(glyph.position, glyph.code_point, *glyph.font, color);
|
||||||
} else {
|
} else {
|
||||||
auto& emoji = glyph_or_emoji.get<Gfx::DrawEmoji>();
|
auto& emoji = transformed_glyph.get<Gfx::DrawEmoji>();
|
||||||
painter.draw_emoji(emoji.position.to_type<int>(), *emoji.emoji, *emoji.font);
|
painter.draw_emoji(emoji.position.to_type<int>(), *emoji.emoji, *emoji.font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Web::Painting {
|
||||||
|
|
||||||
class CommandExecutorCPU : public CommandExecutor {
|
class CommandExecutorCPU : public CommandExecutor {
|
||||||
public:
|
public:
|
||||||
CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&) override;
|
CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&, Gfx::FloatPoint translation) override;
|
||||||
CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) override;
|
CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) override;
|
||||||
CommandResult fill_rect(Gfx::IntRect const& rect, Color 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;
|
CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) override;
|
||||||
|
|
|
@ -31,9 +31,16 @@ CommandExecutorGPU::~CommandExecutorGPU()
|
||||||
painter().flush(m_target_bitmap);
|
painter().flush(m_target_bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandResult CommandExecutorGPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color)
|
CommandResult CommandExecutorGPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color, Gfx::FloatPoint translation)
|
||||||
{
|
{
|
||||||
painter().draw_glyph_run(glyph_run, color);
|
Vector<Gfx::DrawGlyphOrEmoji> 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_run.append(transformed_glyph);
|
||||||
|
}
|
||||||
|
painter().draw_glyph_run(transformed_glyph_run, color);
|
||||||
return CommandResult::Continue;
|
return CommandResult::Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Web::Painting {
|
||||||
|
|
||||||
class CommandExecutorGPU : public CommandExecutor {
|
class CommandExecutorGPU : public CommandExecutor {
|
||||||
public:
|
public:
|
||||||
CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&) override;
|
CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&, Gfx::FloatPoint translation) override;
|
||||||
CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) override;
|
CommandResult draw_text(Gfx::IntRect const& rect, String const& raw_text, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) override;
|
||||||
CommandResult fill_rect(Gfx::IntRect const& rect, Color 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;
|
CommandResult draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode) override;
|
||||||
|
|
|
@ -87,7 +87,7 @@ void CommandList::execute(CommandExecutor& executor)
|
||||||
|
|
||||||
auto result = command.visit(
|
auto result = command.visit(
|
||||||
[&](DrawGlyphRun const& command) {
|
[&](DrawGlyphRun const& command) {
|
||||||
return executor.draw_glyph_run(command.glyph_run, command.color);
|
return executor.draw_glyph_run(command.glyph_run, command.color, command.translation);
|
||||||
},
|
},
|
||||||
[&](DrawText const& command) {
|
[&](DrawText const& command) {
|
||||||
return executor.draw_text(command.rect, command.raw_text, command.alignment, command.color,
|
return executor.draw_text(command.rect, command.raw_text, command.alignment, command.color,
|
||||||
|
|
|
@ -47,7 +47,7 @@ class CommandExecutor {
|
||||||
public:
|
public:
|
||||||
virtual ~CommandExecutor() = default;
|
virtual ~CommandExecutor() = default;
|
||||||
|
|
||||||
virtual CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&) = 0;
|
virtual CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const&, Gfx::FloatPoint translation) = 0;
|
||||||
virtual CommandResult draw_text(Gfx::IntRect const&, String const&, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) = 0;
|
virtual CommandResult draw_text(Gfx::IntRect const&, String const&, Gfx::TextAlignment alignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&) = 0;
|
||||||
virtual CommandResult fill_rect(Gfx::IntRect const&, Color 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;
|
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;
|
||||||
|
|
|
@ -209,16 +209,11 @@ void RecordingPainter::draw_signed_distance_field(Gfx::IntRect const& dst_rect,
|
||||||
void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Span<Gfx::DrawGlyphOrEmoji const> glyph_run, Color color, Gfx::IntRect const& rect)
|
void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Span<Gfx::DrawGlyphOrEmoji const> glyph_run, Color color, Gfx::IntRect const& rect)
|
||||||
{
|
{
|
||||||
auto transformed_baseline_start = state().translation.map(baseline_start).to_type<float>();
|
auto transformed_baseline_start = state().translation.map(baseline_start).to_type<float>();
|
||||||
Vector<Gfx::DrawGlyphOrEmoji> translated_glyph_run;
|
|
||||||
translated_glyph_run.ensure_capacity(glyph_run.size());
|
|
||||||
for (auto glyph : glyph_run) {
|
|
||||||
glyph.visit([&](auto& glyph) { glyph.position.translate_by(transformed_baseline_start); });
|
|
||||||
translated_glyph_run.append(glyph);
|
|
||||||
}
|
|
||||||
append(DrawGlyphRun {
|
append(DrawGlyphRun {
|
||||||
.glyph_run = move(translated_glyph_run),
|
.glyph_run = Vector<Gfx::DrawGlyphOrEmoji> { glyph_run },
|
||||||
.color = color,
|
.color = color,
|
||||||
.rect = state().translation.map(rect),
|
.rect = state().translation.map(rect),
|
||||||
|
.translation = transformed_baseline_start,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue