mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:37:43 +00:00
LibWeb: Use the new Gfx::Painter::draw_text_run() API for drawing text
This avoids a bunch of unnecessary work in Painter which not only took time, but sometimes also led to alignment issues. draw_text_run() will draw the text where we tell it, and that's it.
This commit is contained in:
parent
dd940dfa85
commit
1c88536298
4 changed files with 16 additions and 9 deletions
|
@ -43,6 +43,10 @@ public:
|
||||||
const Gfx::FloatPoint& offset() const { return m_offset; }
|
const Gfx::FloatPoint& offset() const { return m_offset; }
|
||||||
void set_offset(const Gfx::FloatPoint& offset) { m_offset = offset; }
|
void set_offset(const Gfx::FloatPoint& offset) { m_offset = offset; }
|
||||||
|
|
||||||
|
// The baseline of a fragment is the number of pixels from the top to the text baseline.
|
||||||
|
void set_baseline(float y) { m_baseline = y; }
|
||||||
|
float baseline() const { return m_baseline; }
|
||||||
|
|
||||||
const Gfx::FloatSize& size() const { return m_size; }
|
const Gfx::FloatSize& size() const { return m_size; }
|
||||||
void set_width(float width) { m_size.set_width(width); }
|
void set_width(float width) { m_size.set_width(width); }
|
||||||
void set_height(float height) { m_size.set_height(height); }
|
void set_height(float height) { m_size.set_height(height); }
|
||||||
|
@ -75,6 +79,7 @@ private:
|
||||||
Gfx::FloatSize m_size;
|
Gfx::FloatSize m_size;
|
||||||
float m_border_box_top { 0 };
|
float m_border_box_top { 0 };
|
||||||
float m_border_box_bottom { 0 };
|
float m_border_box_bottom { 0 };
|
||||||
|
float m_baseline { 0 };
|
||||||
Type m_type { Type::Normal };
|
Type m_type { Type::Normal };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ void LineBuilder::update_last_line()
|
||||||
|
|
||||||
auto line_box_baseline = [&] {
|
auto line_box_baseline = [&] {
|
||||||
float line_box_baseline = 0;
|
float line_box_baseline = 0;
|
||||||
for (auto const& fragment : line_box.fragments()) {
|
for (auto& fragment : line_box.fragments()) {
|
||||||
auto baseline = fragment_baseline(fragment);
|
auto baseline = fragment_baseline(fragment);
|
||||||
if (fragment.height() < m_context.containing_block().line_height())
|
if (fragment.height() < m_context.containing_block().line_height())
|
||||||
baseline += (m_context.containing_block().line_height() - fragment.height()) / 2;
|
baseline += (m_context.containing_block().line_height() - fragment.height()) / 2;
|
||||||
|
@ -168,6 +168,9 @@ void LineBuilder::update_last_line()
|
||||||
if (auto length_percentage = fragment.layout_node().computed_values().vertical_align().template get_pointer<CSS::LengthPercentage>(); length_percentage && length_percentage->is_length())
|
if (auto length_percentage = fragment.layout_node().computed_values().vertical_align().template get_pointer<CSS::LengthPercentage>(); length_percentage && length_percentage->is_length())
|
||||||
baseline += length_percentage->length().to_px(fragment.layout_node());
|
baseline += length_percentage->length().to_px(fragment.layout_node());
|
||||||
|
|
||||||
|
// Store the baseline on the fragment. This is used when painting.
|
||||||
|
fragment.set_baseline(baseline);
|
||||||
|
|
||||||
line_box_baseline = max(line_box_baseline, baseline);
|
line_box_baseline = max(line_box_baseline, baseline);
|
||||||
}
|
}
|
||||||
return line_box_baseline;
|
return line_box_baseline;
|
||||||
|
|
|
@ -369,8 +369,6 @@ static void paint_text_fragment(PaintContext& context, Layout::TextNode const& t
|
||||||
if (phase == Painting::PaintPhase::Foreground) {
|
if (phase == Painting::PaintPhase::Foreground) {
|
||||||
auto fragment_absolute_rect = fragment.absolute_rect();
|
auto fragment_absolute_rect = fragment.absolute_rect();
|
||||||
|
|
||||||
painter.set_font(text_node.font());
|
|
||||||
|
|
||||||
if (text_node.document().inspected_node() == &text_node.dom_node())
|
if (text_node.document().inspected_node() == &text_node.dom_node())
|
||||||
context.painter().draw_rect(enclosing_int_rect(fragment_absolute_rect), Color::Magenta);
|
context.painter().draw_rect(enclosing_int_rect(fragment_absolute_rect), Color::Magenta);
|
||||||
|
|
||||||
|
@ -382,17 +380,17 @@ static void paint_text_fragment(PaintContext& context, Layout::TextNode const& t
|
||||||
if (text_transform == CSS::TextTransform::Lowercase)
|
if (text_transform == CSS::TextTransform::Lowercase)
|
||||||
text = text_node.text_for_rendering().to_lowercase();
|
text = text_node.text_for_rendering().to_lowercase();
|
||||||
|
|
||||||
// FIXME: This is a hack to prevent text clipping when painting a bitmap font into a too-small box.
|
Gfx::FloatPoint baseline_start { fragment_absolute_rect.x(), fragment_absolute_rect.y() + fragment.baseline() };
|
||||||
auto draw_rect = enclosing_int_rect(fragment_absolute_rect);
|
Utf8View view { text.substring_view(fragment.start(), fragment.length()) };
|
||||||
draw_rect.set_height(max(draw_rect.height(), text_node.font().pixel_size()));
|
|
||||||
painter.draw_text(draw_rect, text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, text_node.computed_values().color());
|
painter.draw_text_run(baseline_start, view, fragment.layout_node().font(), text_node.computed_values().color());
|
||||||
|
|
||||||
auto selection_rect = fragment.selection_rect(text_node.font());
|
auto selection_rect = fragment.selection_rect(text_node.font());
|
||||||
if (!selection_rect.is_empty()) {
|
if (!selection_rect.is_empty()) {
|
||||||
painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
|
painter.fill_rect(enclosing_int_rect(selection_rect), context.palette().selection());
|
||||||
Gfx::PainterStateSaver saver(painter);
|
Gfx::PainterStateSaver saver(painter);
|
||||||
painter.add_clip_rect(enclosing_int_rect(selection_rect));
|
painter.add_clip_rect(enclosing_int_rect(selection_rect));
|
||||||
painter.draw_text(enclosing_int_rect(fragment_absolute_rect), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, context.palette().selection_text());
|
painter.draw_text_run(baseline_start, view, fragment.layout_node().font(), context.palette().selection_text());
|
||||||
}
|
}
|
||||||
|
|
||||||
paint_text_decoration(painter, text_node, fragment);
|
paint_text_decoration(painter, text_node, fragment);
|
||||||
|
|
|
@ -159,7 +159,8 @@ void paint_text_shadow(PaintContext& context, Layout::LineBoxFragment const& fra
|
||||||
Gfx::Painter shadow_painter { *shadow_bitmap };
|
Gfx::Painter shadow_painter { *shadow_bitmap };
|
||||||
shadow_painter.set_font(context.painter().font());
|
shadow_painter.set_font(context.painter().font());
|
||||||
// FIXME: "Spread" the shadow somehow.
|
// FIXME: "Spread" the shadow somehow.
|
||||||
shadow_painter.draw_text(text_rect, fragment.text(), Gfx::TextAlignment::CenterLeft, layer.color);
|
Gfx::FloatPoint baseline_start(text_rect.x(), text_rect.y() + fragment.baseline());
|
||||||
|
shadow_painter.draw_text_run(baseline_start, Utf8View(fragment.text()), context.painter().font(), layer.color);
|
||||||
|
|
||||||
// Blur
|
// Blur
|
||||||
Gfx::FastBoxBlurFilter filter(*shadow_bitmap);
|
Gfx::FastBoxBlurFilter filter(*shadow_bitmap);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue