Sharp (instead of round) edges when using CreateFromSVGString()

asked Mar 4 in GUI Development by erikadlers

I'm trying to import an icon drawn in Adobe Illustrator using CreateFromSVGString(). The SVG metadata looks like this:

<svg id="Layer_1" data-name="Layer 1" xmlns="" viewBox="0 0 100 100">
<g id="Group_3165" data-name="Group 3165">
<g id="Group_3142" data-name="Group 3142">
<path id="Path_3085" data-name="Path 3085" class="cls-1" d="M49.84,86.75c-20.62-.11-37.19-15.82-37.19-35.26A34.05,34.05,0,0,1,23.51,26.77a39.6,39.6,0,0,1,6.69-5.06,3.33,3.33,0,0,1,4.5,1,2.94,2.94,0,0,1-.83,4.08L33.6,27h0c-14.26,8.48-18.75,26.37-9.76,39.91a28.55,28.55,0,0,0,4.39,5.17,32.13,32.13,0,0,0,43.44,0,27.85,27.85,0,0,0,1.6-39.35c-.51-.55-1-1.08-1.6-1.59A26.7,26.7,0,0,0,66.07,27a3,3,0,0,1-1.23-4l.13-.23a3.37,3.37,0,0,1,4.5-1h.11c17.56,10.23,23,31.84,12.19,48.39a34,34,0,0,1-5.38,6.41A38.39,38.39,0,0,1,49.84,86.75"/>
<path id="Path_3086" data-name="Path 3086" class="cls-1" d="M49.85,60.58c-2.46,0-4.34-1.52-4.34-3.51V19.64c0-2,1.88-3.51,4.34-3.51s4.33,1.52,4.33,3.51V57.07C54.18,59.06,52.3,60.58,49.85,60.58Z"/>

I import the SVG to two Graphics::Path using:

IconPathData.CreateFromSVGString("M49.84,86.75c-20.62-.11-37.19-15.82-37.19-35.26A34.05,34.05,0,0,1,23.51,26.77a39.6,39.6,0,0,1,6.69-5.06,3.33,3.33,0,0,1,4.5,1,2.94,2.94,0,0,1-.83,4.08L33.6,27h0c-14.26,8.48-18.75,26.37-9.76,39.91a28.55,28.55,0,0,0,4.39,5.17,32.13,32.13,0,0,0,43.44,0,27.85,27.85,0,0,0,1.6-39.35c-.51-.55-1-1.08-1.6-1.59A26.7,26.7,0,0,0,66.07,27a3,3,0,0,1-1.23-4l.13-.23a3.37,3.37,0,0,1,4.5-1h.11c17.56,10.23,23,31.84,12.19,48.39a34,34,0,0,1-5.38,6.41A38.39,38.39,0,0,1,49.84,86.75", 1.0, 1.0, 0.0, 0.0, 0.0);
IconPathData2.CreateFromSVGString("M49.85,60.58c-2.46,0-4.34-1.52-4.34-3.51V19.64c0-2,1.88-3.51,4.34-3.51s4.33,1.52,4.33,3.51V57.07C54.18,59.06,52.3,60.58,49.85,60.58Z", 1.0, 1.0, 0.0, 0.0, 0.0);

Both calls returns SVGParserStatus::Success.

So far so good, the icon get sharp (instead of smooth round) edges when it is drawn in the UI. See images below:

Screenshot of the imported SVG in Embedded Wizard

SVG data rendered in Embedded wizard

Screenshot of the original SVG file

SVG data rendered in Firefox


Is the input to CreateFromSVGString() too complex? Or is the paths rendered using an insufficient amount of edges? If yes, can on control that somehow?

commented Mar 4 by erikadlers

Another (simpler) example of an SVG that is rendered with sharp edges in Embedded Wizard:

<svg style="width:24px;height:24px" viewBox="0 0 24 24">
    <path fill="currentColor" d="M19.75 5.33A1.25 1.25 0 0 0 18.5 6.58V11.17H17.67V4.08A1.25 1.25 0 0 0 15.17 4.08V11.17H14.33V3.25A1.25 1.25 0 1 0 11.83 3.25V11.17H11V5.33A1.25 1.25 0 0 0 8.5 5.33V15.26L4.91 13.26A1 1 0 0 0 4.41 13.12A1 1 0 0 0 3.75 13.37L2.67 14.37L9.21 21A3.29 3.29 0 0 0 11.58 22H17.67A3.33 3.33 0 0 0 21 18.67V6.58A1.25 1.25 0 0 0 19.75 5.33M11 15A1 1 0 1 1 12 14A1 1 0 0 1 11 15M13 18A1 1 0 1 1 14 17A1 1 0 0 1 13 18M18 16A1 1 0 1 1 19 15A1 1 0 0 1 18 16M17 19A1 1 0 1 1 18 18A1 1 0 0 1 17 19M15 15A1 1 0 1 1 16 14A1 1 0 0 1 15 15Z" />

SVG data rendered in Embedded wizard


Original SVG file with round dots instead of squares

1 Answer

0 votes
answered Mar 4 by Paul Banach

Hello Erikadlers,

thank you for this report. We also observe the same behavior. Small circles appear as quads. To understand this problem you should know that internally all paths are stored as sequences of straight line segments. The circles, Bezier arcs, etc. found in the SVG string are also converted in such line segments. For optimization purpose and due to RAM limitations on embedded systems we limit the minim. length of such segment to ~ 8 pixel. This works very well for most curves. Small arcs, however, are composed of too few line segments. They do not appear round.

In the next version we will adapt the algorithm to calculate the optimal length of a single line segment. We could see that reducing the length to 4 pixel produces already good results. Anyway, you need a workaround working with the actual version. For this purpose, load the SVG string into a temporary Path Data object and scale it with the factor 2.0. With the factor 2.0 the SVG processing will 'think' that the image is bigger and will compose the circles and arcs from more line segments. To get the image in the original size, copy the contents of this temporary Path Data object into the final Path Data object by applying the scaling of 0.5. Following code demonstrates this:

// Create a temporary Path Data object
var Graphics::Path path = new Graphics::Path;
var int32          i;

// Fill the temp. Path Data object with the SVG data. Please note the scaling factors 2.0 to increase the precision
2.0, 2.0, 0.0, 0.0, 0.0);

// Now initialize the final Path data object to have the same capacity as the temp. Path data object.
IconPathData2.SetMaxNoOfSubPaths( path.GetMaxNoOfSubPaths());

// The following for-loop will create a copy of the temp. Path Data. Apply scaling factor 0.5 to this data.
IconPathData2.Scale( 0.5, 0.5 );

// Copy the data from the temp. to the final Path Data object
for ( i = 0; i < path.GetMaxNoOfSubPaths(); i = i + 1 )
  IconPathData2.InitSubPath( i, path.GetNoOfEdges( i ));
  IconPathData2.AddCopy( i, path, i, 0, path.GetNoOfEdges( i ));

Anothwer approach would be to use the Bitmap resources instead of SVG. In this case you can load the SVG data into a graphic editor and raster from it a PNG File. Then add this file to EmWi as a Bitmap resource. This is the common way how you add graphics to a GUI application. The usage of SVG makes sense only when the original data is obtained dynamically and you need to raster it at the runtime of the application.

Hope it helps you.

Best regards

Paul Banach

Ask Embedded Wizard

Welcome to the question and answer site for Embedded Wizard users and UI developers.

Ask your question and receive answers from the Embedded Wizard support team or from other members of the community!

Embedded Wizard Website | Privacy Policy | Imprint