1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 18:27:35 +00:00

LibGfx: Implement new antialiased filled path rasterizer

This is an implementation of the scanline edge-flag algorithm for
antialiased path filling described here:
https://mlab.taik.fi/~kkallio/antialiasing/EdgeFlagAA.pdf

The initial implementation does not try to implement every possible
optimization in favour of keeping things simple. However, it does
support:

   - Both evenodd and nonzero fill rules
   - Applying paint styles/gradients
   - A range of samples per pixel (8, 16, 32)
   - Very nice antialiasing :^)

This replaces the previous path filling code, that only really applied
antialiasing in the x-axis.

There's some very nice improvements around the web with this change,
especially for small icons. Strokes are still a bit wonky, as they don't
yet use this rasterizer, but I think it should be possible to convert
them to do so.
This commit is contained in:
MacDue 2023-05-31 19:02:00 +01:00 committed by Andreas Kling
parent e4adaa2d20
commit 48fa8f97d3
6 changed files with 536 additions and 324 deletions

View file

@ -187,6 +187,8 @@ public:
protected:
friend GradientLine;
friend AntiAliasingPainter;
template<unsigned SamplesPerPixel>
friend class EdgeFlagPathRasterizer;
IntRect to_physical(IntRect const& r) const { return r.translated(translation()) * scale(); }
IntPoint to_physical(IntPoint p) const { return p.translated(translation()) * scale(); }
@ -219,17 +221,6 @@ private:
bool text_contains_bidirectional_text(Utf8View const&, TextDirection);
template<typename DrawGlyphFunction>
void do_draw_text(FloatRect const&, Utf8View const& text, Font const&, TextAlignment, TextElision, TextWrapping, DrawGlyphFunction);
void antialiased_fill_path(Path const&, Color, WindingRule rule, FloatPoint translation);
void antialiased_fill_path(Path const&, PaintStyle const& paint_style, WindingRule rule, FloatPoint translation);
enum class FillPathMode {
PlaceOnIntGrid,
AllowFloatingPoints,
};
template<typename T, typename TColorOrFunction>
void draw_scanline_for_fill_path(int y, T x_start, T x_end, TColorOrFunction color);
template<FillPathMode fill_path_mode, typename ColorOrFunction>
void fill_path_impl(Path const& path, ColorOrFunction color, Gfx::Painter::WindingRule winding_rule, Optional<FloatPoint> offset = {});
};
class PainterStateSaver {