mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:17:44 +00:00
LibGfx: Add fast path to AA line drawing with simple 2D transform
If the effective 2D transform is just a basic translation, we now simply translate the underlying painter before & after drawing AA lines. This avoids all the extra math that otherwise has to happen when mapping points through an affine transform. This noticeably increase "mousing around" performance on Wikipedia. :^)
This commit is contained in:
parent
b4c3882d9c
commit
908d42d0ba
2 changed files with 31 additions and 8 deletions
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
// Base algorithm from https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm,
|
// Base algorithm from https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm,
|
||||||
// because there seems to be no other known method for drawing AA'd lines (?)
|
// because there seems to be no other known method for drawing AA'd lines (?)
|
||||||
template<Gfx::AntiAliasingPainter::AntiAliasPolicy policy>
|
template<Gfx::AntiAliasingPainter::AntiAliasPolicy policy, typename TransformPoint>
|
||||||
void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color)
|
void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color, TransformPoint transform_point)
|
||||||
{
|
{
|
||||||
// FIXME: Implement this :P
|
// FIXME: Implement this :P
|
||||||
VERIFY(style == Painter::LineStyle::Solid);
|
VERIFY(style == Painter::LineStyle::Solid);
|
||||||
|
@ -21,8 +21,8 @@ void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_f
|
||||||
auto corrected_thickness = thickness > 1 ? thickness - 1 : thickness;
|
auto corrected_thickness = thickness > 1 ? thickness - 1 : thickness;
|
||||||
auto size = IntSize(corrected_thickness, corrected_thickness);
|
auto size = IntSize(corrected_thickness, corrected_thickness);
|
||||||
auto plot = [&](int x, int y, float c) {
|
auto plot = [&](int x, int y, float c) {
|
||||||
auto center = m_transform.map(Gfx::IntPoint(x, y)).to_type<int>();
|
transform_point(x, y, m_transform);
|
||||||
m_underlying_painter.fill_rect(IntRect::centered_on(center, size), color.with_alpha(color.alpha() * c));
|
m_underlying_painter.fill_rect(IntRect::centered_on({ x, y }, size), color.with_alpha(color.alpha() * c));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto integer_part = [](float x) { return floorf(x); };
|
auto integer_part = [](float x) { return floorf(x); };
|
||||||
|
@ -112,14 +112,37 @@ void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_f
|
||||||
draw_line(actual_from.x(), actual_from.y(), actual_to.x(), actual_to.y());
|
draw_line(actual_from.x(), actual_from.y(), actual_to.x(), actual_to.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE void no_transform(int&, int&, Gfx::AffineTransform const&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE void full_transform(int& x, int& y, Gfx::AffineTransform const& transform)
|
||||||
|
{
|
||||||
|
auto mapped = transform.map(Gfx::IntPoint { x, y });
|
||||||
|
x = mapped.x();
|
||||||
|
y = mapped.y();
|
||||||
|
}
|
||||||
|
|
||||||
void Gfx::AntiAliasingPainter::draw_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color)
|
void Gfx::AntiAliasingPainter::draw_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color)
|
||||||
{
|
{
|
||||||
draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color);
|
if (m_transform.is_identity_or_translation()) {
|
||||||
|
m_underlying_painter.translate(m_transform.e(), m_transform.f());
|
||||||
|
draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color, no_transform);
|
||||||
|
m_underlying_painter.translate(-m_transform.e(), -m_transform.f());
|
||||||
|
} else {
|
||||||
|
draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color, full_transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color)
|
void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color)
|
||||||
{
|
{
|
||||||
draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color);
|
if (m_transform.is_identity_or_translation()) {
|
||||||
|
m_underlying_painter.translate(m_transform.e(), m_transform.f());
|
||||||
|
draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color, no_transform);
|
||||||
|
m_underlying_painter.translate(-m_transform.e(), -m_transform.f());
|
||||||
|
} else {
|
||||||
|
draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color, full_transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx::AntiAliasingPainter::fill_path(Path& path, Color color, Painter::WindingRule rule)
|
void Gfx::AntiAliasingPainter::fill_path(Path& path, Color color, Painter::WindingRule rule)
|
||||||
|
|
|
@ -37,8 +37,8 @@ private:
|
||||||
OnlyEnds,
|
OnlyEnds,
|
||||||
Full,
|
Full,
|
||||||
};
|
};
|
||||||
template<AntiAliasPolicy policy>
|
template<AntiAliasPolicy policy, typename TransformPoint>
|
||||||
void draw_anti_aliased_line(FloatPoint const&, FloatPoint const&, Color, float thickness, Painter::LineStyle style, Color alternate_color);
|
void draw_anti_aliased_line(FloatPoint const&, FloatPoint const&, Color, float thickness, Painter::LineStyle style, Color alternate_color, TransformPoint);
|
||||||
|
|
||||||
Painter& m_underlying_painter;
|
Painter& m_underlying_painter;
|
||||||
AffineTransform m_transform;
|
AffineTransform m_transform;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue