pocketsvg/PocketSVG

Can't parse SVG tags such as <defs> and <g>

jcooperation0137 opened this issue · 2 comments

Steps to reproduce the issue

  1. I've tried to draw the following svg file by using PocketSVG framework
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none" x="0px" y="0px" width="100px" height="86px" viewBox="0 0 100 86">
<defs>
<g id="Layer0_0_FILL">
<path fill="#000000" stroke="none" d="
M 96.75 19.25
Q 96.65 10.9 96.8 7.2 93.25 7.2 90 7
L 48 7
Q 45.1 7 43.65 7 41.05 7 39.35 7.25 28.75 12.45 14.6 19.45 8 22.7 4.45 24.45
L 5.45 68
Q 5.75 73.15 6.05 78.8 9.1 79.05 14 79
L 80.15 78.2 96.8 56.75
Q 96.95 40.45 96.75 19.25
M 86.4 19.45
Q 90.35 15.35 94.2 11.75
L 94.25 56.3 80.85 73.7 80.7 24.75
Q 82.45 23.5 86.4 19.45
M 93.6 9.65
Q 91 11.85 86.7 16.2 82.4 20.5 79.45 23.25
L 11.85 23.15 39.65 9.5 93.6 9.65
M 7.15 44.2
Q 7 27.55 6.8 25.55
L 78.35 25.4 78.25 76.35 7.85 76.45
Q 7.3 60.85 7.15 44.2
M 75.05 31.2
Q 71.85 31.05 66.15 31.1 60.35 31.15 43.4 30.9 26.4 30.6 14.45 30.9 14.3 35.1 14.2 39 14.05 42.9 14.15 53.05 14.15 63.15 14.35 70.65 36 70.3 56.75 70.25 71.65 70.2 75.45 70.15
L 75.05 31.2
M 44.7 33.15
Q 63.35 33.4 73.15 33.25
L 73.15 68.5 16.75 68.25 16.9 32.9
Q 26 32.9 44.7 33.15 Z"/>

<path fill="#A37A51" stroke="none" d="
M 6.8 25.55
Q 7 27.55 7.15 44.2 7.3 60.85 7.85 76.45
L 78.25 76.35 78.35 25.4 6.8 25.55
M 66.15 31.1
Q 71.85 31.05 75.05 31.2
L 75.45 70.15
Q 71.65 70.2 56.75 70.25 36 70.3 14.35 70.65 14.15 63.15 14.15 53.05 14.05 42.9 14.2 39 14.3 35.1 14.45 30.9 26.4 30.6 43.4 30.9 60.35 31.15 66.15 31.1
M 73.15 33.25
Q 63.35 33.4 44.7 33.15 26 32.9 16.9 32.9
L 16.75 68.25 73.15 68.5 73.15 33.25 Z"/>

<path fill="#CC9966" stroke="none" d="
M 86.7 16.2
Q 91 11.85 93.6 9.65
L 39.65 9.5 11.85 23.15 79.45 23.25
Q 82.4 20.5 86.7 16.2 Z"/>

<path fill="#B98857" stroke="none" d="
M 94.2 11.75
Q 90.35 15.35 86.4 19.45 82.45 23.5 80.7 24.75
L 80.85 73.7 94.25 56.3 94.2 11.75 Z"/>
</g>
</defs>

<g transform="matrix( 1, 0, 0, 1, 0,0) ">
<use xlink:href="#Layer0_0_FILL"/>
</g>
</svg>
  1. PocketSVG has not consider common svg tags such as "defs" and "g"
NSArray *svgParser::parse(NSMapTable ** const aoAttributes)
{
    _xmlReader = xmlReaderForDoc((xmlChar *)[_source UTF8String], NULL, NULL, 0);
    NSCAssert(_xmlReader, @"Failed to create XML parser");

    if(aoAttributes)
        *aoAttributes = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory|NSMapTableObjectPointerPersonality
                                              valueOptions:NSMapTableStrongMemory];
    NSMutableArray * const paths = [NSMutableArray new];

    NSUInteger depthWithinUnknownElement = 0;

    while(xmlTextReaderRead(_xmlReader) == 1) {
        int const type = xmlTextReaderNodeType(_xmlReader);
        const char * const tag = (char *)xmlTextReaderConstName(_xmlReader);
        
        CGPathRef path = NULL;
        if(depthWithinUnknownElement > 0) {
            if(type == XML_READER_TYPE_ELEMENT && !xmlTextReaderIsEmptyElement(_xmlReader))
                ++depthWithinUnknownElement;
            else if(type == XML_READER_TYPE_END_ELEMENT)
                --depthWithinUnknownElement;
        } else if(type == XML_READER_TYPE_ELEMENT && (strcasecmp(tag, "svg") == 0) {
            pushGroup(readAttributes());
        }

As you can see, the framework only consider "svg" tag as a group.
I think PocketSVG had better consider more group tags as follows

        } else if(type == XML_READER_TYPE_ELEMENT &&
                  (strcasecmp(tag, "svg") == 0 ||
                   strcasecmp(tag, "defs") == 0) ||
                  strcasecmp(tag, "g") == 0) {
            pushGroup(readAttributes());
        }

Specifications

  • PocketSVG Version: 2.7.0
  • Xcode Version: 12.2
  • iOS/macOS Version: 14.2/Catalina

Hello, and thank you for raising this. Could you please submit a pull request with your proposed solution?

Closing this as we're not going to support these tags for now.