add svg alphalevel, add full resize

Origin commit data
------------------
Branch: ni/coolstream
Commit: 6de84a4caf
Author: TangoCash <eric@loxat.de>
Date: 2021-10-27 (Wed, 27 Oct 2021)


------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
TangoCash
2021-10-27 21:30:09 +02:00
committed by vanhofen
parent d33277e44c
commit 70bb2497c6
3 changed files with 85 additions and 39 deletions

View File

@@ -195,6 +195,7 @@ void nsvgDelete(NSVGimage* image);
#ifdef NANOSVG_IMPLEMENTATION
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
@@ -211,6 +212,7 @@ void nsvgDelete(NSVGimage* image);
#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
#define NSVG_RGBA(r, g, b, a) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16) | ((unsigned int)a << 24))
#ifdef _MSC_VER
#pragma warning (disable: 4996) // Switch off security warnings
@@ -304,7 +306,7 @@ static void nsvg__parseElement(char* s,
// Get attribs
while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3)
{
char* name = NULL;
char* aname = NULL;
char* value = NULL;
// Skip white space before the attrib name
@@ -315,7 +317,7 @@ static void nsvg__parseElement(char* s,
end = 1;
break;
}
name = s;
aname = s;
// Find end of the attrib name.
while (*s && !nsvg__isspace(*s) && *s != '=') s++;
if (*s)
@@ -336,9 +338,9 @@ static void nsvg__parseElement(char* s,
}
// Store only well formed attributes
if (name && value)
if (aname && value)
{
attr[nattr++] = name;
attr[nattr++] = aname;
attr[nattr++] = value;
}
}
@@ -1364,7 +1366,9 @@ static const char* nsvg__getNextPathItem(const char* s, char* it)
static unsigned int nsvg__parseColorHex(const char* str)
{
unsigned int r=0, g=0, b=0;
unsigned int r=0, g=0, b=0, a=0;
if (sscanf(str, "#%2x%2x%2x%2x", &r, &g, &b, &a) == 4 ) // 2 digit hex with alpha
return NSVG_RGBA(r, g, b, a);
if (sscanf(str, "#%2x%2x%2x", &r, &g, &b) == 3 ) // 2 digit hex
return NSVG_RGB(r, g, b);
if (sscanf(str, "#%1x%1x%1x", &r, &g, &b) == 3 ) // 1 digit hex, e.g. #abc -> 0xccbbaa
@@ -1382,6 +1386,21 @@ static unsigned int nsvg__parseColorRGB(const char* str)
return NSVG_RGB(128, 128, 128);
}
static unsigned int nsvg__parseColorRGBA(const char* str)
{
unsigned int r=0, g=0, b=0;
float a = 1.0;
if (sscanf(str, "rgba(%u, %u, %u, %f)", &r, &g, &b, &a) == 4) // decimal integers
{
float alpha = a * 255;
if (alpha < 1.0) alpha = 1.0;
return NSVG_RGBA(r, g, b, alpha);
}
if (sscanf(str, "rgba(%u%%, %u%%, %u%%, %f)", &r, &g, &b, &a) == 4) // decimal integer percentage
return NSVG_RGBA((r*255)/100, (g*255)/100, (b*255)/100, (a*255)/100);
return NSVG_RGBA(128, 128, 128, 1.0);
}
typedef struct NSVGNamedColor
{
const char* name;
@@ -1567,6 +1586,8 @@ static unsigned int nsvg__parseColor(const char* str)
return nsvg__parseColorHex(str);
else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(')
return nsvg__parseColorRGB(str);
else if (len >= 5 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == 'a' && str[4] == '(')
return nsvg__parseColorRGBA(str);
return nsvg__parseColorName(str);
}
@@ -1923,6 +1944,14 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
{
attr->hasFill = 1;
attr->fillColor = nsvg__parseColor(value);
// if the fillColor has an alpha value then use it to
// set the fillOpacity
if (attr->fillColor & 0xFF000000)
{
attr->fillOpacity = ((attr->fillColor >> 24) & 0xFF) / 255.0;
// remove the alpha value from the color
attr->fillColor &= 0x00FFFFFF;
}
}
}
else if (strcmp(name, "opacity") == 0)
@@ -1948,6 +1977,14 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
{
attr->hasStroke = 1;
attr->strokeColor = nsvg__parseColor(value);
// if the strokeColor has an alpha value then use it to
// set the strokeOpacity
if (attr->strokeColor & 0xFF000000)
{
attr->strokeOpacity = ((attr->strokeColor >> 24) & 0xFF) / 255.0;
// remove the alpha value from the color
attr->strokeColor &= 0x00FFFFFF;
}
}
}
else if (strcmp(name, "stroke-width") == 0)

View File

@@ -62,6 +62,10 @@ void nsvgRasterize(NSVGrasterizer* r,
NSVGimage* image, float tx, float ty, float scale,
unsigned char* dst, int w, int h, int stride);
void nsvgRasterizeFull(NSVGrasterizer* r, NSVGimage* image,
float tx, float ty, float scalex, float scaley,
unsigned char* dst, int w, int h, int stride);
// Deletes rasterizer context.
void nsvgDeleteRasterizer(NSVGrasterizer*);
@@ -391,7 +395,7 @@ static void nsvg__flattenCubicBez(NSVGrasterizer* r,
nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type);
}
static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scalex, float scaley)
{
int i, j;
NSVGpath* path;
@@ -400,14 +404,14 @@ static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
{
r->npoints = 0;
// Flatten path
nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
nsvg__addPathPoint(r, path->pts[0]*scalex, path->pts[1]*scaley, 0);
for (i = 0; i < path->npts-1; i += 3)
{
float* p = &path->pts[i*2];
nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0);
nsvg__flattenCubicBez(r, p[0]*scalex,p[1]*scaley, p[2]*scalex,p[3]*scaley, p[4]*scalex,p[5]*scaley, p[6]*scalex,p[7]*scaley, 0, 0);
}
// Close path
nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
nsvg__addPathPoint(r, path->pts[0]*scalex, path->pts[1]*scaley, 0);
// Build edges
for (i = 0, j = r->npoints-1; i < r->npoints; j = i++)
nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y);
@@ -807,7 +811,7 @@ static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoi
}
}
static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale)
static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scalex, float scaley)
{
int i, j, closed;
NSVGpath* path;
@@ -815,17 +819,17 @@ static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float
float miterLimit = shape->miterLimit;
int lineJoin = shape->strokeLineJoin;
int lineCap = shape->strokeLineCap;
float lineWidth = shape->strokeWidth * scale;
float lineWidth = shape->strokeWidth * (scalex+scaley)*0.5;
for (path = shape->paths; path != NULL; path = path->next)
{
// Flatten path
r->npoints = 0;
nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER);
nsvg__addPathPoint(r, path->pts[0]*scalex, path->pts[1]*scaley, NSVG_PT_CORNER);
for (i = 0; i < path->npts-1; i += 3)
{
float* p = &path->pts[i*2];
nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER);
nsvg__flattenCubicBez(r, p[0]*scalex,p[1]*scaley, p[2]*scalex,p[3]*scaley, p[4]*scalex,p[5]*scaley, p[6]*scalex,p[7]*scaley, 0, NSVG_PT_CORNER);
}
if (r->npoints < 2)
continue;
@@ -874,7 +878,7 @@ static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float
dashOffset -= shape->strokeDashArray[idash];
idash = (idash + 1) % shape->strokeDashCount;
}
dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale;
dashLen = (shape->strokeDashArray[idash] - dashOffset) * (scalex+scaley)*0.5;
for (j = 1; j < r->npoints2; )
{
@@ -899,7 +903,7 @@ static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float
// Advance dash pattern
dashState = !dashState;
idash = (idash+1) % shape->strokeDashCount;
dashLen = shape->strokeDashArray[idash] * scale;
dashLen = shape->strokeDashArray[idash] * (scalex+scaley)*0.5;
// Restart
cur.x = x;
cur.y = y;
@@ -1097,7 +1101,7 @@ static inline int nsvg__div255(int x)
}
static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y,
float tx, float ty, float scale, NSVGcachedPaint* cache)
float tx, float ty, float scalex, float scaley, NSVGcachedPaint* cache)
{
if (cache->type == NSVG_PAINT_COLOR)
@@ -1142,9 +1146,9 @@ static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* co
int i, cr, cg, cb, ca;
unsigned int c;
fx = ((float)x - tx) / scale;
fy = ((float)y - ty) / scale;
dx = 1.0f / scale;
fx = ((float)x - tx) / scalex;
fy = ((float)y - ty) / scaley;
dx = 1.0f / scalex;
for (i = 0; i < count; i++)
{
@@ -1190,9 +1194,9 @@ static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* co
int i, cr, cg, cb, ca;
unsigned int c;
fx = ((float)x - tx) / scale;
fy = ((float)y - ty) / scale;
dx = 1.0f / scale;
fx = ((float)x - tx) / scalex;
fy = ((float)y - ty) / scaley;
dx = 1.0f / scalex;
for (i = 0; i < count; i++)
{
@@ -1232,7 +1236,7 @@ static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* co
}
}
static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule)
static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scalex, float scaley, NSVGcachedPaint* cache, char fillRule)
{
NSVGactiveEdge *active = NULL;
int y, s;
@@ -1331,7 +1335,7 @@ static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, fl
if (xmax > r->width-1) xmax = r->width-1;
if (xmin <= xmax)
{
nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache);
nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scalex, scaley, cache);
}
}
@@ -1519,8 +1523,8 @@ static void dumpEdges(NSVGrasterizer* r, const char* name)
}
*/
void nsvgRasterize(NSVGrasterizer* r,
NSVGimage* image, float tx, float ty, float scale,
void nsvgRasterizeFull(NSVGrasterizer* r,
NSVGimage* image, float tx, float ty, float scalex, float scaley,
unsigned char* dst, int w, int h, int stride)
{
NSVGshape *shape = NULL;
@@ -1540,8 +1544,8 @@ void nsvgRasterize(NSVGrasterizer* r,
if (r->scanline == NULL) return;
}
for (i = 0; i < h; i++)
memset(&dst[i*stride], 0, w*4);
// for (i = 0; i < h; i++)
// memset(&dst[i*stride], 0, w*4);
for (shape = image->shapes; shape != NULL; shape = shape->next)
{
@@ -1554,7 +1558,7 @@ void nsvgRasterize(NSVGrasterizer* r,
r->freelist = NULL;
r->nedges = 0;
nsvg__flattenShape(r, shape, scale);
nsvg__flattenShape(r, shape, scalex, scaley);
// Scale and translate edges
for (i = 0; i < r->nedges; i++)
@@ -1572,15 +1576,15 @@ void nsvgRasterize(NSVGrasterizer* r,
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
nsvg__initPaint(&cache, &shape->fill, shape->opacity);
nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule);
nsvg__rasterizeSortedEdges(r, tx,ty, scalex, scaley, &cache, shape->fillRule);
}
if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f)
if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * (scalex+scaley)*0.5) > 0.01f)
{
nsvg__resetPool(r);
r->freelist = NULL;
r->nedges = 0;
nsvg__flattenShapeStroke(r, shape, scale);
nsvg__flattenShapeStroke(r, shape, scalex, scaley);
// dumpEdges(r, "edge.svg");
@@ -1600,7 +1604,7 @@ void nsvgRasterize(NSVGrasterizer* r,
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
nsvg__initPaint(&cache, &shape->stroke, shape->opacity);
nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO);
nsvg__rasterizeSortedEdges(r, tx,ty, scalex, scaley, &cache, NSVG_FILLRULE_NONZERO);
}
}
@@ -1612,4 +1616,11 @@ void nsvgRasterize(NSVGrasterizer* r,
r->stride = 0;
}
void nsvgRasterize(NSVGrasterizer* r,
NSVGimage* image, float tx, float ty, float scale,
unsigned char* dst, int w, int h, int stride)
{
return nsvgRasterizeFull(r, image, tx, ty, scale, scale, dst, w, h, stride);
}
#endif

View File

@@ -133,14 +133,12 @@ int svg_load_resize(const char *name, unsigned char **buffer, int* ox, int* oy,
goto error;
}
float scale,scale_w,scale_h;
float scale_w,scale_h;
scale_w = *dx/w;
scale_h = *dy/h;
scale = std::max(scale_w,scale_h);
w = (int)(w*scale);
h = (int)(h*scale);
w = (int)(w*scale_w);
h = (int)(h*scale_h);
free(*buffer);
*buffer = (unsigned char*) malloc(w*h*4);
@@ -155,7 +153,7 @@ int svg_load_resize(const char *name, unsigned char **buffer, int* ox, int* oy,
}
//printf("[SVG] rasterizing image %d x %d\n", w, h);
nsvgRasterize(rast, image, 0, 0, scale, *buffer, w, h, w*4);
nsvgRasterizeFull(rast, image, 0, 0, scale_w, scale_h, *buffer, w, h, w*4);
error:
nsvgDeleteRasterizer(rast);