Skip to content

Commit

Permalink
NanoSVG: basic support for stylesheets.
Browse files Browse the repository at this point in the history
Based on memononen/nanosvg#175

(cherry picked from commit 2cd7c06)
  • Loading branch information
dsa-t committed Sep 8, 2023
1 parent 96a3621 commit b0e0932
Showing 1 changed file with 120 additions and 5 deletions.
125 changes: 120 additions & 5 deletions thirdparty/nanosvg/nanosvg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,13 @@ typedef struct NSVGattrib
char visible;
} NSVGattrib;

typedef struct NSVGstyles
{
char* name;
char* description;
struct NSVGstyles* next;
} NSVGstyles;

typedef struct NSVGparser
{
NSVGattrib attr[NSVG_MAX_ATTR];
Expand All @@ -361,13 +368,15 @@ typedef struct NSVGparser
int cpts;
NSVGpath* plist;
NSVGimage* image;
NSVGstyles* styles;
NSVGgradientData* gradients;
NSVGshape* shapesTail;
float viewMinx, viewMiny, viewWidth, viewHeight;
int alignX, alignY, alignType;
float dpi;
char pathFlag;
char defsFlag;
char styleFlag;
} NSVGparser;

static void nsvg__xformIdentity( float* t )
Expand Down Expand Up @@ -612,6 +621,21 @@ static NSVGparser* nsvg__createParser()
}


static void nsvg__deleteStyles( NSVGstyles* style )
{
while( style )
{
NSVGstyles* next = style->next;
if( style->name != NULL )
free( style->name );
if( style->description != NULL )
free( style->description );
free( style );
style = next;
}
}


static void nsvg__deletePaths( NSVGpath* path )
{
while( path )
Expand Down Expand Up @@ -652,6 +676,7 @@ static void nsvg__deleteParser( NSVGparser* p )
{
if( p != NULL )
{
nsvg__deleteStyles( p->styles );
nsvg__deletePaths( p->plist );
nsvg__deleteGradientData( p->gradients );
nsvgDelete( p->image );
Expand Down Expand Up @@ -2108,6 +2133,18 @@ static int nsvg__parseAttr( NSVGparser* p, const char* name, const char* value )
strncpy( attr->id, value, 63 );
attr->id[63] = '\0';
}
else if( strcmp( name, "class" ) == 0 )
{
NSVGstyles* style = p->styles;
while( style )
{
if( strcmp( style->name + 1, value ) == 0 )
{
nsvg__parseStyle( p, style->description );
}
style = style->next;
}
}
else
{
return 0;
Expand Down Expand Up @@ -3352,7 +3389,7 @@ static void nsvg__startElement( void* ud, const char* el, const char** attr )

if( p->defsFlag )
{
// Skip everything but gradients in defs
// Skip everything but gradients and styles in defs
if( strcmp( el, "linearGradient" ) == 0 )
{
nsvg__parseGradient( p, attr, NSVG_PAINT_LINEAR_GRADIENT );
Expand All @@ -3365,6 +3402,10 @@ static void nsvg__startElement( void* ud, const char* el, const char** attr )
{
nsvg__parseGradientStop( p, attr );
}
else if( strcmp( el, "style" ) == 0 )
{
p->styleFlag = 1;
}

return;
}
Expand All @@ -3376,7 +3417,7 @@ static void nsvg__startElement( void* ud, const char* el, const char** attr )
}
else if( strcmp( el, "path" ) == 0 )
{
if( p->pathFlag ) // Do not allow nested paths.
if( p->pathFlag ) // Do not allow nested paths.
return;

nsvg__pushAttr( p );
Expand Down Expand Up @@ -3439,6 +3480,10 @@ static void nsvg__startElement( void* ud, const char* el, const char** attr )
{
nsvg__parseSVG( p, attr );
}
else if( strcmp( el, "style" ) == 0 )
{
p->styleFlag = 1;
}
}


Expand All @@ -3458,14 +3503,84 @@ static void nsvg__endElement( void* ud, const char* el )
{
p->defsFlag = 0;
}
else if( strcmp( el, "style" ) == 0 )
{
p->styleFlag = 0;
}
}


static char* nsvg__strndup( const char* s, size_t n )
{
char* result;
size_t len = strlen( s );

if( n < len )
len = n;

result = (char*) malloc( len + 1 );
if( !result )
return 0;

result[len] = '\0';
return (char*) memcpy( result, s, len );
}


static void nsvg__content( void* ud, const char* s )
{
NSVG_NOTUSED( ud );
NSVG_NOTUSED( s );
// empty
NSVGparser* p = (NSVGparser*) ud;
if( p->styleFlag )
{
int state = 0;
int class_count = 0;
const char* start = s;
while( *s )
{
char c = *s;
if( state == 2 )
{
if( c == '{' )
{
start = s + 1;
}
else if( c == '}' )
{
NSVGstyles* style = p->styles;
while( class_count > 0 )
{
style->description = nsvg__strndup( start, (size_t) ( s - start ) );
style = style->next;
--class_count;
}
state = 0;
}
}
else if( nsvg__isspace( c ) || c == '{' || c == ',' )
{
if( state == 1 )
{
if( *start == '.' )
{
NSVGstyles* next = p->styles;
p->styles = (NSVGstyles*) malloc( sizeof( NSVGstyles ) );
p->styles->description = NULL;
p->styles->next = next;
p->styles->name = nsvg__strndup( start, (size_t) ( s - start ) );
++class_count;
}
start = s + 1;
state = c == ',' ? 0 : 2;
}
}
else if( state == 0 )
{
start = s;
state = 1;
}
s++;
}
}
}


Expand Down

0 comments on commit b0e0932

Please sign in to comment.