SVG Style Paths and Anti-aliasing?


#1

So I doubt what I want to be able to do is feasible on such hardware but I figured I’d ask about it and maybe work on some solutions and alternative options.

SVG

The most common thing I’d like to be able to do with my panel is to display an SVG icon on a background (likely flat color to make things easier). I assume I could simply convert the SVG to be a bitmap and load that from the SD card but it would be nice to have a bit more control for animation purposes.

Ideally I’d like to be able to call backgroundLayer.drawPath(svgPath, x, y, rotation, scale); or backgroundLayer.fillPath(svgPath, x, y, rotation, scale); where (x,y) defines the origin and svgPath is a string defining an SVG style path such as M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z. For fun/practice I’m considering programming an interpreter which draws the SVG as lines but I’m not sure how the curves or fill would be implemented. It would probably need to be done pixel by pixel and I’m assuming that is what is used for the current geometries though perhaps altering the buffer directly rather than wasting instructions calling drawPixel. I haven’t had time to look into the code at all but perhaps some thoughts can be shared on the topic of SVG support.

Anti-aliasing

As far as I can see, there isn’t support for anti-aliasing currently? It seems like it would be reasonably simple to implement basic anti-aliasing by using a weighted average of the current pixel color and the new pixel color to give the illusion of transparency. I believe this would cause issues where multiple anti-aliased drawings overlap closely and have vastly different colors though for most cases this shouldn’t matter. This would of course be an option which is disabled by default.

Perhaps another solution could be to apply a small blur to the image. Is this supported at all?


#2

Hi James,

I don’t know enough about SVG to say whether it could be supported.

Take a look at the graphics functions like fillCircle or fillTriangle to see how they’re implemented.

I haven’t thought much about anti-aliasing, as I’m not sure how successful it would be with such a small resolution display.

For both these topics, I suggest looking at graphics implementations for older computers and/or video game systems, as programmers did a lot with limited hardware back then.

Adding anti-aliasing between layers is probably a bit more complicated than adding it within a single layer, and would require updating the refresh code which isn’t easy to modify right now. I want to make this at a minimum easier to modify for SmartMatrix Library 4.0, so I’m interested in hearing even just at a high level how you’d want anti-aliasing to work between layers (if that’s even what you’re asking).


#3

Which file(s) are the drawing functions defined in? I’ll take a look at the code at some point but if it is possible to create an n-sided polygon, it should be possible to support SVG style paths.

I don’t really think its worth adding support for SVG files themselves but I feel like the ability to define custom shapes would be really useful and allow people to do a lot more with the library. It makes sense to implement that in a way which people are familiar with so I feel using the SVG path syntax is a good way to go. Assuming polygons can be supported, the only real issue is the arcs and bezier curves which would require a few equations to implement, which is always so much ‘fun’.

If SVG paths are implemented though, it makes it so much easier for users to add icons to their displays. All of the icons over at material design icons are available as svg and the path could easily be copied over into the program. It opens up easy access to more complex graphics without needing storage for bitmaps and a bunch of code to read that from memory and draw it on the display. It may even allow really rich animation capabilities depending on how well the draw function performs.

For reference: https://developer.mozilla.org/en/docs/Web/SVG/Tutorial/Paths

On the anti-aliasing side of things, it really only needs to be available on a layer by layer basis. If and when transparency support is added to layers, anti-aliasing between layers should be easy to do. The idea behind anti-aliasing would be to allow for drawing between pixels so you could technically draw a rectangle at (0.5, 0.5) and it would light up the first column and row of the screen at half the brightness of the fill color. This technique would smooth out stepped lines and also make animations look much smoother as the motion of a pixel transitions gradually between the two LEDs.

Usually you would achieve this affect by using transparency and alpha blending but it really isn’t required in this case. Take for example a black background on which you draw a white rectangle. You draw the rectangle at (0.6, 0.6) with a certain width or height which don’t really matter for this example. The top corner is technically supposed to be drawn in (0,0) but as it is only 0.4 pixels into that grid square, the current algorithm rounds that down and doesn’t fill that pixel. Instead, what could be done is to analyze the amount of that pixel which is white and the amount which is black. In this case it is 0.60.6 + 0.40.6 + 0.40.6 = 84% black and 0.40.4 = 16% white. You can then use those values to perform a weighted average on the current pixel color and the new pixel color.


#4

Which file(s) are the drawing functions defined in?

Layer_Background_Impl.h