mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-25 19:56:30 +00:00
LibWeb: Use shape-rendering
to control anti aliasing for SVG paths
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Anti-aliasing is disabled if `shape-rendering` is set to `optimizeSpeed` or `crispEdges`.
This commit is contained in:
parent
1d745884be
commit
cfc6439c12
Notes:
github-actions[bot]
2025-08-19 08:48:50 +00:00
Author: https://github.com/tcl3
Commit: cfc6439c12
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5899
Reviewed-by: https://github.com/AtkinsSJ ✅
10 changed files with 43 additions and 4 deletions
|
@ -896,6 +896,7 @@ class VideoPaintable;
|
||||||
class ViewportPaintable;
|
class ViewportPaintable;
|
||||||
|
|
||||||
enum class PaintPhase;
|
enum class PaintPhase;
|
||||||
|
enum class ShouldAntiAlias : bool;
|
||||||
|
|
||||||
struct BorderRadiiData;
|
struct BorderRadiiData;
|
||||||
struct BorderRadiusData;
|
struct BorderRadiusData;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <LibWeb/Painting/PaintBoxShadowParams.h>
|
#include <LibWeb/Painting/PaintBoxShadowParams.h>
|
||||||
#include <LibWeb/Painting/PaintStyle.h>
|
#include <LibWeb/Painting/PaintStyle.h>
|
||||||
#include <LibWeb/Painting/ScrollState.h>
|
#include <LibWeb/Painting/ScrollState.h>
|
||||||
|
#include <LibWeb/Painting/ShouldAntiAlias.h>
|
||||||
|
|
||||||
namespace Web::Painting {
|
namespace Web::Painting {
|
||||||
|
|
||||||
|
@ -217,6 +218,7 @@ struct FillPath {
|
||||||
float opacity { 1.0f };
|
float opacity { 1.0f };
|
||||||
PaintStyleOrColor paint_style_or_color;
|
PaintStyleOrColor paint_style_or_color;
|
||||||
Gfx::WindingRule winding_rule;
|
Gfx::WindingRule winding_rule;
|
||||||
|
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
|
||||||
|
|
||||||
|
@ -239,6 +241,7 @@ struct StrokePath {
|
||||||
float opacity;
|
float opacity;
|
||||||
PaintStyleOrColor paint_style_or_color;
|
PaintStyleOrColor paint_style_or_color;
|
||||||
float thickness;
|
float thickness;
|
||||||
|
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
|
||||||
|
|
||||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
|
[[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
|
||||||
|
|
||||||
|
|
|
@ -654,7 +654,7 @@ void DisplayListPlayerSkia::fill_path(FillPath const& command)
|
||||||
auto const& color = command.paint_style_or_color.get<Color>();
|
auto const& color = command.paint_style_or_color.get<Color>();
|
||||||
paint.setColor(to_skia_color(color));
|
paint.setColor(to_skia_color(color));
|
||||||
}
|
}
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(command.should_anti_alias == ShouldAntiAlias::Yes);
|
||||||
surface().canvas().drawPath(path, paint);
|
surface().canvas().drawPath(path, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,7 +670,7 @@ void DisplayListPlayerSkia::stroke_path(StrokePath const& command)
|
||||||
auto const& color = command.paint_style_or_color.get<Color>();
|
auto const& color = command.paint_style_or_color.get<Color>();
|
||||||
paint.setColor(to_skia_color(color));
|
paint.setColor(to_skia_color(color));
|
||||||
}
|
}
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(command.should_anti_alias == ShouldAntiAlias::Yes);
|
||||||
paint.setStyle(SkPaint::Style::kStroke_Style);
|
paint.setStyle(SkPaint::Style::kStroke_Style);
|
||||||
paint.setStrokeWidth(command.thickness);
|
paint.setStrokeWidth(command.thickness);
|
||||||
paint.setStrokeCap(to_skia_cap(command.cap_style));
|
paint.setStrokeCap(to_skia_cap(command.cap_style));
|
||||||
|
|
|
@ -78,7 +78,7 @@ void DisplayListRecorder::fill_path(FillPathParams params)
|
||||||
.opacity = params.opacity,
|
.opacity = params.opacity,
|
||||||
.paint_style_or_color = params.paint_style_or_color,
|
.paint_style_or_color = params.paint_style_or_color,
|
||||||
.winding_rule = params.winding_rule,
|
.winding_rule = params.winding_rule,
|
||||||
});
|
.should_anti_alias = params.should_anti_alias });
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::stroke_path(StrokePathParams params)
|
void DisplayListRecorder::stroke_path(StrokePathParams params)
|
||||||
|
@ -105,7 +105,7 @@ void DisplayListRecorder::stroke_path(StrokePathParams params)
|
||||||
.opacity = params.opacity,
|
.opacity = params.opacity,
|
||||||
.paint_style_or_color = params.paint_style_or_color,
|
.paint_style_or_color = params.paint_style_or_color,
|
||||||
.thickness = params.thickness,
|
.thickness = params.thickness,
|
||||||
});
|
.should_anti_alias = params.should_anti_alias });
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::draw_ellipse(Gfx::IntRect const& a_rect, Color color, int thickness)
|
void DisplayListRecorder::draw_ellipse(Gfx::IntRect const& a_rect, Color color, int thickness)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <LibWeb/Painting/GradientData.h>
|
#include <LibWeb/Painting/GradientData.h>
|
||||||
#include <LibWeb/Painting/PaintBoxShadowParams.h>
|
#include <LibWeb/Painting/PaintBoxShadowParams.h>
|
||||||
#include <LibWeb/Painting/PaintStyle.h>
|
#include <LibWeb/Painting/PaintStyle.h>
|
||||||
|
#include <LibWeb/Painting/ShouldAntiAlias.h>
|
||||||
|
|
||||||
namespace Web::Painting {
|
namespace Web::Painting {
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ public:
|
||||||
float opacity = 1.0f;
|
float opacity = 1.0f;
|
||||||
PaintStyleOrColor paint_style_or_color;
|
PaintStyleOrColor paint_style_or_color;
|
||||||
Gfx::WindingRule winding_rule = Gfx::WindingRule::EvenOdd;
|
Gfx::WindingRule winding_rule = Gfx::WindingRule::EvenOdd;
|
||||||
|
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
|
||||||
};
|
};
|
||||||
void fill_path(FillPathParams params);
|
void fill_path(FillPathParams params);
|
||||||
|
|
||||||
|
@ -58,6 +60,7 @@ public:
|
||||||
float opacity = 1.0f;
|
float opacity = 1.0f;
|
||||||
PaintStyleOrColor paint_style_or_color;
|
PaintStyleOrColor paint_style_or_color;
|
||||||
float thickness;
|
float thickness;
|
||||||
|
ShouldAntiAlias should_anti_alias { ShouldAntiAlias::Yes };
|
||||||
};
|
};
|
||||||
void stroke_path(StrokePathParams);
|
void stroke_path(StrokePathParams);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <LibWeb/Painting/ClipFrame.h>
|
#include <LibWeb/Painting/ClipFrame.h>
|
||||||
#include <LibWeb/Painting/Paintable.h>
|
#include <LibWeb/Painting/Paintable.h>
|
||||||
#include <LibWeb/Painting/PaintableFragment.h>
|
#include <LibWeb/Painting/PaintableFragment.h>
|
||||||
|
#include <LibWeb/Painting/ShouldAntiAlias.h>
|
||||||
|
|
||||||
namespace Web::Painting {
|
namespace Web::Painting {
|
||||||
|
|
||||||
|
|
|
@ -33,4 +33,12 @@ CSSPixelRect SVGPaintable::compute_absolute_rect() const
|
||||||
return PaintableBox::compute_absolute_rect();
|
return PaintableBox::compute_absolute_rect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShouldAntiAlias SVGPaintable::should_anti_alias() const
|
||||||
|
{
|
||||||
|
auto shape_rendering = computed_values().shape_rendering();
|
||||||
|
if (first_is_one_of(shape_rendering, CSS::ShapeRendering::Optimizespeed, CSS::ShapeRendering::Crispedges))
|
||||||
|
return ShouldAntiAlias::No;
|
||||||
|
return ShouldAntiAlias::Yes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ protected:
|
||||||
SVGPaintable(Layout::SVGBox const&);
|
SVGPaintable(Layout::SVGBox const&);
|
||||||
|
|
||||||
virtual CSSPixelRect compute_absolute_rect() const override;
|
virtual CSSPixelRect compute_absolute_rect() const override;
|
||||||
|
|
||||||
|
ShouldAntiAlias should_anti_alias() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -98,6 +98,7 @@ void SVGPathPaintable::paint(DisplayListRecordingContext& context, PaintPhase ph
|
||||||
.path = closed_path(),
|
.path = closed_path(),
|
||||||
.paint_style_or_color = Gfx::Color(Color::Black),
|
.paint_style_or_color = Gfx::Color(Color::Black),
|
||||||
.winding_rule = to_gfx_winding_rule(graphics_element.clip_rule().value_or(SVG::ClipRule::Nonzero)),
|
.winding_rule = to_gfx_winding_rule(graphics_element.clip_rule().value_or(SVG::ClipRule::Nonzero)),
|
||||||
|
.should_anti_alias = should_anti_alias(),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -116,12 +117,14 @@ void SVGPathPaintable::paint(DisplayListRecordingContext& context, PaintPhase ph
|
||||||
.opacity = fill_opacity,
|
.opacity = fill_opacity,
|
||||||
.paint_style_or_color = *paint_style,
|
.paint_style_or_color = *paint_style,
|
||||||
.winding_rule = winding_rule,
|
.winding_rule = winding_rule,
|
||||||
|
.should_anti_alias = should_anti_alias(),
|
||||||
});
|
});
|
||||||
} else if (auto fill_color = graphics_element.fill_color(); fill_color.has_value()) {
|
} else if (auto fill_color = graphics_element.fill_color(); fill_color.has_value()) {
|
||||||
context.display_list_recorder().fill_path({
|
context.display_list_recorder().fill_path({
|
||||||
.path = closed_path(),
|
.path = closed_path(),
|
||||||
.paint_style_or_color = fill_color->with_opacity(fill_opacity),
|
.paint_style_or_color = fill_color->with_opacity(fill_opacity),
|
||||||
.winding_rule = winding_rule,
|
.winding_rule = winding_rule,
|
||||||
|
.should_anti_alias = should_anti_alias(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +180,7 @@ void SVGPathPaintable::paint(DisplayListRecordingContext& context, PaintPhase ph
|
||||||
.opacity = stroke_opacity,
|
.opacity = stroke_opacity,
|
||||||
.paint_style_or_color = *paint_style,
|
.paint_style_or_color = *paint_style,
|
||||||
.thickness = stroke_thickness,
|
.thickness = stroke_thickness,
|
||||||
|
.should_anti_alias = should_anti_alias(),
|
||||||
});
|
});
|
||||||
} else if (auto stroke_color = graphics_element.stroke_color(); stroke_color.has_value()) {
|
} else if (auto stroke_color = graphics_element.stroke_color(); stroke_color.has_value()) {
|
||||||
context.display_list_recorder().stroke_path({
|
context.display_list_recorder().stroke_path({
|
||||||
|
@ -188,6 +192,7 @@ void SVGPathPaintable::paint(DisplayListRecordingContext& context, PaintPhase ph
|
||||||
.path = path,
|
.path = path,
|
||||||
.paint_style_or_color = stroke_color->with_opacity(stroke_opacity),
|
.paint_style_or_color = stroke_color->with_opacity(stroke_opacity),
|
||||||
.thickness = stroke_thickness,
|
.thickness = stroke_thickness,
|
||||||
|
.should_anti_alias = should_anti_alias(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
Libraries/LibWeb/Painting/ShouldAntiAlias.h
Normal file
16
Libraries/LibWeb/Painting/ShouldAntiAlias.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Tim Ledbetter <tim.ledbetter@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Web::Painting {
|
||||||
|
|
||||||
|
enum class ShouldAntiAlias : bool {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue