How to perform the equivalent of cairo's mesh patterns?

23 views
Skip to first unread message

Alexandre Bique

unread,
Feb 8, 2024, 8:36:38 AMFeb 8
to skia-discuss
Hi,

I wonder how to perform the equivalent of cairo's mesh patterns with skia?

I couldn't find an equivalent function within Skia's builtin effects, so maybe it has to be manually implemented using SkRuntimeEffect::MakeForShader()?

Thank you very much,
Alex

Brian Osman

unread,
Feb 8, 2024, 8:41:20 AMFeb 8
to skia-d...@googlegroups.com
It looks like the cairo patches are slightly less constrained, but Skia does have a Coons patch primitive (which can do most of what';s described there): https://source.chromium.org/chromium/chromium/src/+/main:third_party/skia/include/core/SkCanvas.h;l=2047;drc=b5f416c26e7317f20e9ea957bba490e9f301d3a0

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/e731a0d8-761a-48e4-9848-9b42d7d8fe6cn%40googlegroups.com.

Alexandre Bique

unread,
Feb 9, 2024, 9:09:18 AMFeb 9
to skia-discuss
Hi Brian,

Thank you very much for the tip.
Do you know if it is possible to store this as a shader? Would it be wise?

Thank you very much,
Alex

Brian Osman

unread,
Feb 9, 2024, 9:51:47 AMFeb 9
to skia-d...@googlegroups.com
It depends ... Those two concepts (patch vs. shader) are very different in Skia. A patch is a geometric primitive - it defines what area of the canvas is drawn. Other geometric primitives are things like rectangles, paths, or text. Each of those just determines the set of pixels that are drawn, but nothing about how they're filled. (Except for color-emoji text, which is a special case).

An SkShader is a pattern - it defines how to fill a set of pixels, once the geometry has selected them. So you can use a shader with any of those (including with a patch), to apply a fill pattern to that area. But you can't really implement a patch with a shader, because the shader never chooses what pixels are (or aren't) drawn - it just colors pixels that are already chosen by some other geometric primitive.

That said - you can write shaders that sort-of perform effects like this, in some situations. For example, you can write a shader that figures out (for each pixel) if it's "inside" a shape, and either returns a color for the interior, or returns a fully transparent pixel for the exterior. Then you have to draw a large enough rectangle (or other bounding shape) to cover the thing you're representing with the shader. This only works with some SkBlendModes, though - there are some (blend modes that will affect the surface, even if your shader outputs a transparent color. Using the default blend mode of kSrcOver, you won't have this problem.

Finally, there is a canvas API called clipShader. This does let you control what pixels are drawn with a shader, but only by controlling the clip-area. Normally, the clip APIs take geometric primitives, and restrict the drawing so that it intersects that shape. You can also clip against a shader, and the drawing is restricted to areas where the shader produces an opaque alpha value. So you can write a shader that computes the outline of a shape, call clipShader with that shader, and then draw some bounding shape (similar to the previous example), to fill in just that area defined by the shader.

Reply all
Reply to author
Forward
0 new messages