Skip to content

Instantly share code, notes, and snippets.

@MacDue
Last active April 1, 2024 18:25
Show Gist options
  • Save MacDue/2b2c74c3c62d97969d6ef195e8750923 to your computer and use it in GitHub Desktop.
Save MacDue/2b2c74c3c62d97969d6ef195e8750923 to your computer and use it in GitHub Desktop.
Painter notes

I've been thinking (starting to) implement a new painting API for LibGfx... I find Gfx::Painter is a bit long in the tooth, with a lot of limitations/assumptions that make it not great for things like HTML canvas, PDF, and generally painting the web.

My current idea for the new painter is:

  • Everything that can be a float is a float
    • Integers are an optimization rather than the default
  • Transformed via Gfx::AffineTransform (rather than an integer translation)
    • Would allow for arbitrary 2D transforms... 3D can wait :^)
  • Support for global opacity, masking (i.e. arbitrary clip paths), and blending
    • Integer clip rects are simply an optimization
    • This is done by keeping two bitmaps internally
      • The target (what the user sees), and an offscreen bitmap
      • If you have a non-zero opacity, mask, or non-default blend mode:
        -> Paint to offscreen bitmap, then composite it later
    • In LibWeb, this would (more simply) allow implementing: border-radius clipping, clip-path, stacking-context opacity, etc
  • Smaller set of paint operations
    • Gfx::Painter has a lot of random stuff with very niche use cases
    • Mostly just filling/stroking shapes, paths, text, and bitmaps
    • Would need to come up with new ways to implement things like shadows (current LibWeb code assumes shadows are never transformed)

The general idea is to have a painter that can apply transforms/effects without resorting to hacks. For example, in LibWeb all painters apply transforms via drawing to a bitmap, then applying the transform to that bitmap, which is very sad (and results in artifacts) :^(

I think the current painting logic in LibWeb is baking in assumptions (and hacks like sample_under_corners) that don't really hold, and are mostly inherited from old painter (and working around it). So, I think it'd be cool to experiment with something more flexible :^)

@nico
Copy link

nico commented Apr 1, 2024

This makes a lot of sense to me.

I think it'd be nice if it was an abstract interface that could also be used with other backends, e.g. emitting PDF page contents, maybe SVGs, html canvas js code, etc. (I mostly care about PDF output though.) That'd probably also help inform the shape of the API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment