SVG to XAML conversion problems
#1
We have several thousand SVG files that we are attempting to convert to XAML using the Ab2d.ReaderSVG library.

After conversion there are many lines/strokes that are "off": the end-points are moved causing unsightly overlap.

We've tried updating to newer versions of the library, as well as increasing the number of decimal places (up to 6) with no noticable difference.

The attached ZIP file includes a document illustrating the issue, as well as a sample input SVG and converted XAML file.

We hope that you will work with us to help improve the quality of the XAML graphics that are produced by the ReaderSVG library.


Attached Files
.zip   SVG to XAML conversion issues.zip (Size: 379.86 KB / Downloads: 4)
#2
I checked the svg files you sent and discovered that the problem is caused by the fact that WPF handles miter limit differently as it is defined in svg standard (as is used by IE and Adobe Illustrator).

The definition in svg standard can be read here: http://www.w3.org/TR/SVG11/painting.html...Properties

Here the miter limit defines an angle at which the miter line cap is changed in bevel line cap.

But in WPF the miter limit defines how far away the miter is allowed to go. For example if miter limit is 4 (currently set as default value from ReaderSvg) and line thickness is 20, than the miter can extent 20 * 4 = 80 points away from the line connection point.

To check the different we can use the following svg file:
Code:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
   x="0px" y="0px" width="300px" height="180px" viewBox="0 0 400 180">

    <g >
        <path fill="#FFFFFF" stroke="red" stroke-linejoin="miter" stroke-miterlimit="1" stroke-width="20"
        d="M20,100 L40,20 60,100" transform="translate(0 0)"/>
        
        <path fill="#FFFFFF" stroke="red" stroke-linejoin="miter" stroke-miterlimit="2" stroke-width="20"
        d="M20,100 L40,20 60,100" transform="translate(50 0)"/>
        
        <path fill="#FFFFFF" stroke="red" stroke-linejoin="miter" stroke-miterlimit="3" stroke-width="20"
        d="M20,100 L40,20 60,100" transform="translate(100 0)"/>
        
        <path fill="#FFFFFF" stroke="red" stroke-linejoin="miter" stroke-miterlimit="4" stroke-width="20"
        d="M20,100 L40,20 60,100" transform="translate(150 0)"/>
        
        <path fill="#FFFFFF" stroke="red" stroke-linejoin="miter" stroke-miterlimit="5" stroke-width="20"
        d="M20,100 L40,20 60,100" transform="translate(200 0)"/>
        
        <path fill="#FFFFFF" stroke="red" stroke-linejoin="miter" stroke-miterlimit="6" stroke-width="20"
        d="M20,100 L40,20 60,100" transform="translate(250 0)"/>        
    </g>

</svg>

The svg file create 6 lines with different miter limit setting (the first has miter limit set to 1; the last has it set to 6).

IE (and Adobe Illustrator) produce the following image:
[Image: http://www.wpf-graphics.com/images/forum...0limit.PNG]

The ViewerSvg creates the following image:
[Image: http://www.wpf-graphics.com/images/forum... limit.PNG]

The difference is caused by the different handling of miter limit values by WPF and IE.


At first it looks like WPF's way of doing it brings more control to the end results. But it has a big disadvantage that becomes a big problem in your svg sample file.

The problem is when for example the first line goes from 0,0 to 0,100 - straight up. Than the lines continues to 0,80 - 20 points straight down. Here the WPF draws the miter because it considers this as 180 degrees turn. If the line thickness there would be 10 and miter limit would be 4, than the miter would extent the line to 0,140. So instead of having a line from 0,0 to 0,100 (going down on the same line is not shown), we have a line from 0,0 to 0,140.

In the svg's way this problem cannot happen, because at 180 degrees the line cap just turns into bevel.

The following is the part from the xaml file created from the sample svg file:
Code:
<Path Fill="White" Stroke="Black" StrokeThickness="0.5" StrokeMiterLimit="4" Data="F1M82.877,128.131L82.877,126.665 82.881,126.731C82.863,126.343 83.465,126.005 84.22,125.98 84.98,125.95 85.607,126.246 85.625,126.626 85.627,126.682 85.617,126.736 85.596,126.789L85.594,126.726 85.576,131.18 85.634,131.18C86.327,131.409,86.856,131.817,86.869,132.272L86.851,132.182 86.939,133.207C86.964,133.965 85.761,134.619 84.25,134.671 82.749,134.719 81.493,134.134 81.444,133.393L81.449,133.406 81.391,132.446 81.4,132.452C81.382,131.88,81.976,131.376,82.957,131.138L82.945,131.142 82.892,127.944C82.916,128.257,82.877,128.131,82.877,128.131z">
    <Path.RenderTransform>
      <TransformGroup>
        <TranslateTransform X="-81" Y="-125"/>
        <ScaleTransform ScaleX="50" ScaleY="50"/>
      </TransformGroup>
    </Path.RenderTransform>
  </Path>

Currently the image is strange. If you change the miter limit in the sample to 1, the image suddenly becomes much more clear. The following image shows the differences (the last image is created without setting the StrokMiterLimit value - this is the same as setting it to its default value of 10):
[Image: http://www.wpf-graphics.com/images/forum...rLimit.png]

I have analyzed the path data and seen that there are lost of 180 degrees turns in the path - those turns creates the biggest problems.


Unfortunately I do not see any perfect solution for this problem.

Currently I am using 4 as the default value for the miter limit (it is defined as default in svg specifiaction). But this surely is not the optimal value.

I think that the best solution would be to just always use 1 as miter limit - this would minimize the "damage" that is done by different WPF approach.

A quick workaround for this problem would be to replace all:
StrokeMiterLimit="4"
with
StrokeMiterLimit="1" in the xaml.

This change would make the sample svg file look correct.

I will try to prepare a fixed version until the end of this week.
Andrej Benedik
#3
I have just published a new version of ReaderSvg v 4.5 that has an additional OverrideMiterLimit property.

Unfortunately there is no way to render miter limits as in svg specifications. But with the OverrideMiterLimit it is possible to minimize the problems that are crated with different WPF rendering. The property overrides the miter limit that is set in svg file and use any other value instead.

For backwards compatibility the default value in RaederSvg is set to 0. This value disables overriding and used value defined in svg file - when the miter limit is not defined in svg file a value of 4 is uses because it is the default value for svg. (note: in ViewerSvg the value of 2 is used by default).

When there are some problem similar to those described in the previous posts, you can set the OverrideMiterLimit to 1 or 2. When you would like to minimize the artifacts created by WPF rendering and can "live" with some sharp edges being cut, set the value to 1. Setting the value to 2 would still produce some small artifacts (but much less as before) and would not cut the sharp edges so soon.
Andrej Benedik
#4
Thank you for the information.

The miter limit (which is standardized as 4 in the source SVG files) is indeed the culprit. We've been able to convert the XAML output to use a miter limit of 1 to resolve this issue.

Thank you again for your excellent analysis and information above regarding this issue. With the conversion in place we are able to convert all the nuances of the source SVG files to XAML with excellent results.
#5
the quality of the XAML graphics that are produced by the ReaderSVG library.
  


Forum Jump:


Users browsing this thread:
1 Guest(s)