mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-15 23:09:05 +00:00
LibWeb: Fix "background-clip: text" for elements nested in scrollable
Instead of carrying the display list for a mask in each command that might potentially be affected by "background-clip: text", this change introduces a new AddMask command that is applied once for all background layers within one box. The new AddMask command includes a rectangle for the mask destination that is translated by the corresponding scroll offset. Fixes https://github.com/LadybirdBrowser/ladybird/issues/857
This commit is contained in:
parent
861d46be3e
commit
a8f4ea5226
Notes:
github-actions[bot]
2024-08-06 19:15:33 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: a8f4ea5226
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/988
19 changed files with 135 additions and 97 deletions
30
Tests/LibWeb/Ref/background-clip-text-inside-scrollable.html
Normal file
30
Tests/LibWeb/Ref/background-clip-text-inside-scrollable.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="match" href="reference/background-clip-text-inside-scrollable-ref.html" />
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text {
|
||||||
|
background: linear-gradient(#6d98cc, #8a64e5);
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
font-size: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#scrollable {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
border: 1px solid black;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="scrollable">
|
||||||
|
<div style="height: 200px"></div>
|
||||||
|
Clip<span id="text">Text</span>
|
||||||
|
<div style="height: 600px"></div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
const scrollContainer = document.getElementById("scrollable");
|
||||||
|
scrollContainer.scrollTop = 200;
|
||||||
|
</script>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text {
|
||||||
|
background: linear-gradient(#6d98cc, #8a64e5);
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
font-size: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#scrollable {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
border: 1px solid black;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="scrollable">
|
||||||
|
Clip<span id="text">Text</span>
|
||||||
|
</div>
|
|
@ -36,7 +36,7 @@ public:
|
||||||
virtual void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const {};
|
virtual void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const {};
|
||||||
|
|
||||||
virtual bool is_paintable() const = 0;
|
virtual bool is_paintable() const = 0;
|
||||||
virtual void paint(PaintContext& context, DevicePixelRect const& dest_rect, ImageRendering, RefPtr<Painting::DisplayList> text_clip = {}) const = 0;
|
virtual void paint(PaintContext& context, DevicePixelRect const& dest_rect, ImageRendering) const = 0;
|
||||||
|
|
||||||
virtual Optional<Gfx::Color> color_if_single_pixel_bitmap() const { return {}; }
|
virtual Optional<Gfx::Color> color_if_single_pixel_bitmap() const { return {}; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,12 +42,12 @@ void ConicGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModelM
|
||||||
m_resolved->position = m_properties.position->resolved(node, CSSPixelRect { { 0, 0 }, size });
|
m_resolved->position = m_properties.position->resolved(node, CSSPixelRect { { 0, 0 }, size });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConicGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering, RefPtr<Painting::DisplayList> text_clip) const
|
void ConicGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering) const
|
||||||
{
|
{
|
||||||
VERIFY(m_resolved.has_value());
|
VERIFY(m_resolved.has_value());
|
||||||
auto destination_rect = dest_rect.to_type<int>();
|
auto destination_rect = dest_rect.to_type<int>();
|
||||||
auto position = context.rounded_device_point(m_resolved->position).to_type<int>();
|
auto position = context.rounded_device_point(m_resolved->position).to_type<int>();
|
||||||
context.display_list_recorder().fill_rect_with_conic_gradient(destination_rect, m_resolved->data, position, text_clip);
|
context.display_list_recorder().fill_rect_with_conic_gradient(destination_rect, m_resolved->data, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConicGradientStyleValue::equals(StyleValue const& other) const
|
bool ConicGradientStyleValue::equals(StyleValue const& other) const
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
|
|
||||||
virtual String to_string() const override;
|
virtual String to_string() const override;
|
||||||
|
|
||||||
void paint(PaintContext&, DevicePixelRect const& dest_rect, CSS::ImageRendering, RefPtr<Painting::DisplayList> text_clip = {}) const override;
|
void paint(PaintContext&, DevicePixelRect const& dest_rect, CSS::ImageRendering) const override;
|
||||||
|
|
||||||
virtual bool equals(StyleValue const& other) const override;
|
virtual bool equals(StyleValue const& other) const override;
|
||||||
|
|
||||||
|
|
|
@ -137,11 +137,11 @@ Optional<CSSPixelFraction> ImageStyleValue::natural_aspect_ratio() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering, RefPtr<Painting::DisplayList> text_clip) const
|
void ImageStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering) const
|
||||||
{
|
{
|
||||||
if (auto const* b = bitmap(m_current_frame_index, dest_rect.size().to_type<int>()); b != nullptr) {
|
if (auto const* b = bitmap(m_current_frame_index, dest_rect.size().to_type<int>()); b != nullptr) {
|
||||||
auto scaling_mode = to_gfx_scaling_mode(image_rendering, b->rect(), dest_rect.to_type<int>());
|
auto scaling_mode = to_gfx_scaling_mode(image_rendering, b->rect(), dest_rect.to_type<int>());
|
||||||
context.display_list_recorder().draw_scaled_immutable_bitmap(dest_rect.to_type<int>(), *b, b->rect(), scaling_mode, text_clip);
|
context.display_list_recorder().draw_scaled_immutable_bitmap(dest_rect.to_type<int>(), *b, b->rect(), scaling_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
Optional<CSSPixelFraction> natural_aspect_ratio() const override;
|
Optional<CSSPixelFraction> natural_aspect_ratio() const override;
|
||||||
|
|
||||||
virtual bool is_paintable() const override;
|
virtual bool is_paintable() const override;
|
||||||
void paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering, RefPtr<Painting::DisplayList> clip_paths = {}) const override;
|
void paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering) const override;
|
||||||
|
|
||||||
virtual Optional<Gfx::Color> color_if_single_pixel_bitmap() const override;
|
virtual Optional<Gfx::Color> color_if_single_pixel_bitmap() const override;
|
||||||
Gfx::ImmutableBitmap const* current_frame_bitmap(DevicePixelRect const& dest_rect) const;
|
Gfx::ImmutableBitmap const* current_frame_bitmap(DevicePixelRect const& dest_rect) const;
|
||||||
|
|
|
@ -109,10 +109,10 @@ void LinearGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModel
|
||||||
m_resolved = ResolvedData { Painting::resolve_linear_gradient_data(node, size, *this), size };
|
m_resolved = ResolvedData { Painting::resolve_linear_gradient_data(node, size, *this), size };
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinearGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering, RefPtr<Painting::DisplayList> text_clip) const
|
void LinearGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering) const
|
||||||
{
|
{
|
||||||
VERIFY(m_resolved.has_value());
|
VERIFY(m_resolved.has_value());
|
||||||
context.display_list_recorder().fill_rect_with_linear_gradient(dest_rect.to_type<int>(), m_resolved->data, text_clip);
|
context.display_list_recorder().fill_rect_with_linear_gradient(dest_rect.to_type<int>(), m_resolved->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const override;
|
void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const override;
|
||||||
|
|
||||||
bool is_paintable() const override { return true; }
|
bool is_paintable() const override { return true; }
|
||||||
void paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering, RefPtr<Painting::DisplayList> text_clip = {}) const override;
|
void paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LinearGradientStyleValue(GradientDirection direction, Vector<LinearColorStopListElement> color_stop_list, GradientType type, GradientRepeating repeating)
|
LinearGradientStyleValue(GradientDirection direction, Vector<LinearColorStopListElement> color_stop_list, GradientType type, GradientRepeating repeating)
|
||||||
|
|
|
@ -207,12 +207,12 @@ bool RadialGradientStyleValue::equals(StyleValue const& other) const
|
||||||
return m_properties == other_gradient.m_properties;
|
return m_properties == other_gradient.m_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering, RefPtr<Painting::DisplayList> text_clip) const
|
void RadialGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering) const
|
||||||
{
|
{
|
||||||
VERIFY(m_resolved.has_value());
|
VERIFY(m_resolved.has_value());
|
||||||
auto center = context.rounded_device_point(m_resolved->center).to_type<int>();
|
auto center = context.rounded_device_point(m_resolved->center).to_type<int>();
|
||||||
auto size = context.rounded_device_size(m_resolved->gradient_size).to_type<int>();
|
auto size = context.rounded_device_size(m_resolved->gradient_size).to_type<int>();
|
||||||
context.display_list_recorder().fill_rect_with_radial_gradient(dest_rect.to_type<int>(), m_resolved->data, center, size, text_clip);
|
context.display_list_recorder().fill_rect_with_radial_gradient(dest_rect.to_type<int>(), m_resolved->data, center, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
|
|
||||||
virtual String to_string() const override;
|
virtual String to_string() const override;
|
||||||
|
|
||||||
void paint(PaintContext&, DevicePixelRect const& dest_rect, CSS::ImageRendering, RefPtr<Painting::DisplayList> text_clip = {}) const override;
|
void paint(PaintContext&, DevicePixelRect const& dest_rect, CSS::ImageRendering) const override;
|
||||||
|
|
||||||
virtual bool equals(StyleValue const& other) const override;
|
virtual bool equals(StyleValue const& other) const override;
|
||||||
|
|
||||||
|
|
|
@ -56,10 +56,12 @@ static CSSPixelSize run_default_sizing_algorithm(
|
||||||
return default_size;
|
return default_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<DisplayList> compute_text_clip_paths(PaintContext& context, Paintable const& paintable)
|
static RefPtr<DisplayList> compute_text_clip_paths(PaintContext& context, Paintable const& paintable, CSSPixelPoint containing_block_location)
|
||||||
{
|
{
|
||||||
auto text_clip_paths = DisplayList::create();
|
auto text_clip_paths = DisplayList::create();
|
||||||
DisplayListRecorder display_list_recorder(*text_clip_paths);
|
DisplayListRecorder display_list_recorder(*text_clip_paths);
|
||||||
|
// Remove containing block offset, so executing the display list will produce mask at (0, 0)
|
||||||
|
display_list_recorder.translate(-context.floored_device_point(containing_block_location).to_type<int>());
|
||||||
auto add_text_clip_path = [&](PaintableFragment const& fragment) {
|
auto add_text_clip_path = [&](PaintableFragment const& fragment) {
|
||||||
auto glyph_run = fragment.glyph_run();
|
auto glyph_run = fragment.glyph_run();
|
||||||
if (!glyph_run || glyph_run->glyphs().is_empty())
|
if (!glyph_run || glyph_run->glyphs().is_empty())
|
||||||
|
@ -116,13 +118,15 @@ static BackgroundBox get_box(CSS::BackgroundBox box_clip, BackgroundBox border_b
|
||||||
// https://www.w3.org/TR/css-backgrounds-3/#backgrounds
|
// https://www.w3.org/TR/css-backgrounds-3/#backgrounds
|
||||||
void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMetrics const& layout_node, CSS::ImageRendering image_rendering, ResolvedBackground resolved_background, BorderRadiiData const& border_radii)
|
void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMetrics const& layout_node, CSS::ImageRendering image_rendering, ResolvedBackground resolved_background, BorderRadiiData const& border_radii)
|
||||||
{
|
{
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
if (resolved_background.needs_text_clip) {
|
|
||||||
text_clip = compute_text_clip_paths(context, *layout_node.paintable());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& display_list_recorder = context.display_list_recorder();
|
auto& display_list_recorder = context.display_list_recorder();
|
||||||
|
|
||||||
|
DisplayListRecorderStateSaver state { display_list_recorder };
|
||||||
|
if (resolved_background.needs_text_clip) {
|
||||||
|
auto display_list = compute_text_clip_paths(context, *layout_node.paintable(), resolved_background.background_rect.location());
|
||||||
|
auto rect = context.rounded_device_rect(resolved_background.background_rect);
|
||||||
|
display_list_recorder.add_mask(move(display_list), rect.to_type<int>());
|
||||||
|
}
|
||||||
|
|
||||||
BackgroundBox border_box {
|
BackgroundBox border_box {
|
||||||
resolved_background.background_rect,
|
resolved_background.background_rect,
|
||||||
border_radii
|
border_radii
|
||||||
|
@ -136,8 +140,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
||||||
color_box.radii.top_left.as_corner(context),
|
color_box.radii.top_left.as_corner(context),
|
||||||
color_box.radii.top_right.as_corner(context),
|
color_box.radii.top_right.as_corner(context),
|
||||||
color_box.radii.bottom_right.as_corner(context),
|
color_box.radii.bottom_right.as_corner(context),
|
||||||
color_box.radii.bottom_left.as_corner(context),
|
color_box.radii.bottom_left.as_corner(context));
|
||||||
text_clip);
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
DevicePixels top { 0 };
|
DevicePixels top { 0 };
|
||||||
|
@ -332,17 +335,17 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
||||||
fill_rect = fill_rect->united(image_device_rect);
|
fill_rect = fill_rect->united(image_device_rect);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
display_list_recorder.fill_rect(fill_rect->to_type<int>(), color.value(), text_clip);
|
display_list_recorder.fill_rect(fill_rect->to_type<int>(), color.value());
|
||||||
} else if (is<CSS::ImageStyleValue>(image) && repeat_x && repeat_y && !repeat_x_has_gap && !repeat_y_has_gap) {
|
} else if (is<CSS::ImageStyleValue>(image) && repeat_x && repeat_y && !repeat_x_has_gap && !repeat_y_has_gap) {
|
||||||
// Use a dedicated painting command for repeated images instead of recording a separate command for each instance
|
// Use a dedicated painting command for repeated images instead of recording a separate command for each instance
|
||||||
// of a repeated background, so the painter has the opportunity to optimize the painting of repeated images.
|
// of a repeated background, so the painter has the opportunity to optimize the painting of repeated images.
|
||||||
auto dest_rect = context.rounded_device_rect(image_rect);
|
auto dest_rect = context.rounded_device_rect(image_rect);
|
||||||
auto const* bitmap = static_cast<CSS::ImageStyleValue const&>(image).current_frame_bitmap(dest_rect);
|
auto const* bitmap = static_cast<CSS::ImageStyleValue const&>(image).current_frame_bitmap(dest_rect);
|
||||||
auto scaling_mode = to_gfx_scaling_mode(image_rendering, bitmap->rect(), dest_rect.to_type<int>());
|
auto scaling_mode = to_gfx_scaling_mode(image_rendering, bitmap->rect(), dest_rect.to_type<int>());
|
||||||
context.display_list_recorder().draw_repeated_immutable_bitmap(dest_rect.to_type<int>(), clip_rect.to_type<int>(), *bitmap, scaling_mode, { .x = repeat_x, .y = repeat_y }, text_clip);
|
context.display_list_recorder().draw_repeated_immutable_bitmap(dest_rect.to_type<int>(), clip_rect.to_type<int>(), *bitmap, scaling_mode, { .x = repeat_x, .y = repeat_y });
|
||||||
} else {
|
} else {
|
||||||
for_each_image_device_rect([&](auto const& image_device_rect) {
|
for_each_image_device_rect([&](auto const& image_device_rect) {
|
||||||
image.paint(context, image_device_rect, image_rendering, text_clip);
|
image.paint(context, image_device_rect, image_rendering);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,6 @@ struct DrawGlyphRun {
|
||||||
struct FillRect {
|
struct FillRect {
|
||||||
Gfx::IntRect rect;
|
Gfx::IntRect rect;
|
||||||
Color color;
|
Color color;
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||||
|
@ -71,7 +70,6 @@ struct DrawScaledImmutableBitmap {
|
||||||
NonnullRefPtr<Gfx::ImmutableBitmap> bitmap;
|
NonnullRefPtr<Gfx::ImmutableBitmap> bitmap;
|
||||||
Gfx::IntRect src_rect;
|
Gfx::IntRect src_rect;
|
||||||
Gfx::ScalingMode scaling_mode;
|
Gfx::ScalingMode scaling_mode;
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return dst_rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return dst_rect; }
|
||||||
void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
|
void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
|
||||||
|
@ -88,7 +86,6 @@ struct DrawRepeatedImmutableBitmap {
|
||||||
NonnullRefPtr<Gfx::ImmutableBitmap> bitmap;
|
NonnullRefPtr<Gfx::ImmutableBitmap> bitmap;
|
||||||
Gfx::ScalingMode scaling_mode;
|
Gfx::ScalingMode scaling_mode;
|
||||||
Repeat repeat;
|
Repeat repeat;
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
|
|
||||||
void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
|
void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
|
||||||
};
|
};
|
||||||
|
@ -133,7 +130,6 @@ struct PopStackingContext { };
|
||||||
struct PaintLinearGradient {
|
struct PaintLinearGradient {
|
||||||
Gfx::IntRect gradient_rect;
|
Gfx::IntRect gradient_rect;
|
||||||
LinearGradientData linear_gradient_data;
|
LinearGradientData linear_gradient_data;
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return gradient_rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return gradient_rect; }
|
||||||
|
|
||||||
|
@ -174,7 +170,6 @@ struct FillRectWithRoundedCorners {
|
||||||
Gfx::IntRect rect;
|
Gfx::IntRect rect;
|
||||||
Color color;
|
Color color;
|
||||||
CornerRadii corner_radii;
|
CornerRadii corner_radii;
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||||
|
@ -314,7 +309,6 @@ struct PaintRadialGradient {
|
||||||
RadialGradientData radial_gradient_data;
|
RadialGradientData radial_gradient_data;
|
||||||
Gfx::IntPoint center;
|
Gfx::IntPoint center;
|
||||||
Gfx::IntSize size;
|
Gfx::IntSize size;
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||||
|
|
||||||
|
@ -325,7 +319,6 @@ struct PaintConicGradient {
|
||||||
Gfx::IntRect rect;
|
Gfx::IntRect rect;
|
||||||
ConicGradientData conic_gradient_data;
|
ConicGradientData conic_gradient_data;
|
||||||
Gfx::IntPoint position;
|
Gfx::IntPoint position;
|
||||||
RefPtr<DisplayList> text_clip;
|
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||||
|
|
||||||
|
@ -356,6 +349,16 @@ struct AddRoundedRectClip {
|
||||||
void translate_by(Gfx::IntPoint const& offset) { border_rect.translate_by(offset); }
|
void translate_by(Gfx::IntPoint const& offset) { border_rect.translate_by(offset); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AddMask {
|
||||||
|
RefPtr<DisplayList> display_list;
|
||||||
|
Gfx::IntRect rect;
|
||||||
|
|
||||||
|
void translate_by(Gfx::IntPoint const& offset)
|
||||||
|
{
|
||||||
|
rect.translate_by(offset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
using Command = Variant<
|
using Command = Variant<
|
||||||
DrawGlyphRun,
|
DrawGlyphRun,
|
||||||
FillRect,
|
FillRect,
|
||||||
|
@ -384,6 +387,7 @@ using Command = Variant<
|
||||||
ApplyBackdropFilter,
|
ApplyBackdropFilter,
|
||||||
DrawRect,
|
DrawRect,
|
||||||
DrawTriangleWave,
|
DrawTriangleWave,
|
||||||
AddRoundedRectClip>;
|
AddRoundedRectClip,
|
||||||
|
AddMask>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ void DisplayListPlayer::execute(DisplayList& display_list)
|
||||||
else HANDLE_COMMAND(DrawRect, draw_rect)
|
else HANDLE_COMMAND(DrawRect, draw_rect)
|
||||||
else HANDLE_COMMAND(DrawTriangleWave, draw_triangle_wave)
|
else HANDLE_COMMAND(DrawTriangleWave, draw_triangle_wave)
|
||||||
else HANDLE_COMMAND(AddRoundedRectClip, add_rounded_rect_clip)
|
else HANDLE_COMMAND(AddRoundedRectClip, add_rounded_rect_clip)
|
||||||
|
else HANDLE_COMMAND(AddMask, add_mask)
|
||||||
else VERIFY_NOT_REACHED();
|
else VERIFY_NOT_REACHED();
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ private:
|
||||||
virtual void draw_rect(DrawRect const&) = 0;
|
virtual void draw_rect(DrawRect const&) = 0;
|
||||||
virtual void draw_triangle_wave(DrawTriangleWave const&) = 0;
|
virtual void draw_triangle_wave(DrawTriangleWave const&) = 0;
|
||||||
virtual void add_rounded_rect_clip(AddRoundedRectClip const&) = 0;
|
virtual void add_rounded_rect_clip(AddRoundedRectClip const&) = 0;
|
||||||
|
virtual void add_mask(AddMask const&) = 0;
|
||||||
virtual bool would_be_fully_clipped_by_painter(Gfx::IntRect) const = 0;
|
virtual bool would_be_fully_clipped_by_painter(Gfx::IntRect) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -374,15 +374,6 @@ static SkSamplingOptions to_skia_sampling_options(Gfx::ScalingMode scaling_mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define APPLY_TEXT_CLIP_IF_NEEDED(MASK_RECT) \
|
|
||||||
ScopeGuard const restore { [&] { \
|
|
||||||
if (command.text_clip) \
|
|
||||||
surface().canvas().restore(); \
|
|
||||||
} }; \
|
|
||||||
if (command.text_clip) { \
|
|
||||||
apply_mask_painted_from(*command.text_clip, MASK_RECT); \
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayListPlayerSkia::SkiaSurface& DisplayListPlayerSkia::surface() const
|
DisplayListPlayerSkia::SkiaSurface& DisplayListPlayerSkia::surface() const
|
||||||
{
|
{
|
||||||
return static_cast<SkiaSurface&>(*m_surface);
|
return static_cast<SkiaSurface&>(*m_surface);
|
||||||
|
@ -422,8 +413,6 @@ void DisplayListPlayerSkia::draw_glyph_run(DrawGlyphRun const& command)
|
||||||
|
|
||||||
void DisplayListPlayerSkia::fill_rect(FillRect const& command)
|
void DisplayListPlayerSkia::fill_rect(FillRect const& command)
|
||||||
{
|
{
|
||||||
APPLY_TEXT_CLIP_IF_NEEDED(command.rect)
|
|
||||||
|
|
||||||
auto const& rect = command.rect;
|
auto const& rect = command.rect;
|
||||||
auto& canvas = surface().canvas();
|
auto& canvas = surface().canvas();
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
|
@ -444,8 +433,6 @@ void DisplayListPlayerSkia::draw_scaled_bitmap(DrawScaledBitmap const& command)
|
||||||
|
|
||||||
void DisplayListPlayerSkia::draw_scaled_immutable_bitmap(DrawScaledImmutableBitmap const& command)
|
void DisplayListPlayerSkia::draw_scaled_immutable_bitmap(DrawScaledImmutableBitmap const& command)
|
||||||
{
|
{
|
||||||
APPLY_TEXT_CLIP_IF_NEEDED(command.dst_rect)
|
|
||||||
|
|
||||||
auto src_rect = to_skia_rect(command.src_rect);
|
auto src_rect = to_skia_rect(command.src_rect);
|
||||||
auto dst_rect = to_skia_rect(command.dst_rect);
|
auto dst_rect = to_skia_rect(command.dst_rect);
|
||||||
auto bitmap = to_skia_bitmap(command.bitmap->bitmap());
|
auto bitmap = to_skia_bitmap(command.bitmap->bitmap());
|
||||||
|
@ -457,8 +444,6 @@ void DisplayListPlayerSkia::draw_scaled_immutable_bitmap(DrawScaledImmutableBitm
|
||||||
|
|
||||||
void DisplayListPlayerSkia::draw_repeated_immutable_bitmap(DrawRepeatedImmutableBitmap const& command)
|
void DisplayListPlayerSkia::draw_repeated_immutable_bitmap(DrawRepeatedImmutableBitmap const& command)
|
||||||
{
|
{
|
||||||
APPLY_TEXT_CLIP_IF_NEEDED(command.clip_rect)
|
|
||||||
|
|
||||||
auto bitmap = to_skia_bitmap(command.bitmap->bitmap());
|
auto bitmap = to_skia_bitmap(command.bitmap->bitmap());
|
||||||
auto image = SkImages::RasterFromBitmap(bitmap);
|
auto image = SkImages::RasterFromBitmap(bitmap);
|
||||||
|
|
||||||
|
@ -655,8 +640,6 @@ static ColorStopList expand_repeat_length(ColorStopList const& color_stop_list,
|
||||||
|
|
||||||
void DisplayListPlayerSkia::paint_linear_gradient(PaintLinearGradient const& command)
|
void DisplayListPlayerSkia::paint_linear_gradient(PaintLinearGradient const& command)
|
||||||
{
|
{
|
||||||
APPLY_TEXT_CLIP_IF_NEEDED(command.gradient_rect)
|
|
||||||
|
|
||||||
auto const& linear_gradient_data = command.linear_gradient_data;
|
auto const& linear_gradient_data = command.linear_gradient_data;
|
||||||
auto color_stop_list = linear_gradient_data.color_stops.list;
|
auto color_stop_list = linear_gradient_data.color_stops.list;
|
||||||
auto const& repeat_length = linear_gradient_data.color_stops.repeat_length;
|
auto const& repeat_length = linear_gradient_data.color_stops.repeat_length;
|
||||||
|
@ -833,8 +816,6 @@ void DisplayListPlayerSkia::paint_text_shadow(PaintTextShadow const& command)
|
||||||
|
|
||||||
void DisplayListPlayerSkia::fill_rect_with_rounded_corners(FillRectWithRoundedCorners const& command)
|
void DisplayListPlayerSkia::fill_rect_with_rounded_corners(FillRectWithRoundedCorners const& command)
|
||||||
{
|
{
|
||||||
APPLY_TEXT_CLIP_IF_NEEDED(command.rect)
|
|
||||||
|
|
||||||
auto const& rect = command.rect;
|
auto const& rect = command.rect;
|
||||||
|
|
||||||
auto& canvas = surface().canvas();
|
auto& canvas = surface().canvas();
|
||||||
|
@ -1200,8 +1181,6 @@ void DisplayListPlayerSkia::draw_rect(DrawRect const& command)
|
||||||
|
|
||||||
void DisplayListPlayerSkia::paint_radial_gradient(PaintRadialGradient const& command)
|
void DisplayListPlayerSkia::paint_radial_gradient(PaintRadialGradient const& command)
|
||||||
{
|
{
|
||||||
APPLY_TEXT_CLIP_IF_NEEDED(command.rect)
|
|
||||||
|
|
||||||
auto const& radial_gradient_data = command.radial_gradient_data;
|
auto const& radial_gradient_data = command.radial_gradient_data;
|
||||||
|
|
||||||
auto color_stop_list = radial_gradient_data.color_stops.list;
|
auto color_stop_list = radial_gradient_data.color_stops.list;
|
||||||
|
@ -1249,8 +1228,6 @@ void DisplayListPlayerSkia::paint_radial_gradient(PaintRadialGradient const& com
|
||||||
|
|
||||||
void DisplayListPlayerSkia::paint_conic_gradient(PaintConicGradient const& command)
|
void DisplayListPlayerSkia::paint_conic_gradient(PaintConicGradient const& command)
|
||||||
{
|
{
|
||||||
APPLY_TEXT_CLIP_IF_NEEDED(command.rect)
|
|
||||||
|
|
||||||
auto const& conic_gradient_data = command.conic_gradient_data;
|
auto const& conic_gradient_data = command.conic_gradient_data;
|
||||||
|
|
||||||
auto color_stop_list = conic_gradient_data.color_stops.list;
|
auto color_stop_list = conic_gradient_data.color_stops.list;
|
||||||
|
@ -1300,19 +1277,14 @@ void DisplayListPlayerSkia::add_rounded_rect_clip(AddRoundedRectClip const& comm
|
||||||
canvas.clipRRect(rounded_rect, clip_op, true);
|
canvas.clipRRect(rounded_rect, clip_op, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DisplayListPlayerSkia::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const
|
void DisplayListPlayerSkia::add_mask(AddMask const& command)
|
||||||
{
|
|
||||||
return surface().canvas().quickReject(to_skia_rect(rect));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayListPlayerSkia::apply_mask_painted_from(DisplayList& display_list, Gfx::IntRect rect)
|
|
||||||
{
|
{
|
||||||
|
auto const& rect = command.rect;
|
||||||
auto mask_surface = m_surface->make_surface(rect.width(), rect.height());
|
auto mask_surface = m_surface->make_surface(rect.width(), rect.height());
|
||||||
|
|
||||||
auto previous_surface = move(m_surface);
|
auto previous_surface = move(m_surface);
|
||||||
m_surface = make<SkiaSurface>(mask_surface);
|
m_surface = make<SkiaSurface>(mask_surface);
|
||||||
surface().canvas().translate(-rect.x(), -rect.y());
|
execute(*command.display_list);
|
||||||
execute(display_list);
|
|
||||||
m_surface = move(previous_surface);
|
m_surface = move(previous_surface);
|
||||||
|
|
||||||
SkMatrix mask_matrix;
|
SkMatrix mask_matrix;
|
||||||
|
@ -1323,4 +1295,9 @@ void DisplayListPlayerSkia::apply_mask_painted_from(DisplayList& display_list, G
|
||||||
surface().canvas().clipShader(shader);
|
surface().canvas().clipShader(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DisplayListPlayerSkia::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const
|
||||||
|
{
|
||||||
|
return surface().canvas().quickReject(to_skia_rect(rect));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,11 +76,10 @@ private:
|
||||||
void paint_conic_gradient(PaintConicGradient const&) override;
|
void paint_conic_gradient(PaintConicGradient const&) override;
|
||||||
void draw_triangle_wave(DrawTriangleWave const&) override;
|
void draw_triangle_wave(DrawTriangleWave const&) override;
|
||||||
void add_rounded_rect_clip(AddRoundedRectClip const&) override;
|
void add_rounded_rect_clip(AddRoundedRectClip const&) override;
|
||||||
|
void add_mask(AddMask const&) override;
|
||||||
|
|
||||||
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;
|
bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override;
|
||||||
|
|
||||||
void apply_mask_painted_from(DisplayList&, Gfx::IntRect);
|
|
||||||
|
|
||||||
class SkiaSurface;
|
class SkiaSurface;
|
||||||
SkiaSurface& surface() const;
|
SkiaSurface& surface() const;
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,20 @@ void DisplayListRecorder::add_rounded_rect_clip(CornerRadii corner_radii, Gfx::I
|
||||||
corner_clip });
|
corner_clip });
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::fill_rect(Gfx::IntRect const& rect, Color color, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::add_mask(RefPtr<DisplayList> display_list, Gfx::IntRect rect)
|
||||||
|
{
|
||||||
|
append(AddMask {
|
||||||
|
.display_list = move(display_list),
|
||||||
|
.rect = state().translation.map(rect) });
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayListRecorder::fill_rect(Gfx::IntRect const& rect, Color color)
|
||||||
{
|
{
|
||||||
if (rect.is_empty())
|
if (rect.is_empty())
|
||||||
return;
|
return;
|
||||||
append(FillRect {
|
append(FillRect {
|
||||||
.rect = state().translation.map(rect),
|
.rect = state().translation.map(rect),
|
||||||
.color = color,
|
.color = color,
|
||||||
.text_clip = move(text_clip),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,28 +134,26 @@ void DisplayListRecorder::fill_ellipse(Gfx::IntRect const& a_rect, Color color)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::fill_rect_with_linear_gradient(Gfx::IntRect const& gradient_rect, LinearGradientData const& data, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::fill_rect_with_linear_gradient(Gfx::IntRect const& gradient_rect, LinearGradientData const& data)
|
||||||
{
|
{
|
||||||
if (gradient_rect.is_empty())
|
if (gradient_rect.is_empty())
|
||||||
return;
|
return;
|
||||||
append(PaintLinearGradient {
|
append(PaintLinearGradient {
|
||||||
.gradient_rect = state().translation.map(gradient_rect),
|
.gradient_rect = state().translation.map(gradient_rect),
|
||||||
.linear_gradient_data = data,
|
.linear_gradient_data = data });
|
||||||
.text_clip = move(text_clip) });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::fill_rect_with_conic_gradient(Gfx::IntRect const& rect, ConicGradientData const& data, Gfx::IntPoint const& position, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::fill_rect_with_conic_gradient(Gfx::IntRect const& rect, ConicGradientData const& data, Gfx::IntPoint const& position)
|
||||||
{
|
{
|
||||||
if (rect.is_empty())
|
if (rect.is_empty())
|
||||||
return;
|
return;
|
||||||
append(PaintConicGradient {
|
append(PaintConicGradient {
|
||||||
.rect = state().translation.map(rect),
|
.rect = state().translation.map(rect),
|
||||||
.conic_gradient_data = data,
|
.conic_gradient_data = data,
|
||||||
.position = position,
|
.position = position });
|
||||||
.text_clip = move(text_clip) });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::fill_rect_with_radial_gradient(Gfx::IntRect const& rect, RadialGradientData const& data, Gfx::IntPoint center, Gfx::IntSize size, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::fill_rect_with_radial_gradient(Gfx::IntRect const& rect, RadialGradientData const& data, Gfx::IntPoint center, Gfx::IntSize size)
|
||||||
{
|
{
|
||||||
if (rect.is_empty())
|
if (rect.is_empty())
|
||||||
return;
|
return;
|
||||||
|
@ -157,8 +161,7 @@ void DisplayListRecorder::fill_rect_with_radial_gradient(Gfx::IntRect const& rec
|
||||||
.rect = state().translation.map(rect),
|
.rect = state().translation.map(rect),
|
||||||
.radial_gradient_data = data,
|
.radial_gradient_data = data,
|
||||||
.center = center,
|
.center = center,
|
||||||
.size = size,
|
.size = size });
|
||||||
.text_clip = move(text_clip) });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::draw_rect(Gfx::IntRect const& rect, Color color, bool rough)
|
void DisplayListRecorder::draw_rect(Gfx::IntRect const& rect, Color color, bool rough)
|
||||||
|
@ -183,7 +186,7 @@ void DisplayListRecorder::draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::draw_scaled_immutable_bitmap(Gfx::IntRect const& dst_rect, Gfx::ImmutableBitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::draw_scaled_immutable_bitmap(Gfx::IntRect const& dst_rect, Gfx::ImmutableBitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode)
|
||||||
{
|
{
|
||||||
if (dst_rect.is_empty())
|
if (dst_rect.is_empty())
|
||||||
return;
|
return;
|
||||||
|
@ -192,11 +195,10 @@ void DisplayListRecorder::draw_scaled_immutable_bitmap(Gfx::IntRect const& dst_r
|
||||||
.bitmap = bitmap,
|
.bitmap = bitmap,
|
||||||
.src_rect = src_rect,
|
.src_rect = src_rect,
|
||||||
.scaling_mode = scaling_mode,
|
.scaling_mode = scaling_mode,
|
||||||
.text_clip = move(text_clip),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::draw_repeated_immutable_bitmap(Gfx::IntRect dst_rect, Gfx::IntRect clip_rect, NonnullRefPtr<Gfx::ImmutableBitmap> bitmap, Gfx::ScalingMode scaling_mode, DrawRepeatedImmutableBitmap::Repeat repeat, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::draw_repeated_immutable_bitmap(Gfx::IntRect dst_rect, Gfx::IntRect clip_rect, NonnullRefPtr<Gfx::ImmutableBitmap> bitmap, Gfx::ScalingMode scaling_mode, DrawRepeatedImmutableBitmap::Repeat repeat)
|
||||||
{
|
{
|
||||||
append(DrawRepeatedImmutableBitmap {
|
append(DrawRepeatedImmutableBitmap {
|
||||||
.dst_rect = dst_rect,
|
.dst_rect = dst_rect,
|
||||||
|
@ -204,7 +206,6 @@ void DisplayListRecorder::draw_repeated_immutable_bitmap(Gfx::IntRect dst_rect,
|
||||||
.bitmap = move(bitmap),
|
.bitmap = move(bitmap),
|
||||||
.scaling_mode = scaling_mode,
|
.scaling_mode = scaling_mode,
|
||||||
.repeat = repeat,
|
.repeat = repeat,
|
||||||
.text_clip = move(text_clip),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,13 +353,13 @@ void DisplayListRecorder::paint_text_shadow(int blur_radius, Gfx::IntRect boundi
|
||||||
.draw_location = state().translation.map(draw_location) });
|
.draw_location = state().translation.map(draw_location) });
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::AntiAliasingPainter::CornerRadius top_left_radius, Gfx::AntiAliasingPainter::CornerRadius top_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_left_radius, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::AntiAliasingPainter::CornerRadius top_left_radius, Gfx::AntiAliasingPainter::CornerRadius top_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_left_radius)
|
||||||
{
|
{
|
||||||
if (rect.is_empty())
|
if (rect.is_empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!top_left_radius && !top_right_radius && !bottom_right_radius && !bottom_left_radius) {
|
if (!top_left_radius && !top_right_radius && !bottom_right_radius && !bottom_left_radius) {
|
||||||
fill_rect(rect, color, text_clip);
|
fill_rect(rect, color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,18 +372,17 @@ void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& rec
|
||||||
.bottom_right = bottom_right_radius,
|
.bottom_right = bottom_right_radius,
|
||||||
.bottom_left = bottom_left_radius,
|
.bottom_left = bottom_left_radius,
|
||||||
},
|
},
|
||||||
.text_clip = text_clip,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int radius, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int radius)
|
||||||
{
|
{
|
||||||
if (a_rect.is_empty())
|
if (a_rect.is_empty())
|
||||||
return;
|
return;
|
||||||
fill_rect_with_rounded_corners(a_rect, color, radius, radius, radius, radius, move(text_clip));
|
fill_rect_with_rounded_corners(a_rect, color, radius, radius, radius, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius, RefPtr<DisplayList> text_clip)
|
void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius)
|
||||||
{
|
{
|
||||||
if (a_rect.is_empty())
|
if (a_rect.is_empty())
|
||||||
return;
|
return;
|
||||||
|
@ -390,8 +390,7 @@ void DisplayListRecorder::fill_rect_with_rounded_corners(Gfx::IntRect const& a_r
|
||||||
{ top_left_radius, top_left_radius },
|
{ top_left_radius, top_left_radius },
|
||||||
{ top_right_radius, top_right_radius },
|
{ top_right_radius, top_right_radius },
|
||||||
{ bottom_right_radius, bottom_right_radius },
|
{ bottom_right_radius, bottom_right_radius },
|
||||||
{ bottom_left_radius, bottom_left_radius },
|
{ bottom_left_radius, bottom_left_radius });
|
||||||
move(text_clip));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness = 1)
|
void DisplayListRecorder::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness = 1)
|
||||||
|
|
|
@ -40,7 +40,7 @@ class DisplayListRecorder {
|
||||||
AK_MAKE_NONMOVABLE(DisplayListRecorder);
|
AK_MAKE_NONMOVABLE(DisplayListRecorder);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void fill_rect(Gfx::IntRect const& rect, Color color, RefPtr<DisplayList> text_clip = {});
|
void fill_rect(Gfx::IntRect const& rect, Color color);
|
||||||
|
|
||||||
struct FillPathUsingColorParams {
|
struct FillPathUsingColorParams {
|
||||||
Gfx::Path path;
|
Gfx::Path path;
|
||||||
|
@ -80,16 +80,16 @@ public:
|
||||||
|
|
||||||
void fill_ellipse(Gfx::IntRect const& a_rect, Color color);
|
void fill_ellipse(Gfx::IntRect const& a_rect, Color color);
|
||||||
|
|
||||||
void fill_rect_with_linear_gradient(Gfx::IntRect const& gradient_rect, LinearGradientData const& data, RefPtr<DisplayList> text_clip = {});
|
void fill_rect_with_linear_gradient(Gfx::IntRect const& gradient_rect, LinearGradientData const& data);
|
||||||
void fill_rect_with_conic_gradient(Gfx::IntRect const& rect, ConicGradientData const& data, Gfx::IntPoint const& position, RefPtr<DisplayList> text_clip = {});
|
void fill_rect_with_conic_gradient(Gfx::IntRect const& rect, ConicGradientData const& data, Gfx::IntPoint const& position);
|
||||||
void fill_rect_with_radial_gradient(Gfx::IntRect const& rect, RadialGradientData const& data, Gfx::IntPoint center, Gfx::IntSize size, RefPtr<DisplayList> text_clip = {});
|
void fill_rect_with_radial_gradient(Gfx::IntRect const& rect, RadialGradientData const& data, Gfx::IntPoint center, Gfx::IntSize size);
|
||||||
|
|
||||||
void draw_rect(Gfx::IntRect const& rect, Color color, bool rough = false);
|
void draw_rect(Gfx::IntRect const& rect, Color color, bool rough = false);
|
||||||
|
|
||||||
void draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor);
|
void draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor);
|
||||||
void draw_scaled_immutable_bitmap(Gfx::IntRect const& dst_rect, Gfx::ImmutableBitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor, RefPtr<DisplayList> text_clip = {});
|
void draw_scaled_immutable_bitmap(Gfx::IntRect const& dst_rect, Gfx::ImmutableBitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor);
|
||||||
|
|
||||||
void draw_repeated_immutable_bitmap(Gfx::IntRect dst_rect, Gfx::IntRect clip_rect, NonnullRefPtr<Gfx::ImmutableBitmap> bitmap, Gfx::ScalingMode scaling_mode, DrawRepeatedImmutableBitmap::Repeat, RefPtr<DisplayList> text_clip = {});
|
void draw_repeated_immutable_bitmap(Gfx::IntRect dst_rect, Gfx::IntRect clip_rect, NonnullRefPtr<Gfx::ImmutableBitmap> bitmap, Gfx::ScalingMode scaling_mode, DrawRepeatedImmutableBitmap::Repeat);
|
||||||
|
|
||||||
void draw_line(Gfx::IntPoint from, Gfx::IntPoint to, Color color, int thickness = 1, Gfx::LineStyle style = Gfx::LineStyle::Solid, Color alternate_color = Color::Transparent);
|
void draw_line(Gfx::IntPoint from, Gfx::IntPoint to, Color color, int thickness = 1, Gfx::LineStyle style = Gfx::LineStyle::Solid, Color alternate_color = Color::Transparent);
|
||||||
|
|
||||||
|
@ -123,6 +123,7 @@ public:
|
||||||
void pop_stacking_context();
|
void pop_stacking_context();
|
||||||
|
|
||||||
void add_rounded_rect_clip(CornerRadii corner_radii, Gfx::IntRect border_rect, CornerClip corner_clip);
|
void add_rounded_rect_clip(CornerRadii corner_radii, Gfx::IntRect border_rect, CornerClip corner_clip);
|
||||||
|
void add_mask(RefPtr<DisplayList> display_list, Gfx::IntRect rect);
|
||||||
|
|
||||||
void apply_backdrop_filter(Gfx::IntRect const& backdrop_region, BorderRadiiData const& border_radii_data, CSS::ResolvedBackdropFilter const& backdrop_filter);
|
void apply_backdrop_filter(Gfx::IntRect const& backdrop_region, BorderRadiiData const& border_radii_data, CSS::ResolvedBackdropFilter const& backdrop_filter);
|
||||||
|
|
||||||
|
@ -130,9 +131,9 @@ public:
|
||||||
void paint_inner_box_shadow_params(PaintBoxShadowParams params);
|
void paint_inner_box_shadow_params(PaintBoxShadowParams params);
|
||||||
void paint_text_shadow(int blur_radius, Gfx::IntRect bounding_rect, Gfx::IntRect text_rect, Gfx::GlyphRun const&, double glyph_run_scale, Color color, Gfx::IntPoint draw_location);
|
void paint_text_shadow(int blur_radius, Gfx::IntRect bounding_rect, Gfx::IntRect text_rect, Gfx::GlyphRun const&, double glyph_run_scale, Color color, Gfx::IntPoint draw_location);
|
||||||
|
|
||||||
void fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::AntiAliasingPainter::CornerRadius top_left_radius, Gfx::AntiAliasingPainter::CornerRadius top_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_left_radius, RefPtr<DisplayList> text_clip = {});
|
void fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::AntiAliasingPainter::CornerRadius top_left_radius, Gfx::AntiAliasingPainter::CornerRadius top_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_left_radius);
|
||||||
void fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int radius, RefPtr<DisplayList> text_clip = {});
|
void fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int radius);
|
||||||
void fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius, RefPtr<DisplayList> text_clip = {});
|
void fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius);
|
||||||
|
|
||||||
void draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness);
|
void draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue