mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:37:35 +00:00
LibGfx: Add AA dotted horizontal/vertical lines
This adds simple dotted lines (horizontal/vertical only for now). There's a little number fudging added in to make sure the final dot is always drawn at the endpoint (for lines with at least a handful of dots).
This commit is contained in:
parent
50c88e5e3a
commit
6139fc5c87
2 changed files with 46 additions and 0 deletions
|
@ -123,8 +123,52 @@ void Gfx::AntiAliasingPainter::draw_aliased_line(FloatPoint const& actual_from,
|
|||
draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color);
|
||||
}
|
||||
|
||||
void Gfx::AntiAliasingPainter::draw_dotted_line(IntPoint point1, IntPoint point2, Gfx::Color color, int thickness)
|
||||
{
|
||||
// AA circles don't really work below a radius of 2px.
|
||||
if (thickness < 4)
|
||||
return m_underlying_painter.draw_line(point1, point2, color, thickness, Painter::LineStyle::Dotted);
|
||||
|
||||
auto draw_spaced_dots = [&](int start, int end, auto to_point) {
|
||||
int step = thickness * 2;
|
||||
if (start > end)
|
||||
swap(start, end);
|
||||
int delta = end - start;
|
||||
int dots = delta / step;
|
||||
if (dots == 0)
|
||||
return;
|
||||
int fudge_per_dot = 0;
|
||||
int extra_fudge = 0;
|
||||
if (dots > 3) {
|
||||
// Fudge the numbers so the last dot is drawn at the `end' point (otherwise you can get lines cuts short).
|
||||
// You need at least a handful of dots to do this.
|
||||
int fudge = delta % step;
|
||||
fudge_per_dot = fudge / dots;
|
||||
extra_fudge = fudge % dots;
|
||||
}
|
||||
for (int dot = start; dot <= end; dot += (step + fudge_per_dot + (extra_fudge > 0))) {
|
||||
fill_circle(to_point(dot), thickness / 2, color);
|
||||
--extra_fudge;
|
||||
}
|
||||
};
|
||||
|
||||
if (point1.y() == point2.y()) {
|
||||
draw_spaced_dots(point1.x(), point2.x(), [&](int dot_x) {
|
||||
return IntPoint { dot_x, point1.y() };
|
||||
});
|
||||
} else if (point1.x() == point2.x()) {
|
||||
draw_spaced_dots(point1.y(), point2.y(), [&](int dot_y) {
|
||||
return IntPoint { point1.x(), dot_y };
|
||||
});
|
||||
} else {
|
||||
TODO();
|
||||
}
|
||||
}
|
||||
|
||||
void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color)
|
||||
{
|
||||
if (style == Painter::LineStyle::Dotted)
|
||||
return draw_dotted_line(actual_from.to_rounded<int>(), actual_to.to_rounded<int>(), color, static_cast<int>(round(thickness)));
|
||||
draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ private:
|
|||
|
||||
Range draw_ellipse_part(IntPoint a_rect, int radius_a, int radius_b, Color, bool flip_x_and_y, Optional<Range> x_clip, BlendMode blend_mode);
|
||||
|
||||
void draw_dotted_line(IntPoint, IntPoint, Gfx::Color, int thickness);
|
||||
|
||||
enum class AntiAliasPolicy {
|
||||
OnlyEnds,
|
||||
Full,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue