LibWeb: Use glyph run to store text paint command in RecordingPainter

Representing a text run panting command as a vector of glyphs, rather
than as a string simplifies collecting of unique glyphs which is a
prerequisite for `prepare_glyphs_texture()` call.
This commit is contained in:
Aliaksandr Kalenik 2023-11-05 00:43:50 +01:00 committed by Andreas Kling
parent 32ea11d45c
commit ee28ba0c93
6 changed files with 23 additions and 17 deletions

View file

@ -20,10 +20,18 @@ PaintingCommandExecutorCPU::PaintingCommandExecutorCPU(Gfx::Bitmap& bitmap)
stacking_contexts.append({ Gfx::Painter(bitmap), {}, 1.0f });
}
CommandResult PaintingCommandExecutorCPU::draw_text_run(Color const& color, Gfx::IntPoint const& baseline_start, String const& string, Gfx::Font const& font)
CommandResult PaintingCommandExecutorCPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color)
{
auto& painter = this->painter();
painter.draw_text_run(baseline_start, Utf8View(string), font, color);
for (auto& glyph_or_emoji : glyph_run) {
if (glyph_or_emoji.has<Gfx::DrawGlyph>()) {
auto& glyph = glyph_or_emoji.get<Gfx::DrawGlyph>();
painter.draw_glyph(glyph.position, glyph.code_point, *glyph.font, color);
} else {
auto& emoji = glyph_or_emoji.get<Gfx::DrawEmoji>();
painter.draw_emoji(emoji.position, *emoji.emoji, *emoji.font);
}
}
return CommandResult::Continue;
}

View file

@ -12,7 +12,7 @@ namespace Web::Painting {
class PaintingCommandExecutorCPU : public PaintingCommandExecutor {
public:
CommandResult draw_text_run(Color const&, Gfx::IntPoint const& baseline_start, String const& string, Gfx::Font const& font) override;
CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color 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 draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, float opacity, Gfx::Painter::ScalingMode scaling_mode) override;

View file

@ -18,7 +18,7 @@ PaintingCommandExecutorGPU::~PaintingCommandExecutorGPU()
m_painter.flush();
}
CommandResult PaintingCommandExecutorGPU::draw_text_run(Color const&, Gfx::IntPoint const&, String const&, Gfx::Font const&)
CommandResult PaintingCommandExecutorGPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const&, Color const&)
{
// FIXME
return CommandResult::Continue;

View file

@ -14,7 +14,7 @@ namespace Web::Painting {
class PaintingCommandExecutorGPU : public PaintingCommandExecutor {
public:
CommandResult draw_text_run(Color const&, Gfx::IntPoint const& baseline_start, String const& string, Gfx::Font const& font) override;
CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color 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 draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, float opacity, Gfx::Painter::ScalingMode scaling_mode) override;

View file

@ -207,11 +207,10 @@ void RecordingPainter::draw_signed_distance_field(Gfx::IntRect const& dst_rect,
void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Utf8View string, Gfx::Font const& font, Color color, Gfx::IntRect const& rect)
{
push_command(DrawTextRun {
auto glyph_run = Gfx::get_glyph_run(state().translation.map(baseline_start).to_type<float>(), string, font);
push_command(DrawGlyphRun {
.glyph_run = glyph_run,
.color = color,
.baseline_start = state().translation.map(baseline_start),
.string = String::from_utf8(string.as_string()).release_value_but_fixme_should_propagate_errors(),
.font = font,
.rect = state().translation.map(rect),
});
}
@ -427,8 +426,8 @@ void RecordingPainter::execute(PaintingCommandExecutor& executor)
}
auto result = command.visit(
[&](DrawTextRun const& command) {
return executor.draw_text_run(command.color, command.baseline_start, command.string, command.font);
[&](DrawGlyphRun const& command) {
return executor.draw_glyph_run(command.glyph_run, command.color);
},
[&](DrawText const& command) {
return executor.draw_text(command.rect, command.raw_text, command.alignment, command.color, command.elision, command.wrapping, command.font);

View file

@ -25,6 +25,7 @@
#include <LibGfx/TextAlignment.h>
#include <LibGfx/TextDirection.h>
#include <LibGfx/TextElision.h>
#include <LibGfx/TextLayout.h>
#include <LibGfx/TextWrapping.h>
#include <LibWeb/Painting/BorderRadiiData.h>
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
@ -38,11 +39,9 @@ enum class CommandResult {
SkipStackingContext,
};
struct DrawTextRun {
struct DrawGlyphRun {
Vector<Gfx::DrawGlyphOrEmoji> glyph_run;
Color color;
Gfx::IntPoint baseline_start;
String string;
NonnullRefPtr<Gfx::Font> font;
Gfx::IntRect rect;
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
@ -304,7 +303,7 @@ struct BlitCornerClipping {
};
using PaintingCommand = Variant<
DrawTextRun,
DrawGlyphRun,
DrawText,
FillRect,
DrawScaledBitmap,
@ -342,7 +341,7 @@ class PaintingCommandExecutor {
public:
virtual ~PaintingCommandExecutor() = default;
virtual CommandResult draw_text_run(Color const&, Gfx::IntPoint const& baseline_start, String const&, Gfx::Font const&) = 0;
virtual CommandResult draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color 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 draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, float opacity, Gfx::Painter::ScalingMode scaling_mode) = 0;