mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-09 01:29:17 +00:00
LibWeb: Invalidate text-decoration-thickness as paint-only property
Fixes underinvalidation caused by resolving text-decoration-thickness during layout commit, while this property can be invalidated independently of layout.
This commit is contained in:
parent
61c1e4a855
commit
2e256d2eac
Notes:
github-actions[bot]
2025-03-16 21:26:18 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 2e256d2eac
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3968
4 changed files with 24 additions and 23 deletions
|
@ -363,17 +363,6 @@ void LayoutState::commit(Box& root)
|
||||||
|
|
||||||
for (auto* text_node : text_nodes) {
|
for (auto* text_node : text_nodes) {
|
||||||
text_node->add_paintable(text_node->create_paintable());
|
text_node->add_paintable(text_node->create_paintable());
|
||||||
auto* paintable = text_node->first_paintable();
|
|
||||||
auto const& font = text_node->first_available_font();
|
|
||||||
auto const glyph_height = CSSPixels::nearest_value_for(font.pixel_size());
|
|
||||||
auto const css_line_thickness = [&] {
|
|
||||||
auto computed_thickness = text_node->computed_values().text_decoration_thickness().resolved(*text_node, CSS::Length(1, CSS::Length::Type::Em).to_px(*text_node));
|
|
||||||
if (computed_thickness.is_auto())
|
|
||||||
return max(glyph_height.scaled(0.1), 1);
|
|
||||||
return computed_thickness.to_px(*text_node);
|
|
||||||
}();
|
|
||||||
auto& text_paintable = static_cast<Painting::TextPaintable&>(*paintable);
|
|
||||||
text_paintable.set_text_decoration_thickness(css_line_thickness);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build_paint_tree(root);
|
build_paint_tree(root);
|
||||||
|
|
|
@ -687,9 +687,7 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable
|
||||||
|
|
||||||
auto line_color = paintable.computed_values().text_decoration_color();
|
auto line_color = paintable.computed_values().text_decoration_color();
|
||||||
auto line_style = paintable.computed_values().text_decoration_style();
|
auto line_style = paintable.computed_values().text_decoration_style();
|
||||||
auto const& text_paintable = static_cast<TextPaintable const&>(fragment.paintable());
|
auto device_line_thickness = context.rounded_device_pixels(fragment.text_decoration_thickness());
|
||||||
auto device_line_thickness = context.rounded_device_pixels(text_paintable.text_decoration_thickness());
|
|
||||||
|
|
||||||
auto text_decoration_lines = paintable.computed_values().text_decoration_line();
|
auto text_decoration_lines = paintable.computed_values().text_decoration_line();
|
||||||
for (auto line : text_decoration_lines) {
|
for (auto line : text_decoration_lines) {
|
||||||
DevicePixelPoint line_start_point {};
|
DevicePixelPoint line_start_point {};
|
||||||
|
@ -1364,10 +1362,24 @@ void PaintableWithLines::resolve_paint_properties()
|
||||||
Base::resolve_paint_properties();
|
Base::resolve_paint_properties();
|
||||||
|
|
||||||
auto const& layout_node = this->layout_node();
|
auto const& layout_node = this->layout_node();
|
||||||
for (auto const& fragment : fragments()) {
|
for (auto& fragment : fragments()) {
|
||||||
auto const& text_shadow = fragment.m_layout_node->computed_values().text_shadow();
|
if (!fragment.m_layout_node->is_text_node())
|
||||||
|
continue;
|
||||||
|
auto const& text_node = static_cast<Layout::TextNode const&>(*fragment.m_layout_node);
|
||||||
|
|
||||||
|
auto const& font = fragment.m_layout_node->first_available_font();
|
||||||
|
auto const glyph_height = CSSPixels::nearest_value_for(font.pixel_size());
|
||||||
|
auto const css_line_thickness = [&] {
|
||||||
|
auto computed_thickness = text_node.computed_values().text_decoration_thickness().resolved(text_node, CSS::Length(1, CSS::Length::Type::Em).to_px(text_node));
|
||||||
|
if (computed_thickness.is_auto())
|
||||||
|
return max(glyph_height.scaled(0.1), 1);
|
||||||
|
return computed_thickness.to_px(*fragment.m_layout_node);
|
||||||
|
}();
|
||||||
|
fragment.set_text_decoration_thickness(css_line_thickness);
|
||||||
|
|
||||||
|
auto const& text_shadow = text_node.computed_values().text_shadow();
|
||||||
if (!text_shadow.is_empty()) {
|
if (!text_shadow.is_empty()) {
|
||||||
Vector<Painting::ShadowData> resolved_shadow_data;
|
Vector<ShadowData> resolved_shadow_data;
|
||||||
resolved_shadow_data.ensure_capacity(text_shadow.size());
|
resolved_shadow_data.ensure_capacity(text_shadow.size());
|
||||||
for (auto const& layer : text_shadow) {
|
for (auto const& layer : text_shadow) {
|
||||||
resolved_shadow_data.empend(
|
resolved_shadow_data.empend(
|
||||||
|
@ -1376,9 +1388,9 @@ void PaintableWithLines::resolve_paint_properties()
|
||||||
layer.offset_y.to_px(layout_node),
|
layer.offset_y.to_px(layout_node),
|
||||||
layer.blur_radius.to_px(layout_node),
|
layer.blur_radius.to_px(layout_node),
|
||||||
layer.spread_distance.to_px(layout_node),
|
layer.spread_distance.to_px(layout_node),
|
||||||
Painting::ShadowPlacement::Outer);
|
ShadowPlacement::Outer);
|
||||||
}
|
}
|
||||||
const_cast<Painting::PaintableFragment&>(fragment).set_shadows(move(resolved_shadow_data));
|
fragment.set_shadows(move(resolved_shadow_data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,9 @@ public:
|
||||||
|
|
||||||
StringView string_view() const;
|
StringView string_view() const;
|
||||||
|
|
||||||
|
CSSPixels text_decoration_thickness() const { return m_text_decoration_thickness; }
|
||||||
|
void set_text_decoration_thickness(CSSPixels thickness) { m_text_decoration_thickness = thickness; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GC::Ref<Layout::Node const> m_layout_node;
|
GC::Ref<Layout::Node const> m_layout_node;
|
||||||
CSSPixelPoint m_offset;
|
CSSPixelPoint m_offset;
|
||||||
|
@ -58,6 +61,7 @@ private:
|
||||||
RefPtr<Gfx::GlyphRun> m_glyph_run;
|
RefPtr<Gfx::GlyphRun> m_glyph_run;
|
||||||
CSS::WritingMode m_writing_mode;
|
CSS::WritingMode m_writing_mode;
|
||||||
Vector<ShadowData> m_shadows;
|
Vector<ShadowData> m_shadows;
|
||||||
|
CSSPixels m_text_decoration_thickness { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,6 @@ public:
|
||||||
virtual DispatchEventOfSameName handle_mouseup(Badge<EventHandler>, CSSPixelPoint, unsigned button, unsigned modifiers) override;
|
virtual DispatchEventOfSameName handle_mouseup(Badge<EventHandler>, CSSPixelPoint, unsigned button, unsigned modifiers) override;
|
||||||
virtual DispatchEventOfSameName handle_mousemove(Badge<EventHandler>, CSSPixelPoint, unsigned button, unsigned modifiers) override;
|
virtual DispatchEventOfSameName handle_mousemove(Badge<EventHandler>, CSSPixelPoint, unsigned button, unsigned modifiers) override;
|
||||||
|
|
||||||
void set_text_decoration_thickness(CSSPixels thickness) { m_text_decoration_thickness = thickness; }
|
|
||||||
CSSPixels text_decoration_thickness() const { return m_text_decoration_thickness; }
|
|
||||||
|
|
||||||
String const& text_for_rendering() const { return m_text_for_rendering; }
|
String const& text_for_rendering() const { return m_text_for_rendering; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -36,7 +33,6 @@ private:
|
||||||
TextPaintable(Layout::TextNode const&, String const& text_for_rendering);
|
TextPaintable(Layout::TextNode const&, String const& text_for_rendering);
|
||||||
|
|
||||||
String m_text_for_rendering;
|
String m_text_for_rendering;
|
||||||
CSSPixels m_text_decoration_thickness { 0 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue