- added parsing for per shape opacity - added support for per shape opacity in rasteriser
This commit is contained in:
parent
1b894120be
commit
95caf10c0b
@ -112,6 +112,7 @@ struct NSVGshape
|
||||
{
|
||||
struct NSVGpaint fill; // Fill paint
|
||||
struct NSVGpaint stroke; // Stroke paint
|
||||
float opacity; // Opacity of the shape.
|
||||
float strokeWidth; // Stroke width (scaled)
|
||||
float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy].
|
||||
struct NSVGpath* paths; // Linked list of paths in the image.
|
||||
@ -156,6 +157,8 @@ void nsvgDelete(struct NSVGimage* image);
|
||||
#define NSVG_ALIGN_MEET 1
|
||||
#define NSVG_ALIGN_SLICE 2
|
||||
|
||||
#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996) // Switch off security warnings
|
||||
#pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
|
||||
@ -335,6 +338,7 @@ struct NSVGattrib
|
||||
float xform[6];
|
||||
unsigned int fillColor;
|
||||
unsigned int strokeColor;
|
||||
float opacity;
|
||||
float fillOpacity;
|
||||
float strokeOpacity;
|
||||
char fillGradient[64];
|
||||
@ -536,13 +540,14 @@ static struct NSVGparser* nsvg__createParser()
|
||||
|
||||
// Init style
|
||||
nsvg__xformIdentity(p->attr[0].xform);
|
||||
p->attr[0].fillColor = 0;
|
||||
p->attr[0].strokeColor = 0;
|
||||
p->attr[0].fillColor = NSVG_RGB(0,0,0);
|
||||
p->attr[0].strokeColor = NSVG_RGB(0,0,0);
|
||||
p->attr[0].opacity = 1;
|
||||
p->attr[0].fillOpacity = 1;
|
||||
p->attr[0].strokeOpacity = 1;
|
||||
p->attr[0].stopOpacity = 1;
|
||||
p->attr[0].strokeWidth = 1;
|
||||
p->attr[0].hasFill = 0;
|
||||
p->attr[0].hasFill = 1;
|
||||
p->attr[0].hasStroke = 0;
|
||||
p->attr[0].visible = 1;
|
||||
|
||||
@ -743,6 +748,7 @@ static void nsvg__addShape(struct NSVGparser* p)
|
||||
|
||||
scale = nsvg__maxf(fabsf(attr->xform[0]), fabsf(attr->xform[3]));
|
||||
shape->strokeWidth = attr->strokeWidth * scale;
|
||||
shape->opacity = attr->opacity;
|
||||
|
||||
shape->paths = p->plist;
|
||||
p->plist = NULL;
|
||||
@ -929,8 +935,6 @@ static float nsvg__actualLength(struct NSVGparser* p)
|
||||
}
|
||||
|
||||
|
||||
#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
|
||||
|
||||
static unsigned int nsvg__parseColorHex(const char* str)
|
||||
{
|
||||
unsigned int c = 0, r = 0, g = 0, b = 0;
|
||||
@ -1389,6 +1393,8 @@ static int nsvg__parseAttr(struct NSVGparser* p, const char* name, const char* v
|
||||
attr->hasFill = 1;
|
||||
attr->fillColor = nsvg__parseColor(value);
|
||||
}
|
||||
} else if (strcmp(name, "opacity") == 0) {
|
||||
attr->opacity = nsvg__parseFloat(p, value, 2);
|
||||
} else if (strcmp(name, "fill-opacity") == 0) {
|
||||
attr->fillOpacity = nsvg__parseFloat(p, value, 2);
|
||||
} else if (strcmp(name, "stroke") == 0) {
|
||||
|
@ -394,6 +394,16 @@ static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u)
|
||||
return nsvg__RGBA(r,g,b,a);
|
||||
}
|
||||
|
||||
static unsigned int nsvg__applyOpacity(unsigned int c, float u)
|
||||
{
|
||||
int iu = (float)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f);
|
||||
int r = (c) & 0xff;
|
||||
int g = (c>>8) & 0xff;
|
||||
int b = (c>>16) & 0xff;
|
||||
int a = (((c>>24) & 0xff)*iu) >> 8;
|
||||
return nsvg__RGBA(r,g,b,a);
|
||||
}
|
||||
|
||||
static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y,
|
||||
float tx, float ty, float scale, struct NSVGcachedPaint* cache)
|
||||
{
|
||||
@ -670,7 +680,7 @@ static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int str
|
||||
}
|
||||
|
||||
|
||||
static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* paint)
|
||||
static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* paint, float opacity)
|
||||
{
|
||||
int i, j;
|
||||
struct NSVGgradient* grad;
|
||||
@ -678,7 +688,7 @@ static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* pai
|
||||
cache->type = paint->type;
|
||||
|
||||
if (paint->type == NSVG_PAINT_COLOR) {
|
||||
cache->colors[0] = paint->color;
|
||||
cache->colors[0] = nsvg__applyOpacity(paint->color, opacity);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -692,14 +702,13 @@ static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* pai
|
||||
cache->colors[i] = 0;
|
||||
} if (grad->nstops == 1) {
|
||||
for (i = 0; i < 256; i++)
|
||||
cache->colors[i] = grad->stops[i].color;
|
||||
cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity);
|
||||
} else {
|
||||
unsigned int ca, cb;
|
||||
float ua, ub, du, u;
|
||||
int ia, ib, count;
|
||||
|
||||
ca = grad->stops[0].color;
|
||||
cb = grad->stops[grad->nstops-1].color;
|
||||
ca = nsvg__applyOpacity(grad->stops[0].color, opacity);
|
||||
ua = nsvg__clampf(grad->stops[0].offset, 0, 1);
|
||||
ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1);
|
||||
ia = ua * 255.0f;
|
||||
@ -709,8 +718,8 @@ static void nsvg__initPaint(struct NSVGcachedPaint* cache, struct NSVGpaint* pai
|
||||
}
|
||||
|
||||
for (i = 0; i < grad->nstops-1; i++) {
|
||||
ca = grad->stops[i].color;
|
||||
cb = grad->stops[i+1].color;
|
||||
ca = nsvg__applyOpacity(grad->stops[i].color, opacity);
|
||||
cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity);
|
||||
ua = nsvg__clampf(grad->stops[i].offset, 0, 1);
|
||||
ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1);
|
||||
ia = ua * 255.0f;
|
||||
@ -778,7 +787,7 @@ void nsvgRasterize(struct NSVGrasterizer* r,
|
||||
qsort(r->edges, r->nedges, sizeof(struct NSVGedge), nsvg__cmpEdge);
|
||||
|
||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||
nsvg__initPaint(&cache, &shape->fill);
|
||||
nsvg__initPaint(&cache, &shape->fill, shape->opacity);
|
||||
|
||||
nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user