mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-31 01:11:06 +02:00
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:
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user