diff --git a/example/demo.c b/example/demo.c index ea53cba..e1c3140 100644 --- a/example/demo.c +++ b/example/demo.c @@ -254,17 +254,17 @@ void drawCheckBox(struct NVGcontext* vg, const char* text, float x, float y, flo nvgText(vg, x+9+2, y+h*0.5f, cpToUTF8(ICON_CHECK,icon), NULL); } -void drawButton(struct NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, unsigned int col) +void drawButton(struct NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, struct NVGcolor col) { struct NVGpaint bg; char icon[8]; float cornerRadius = 4.0f; float tw = 0, iw = 0; - bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(255,255,255,col==0?16:32), nvgRGBA(0,0,0,col==0?16:32)); + bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(255,255,255,nvgIsBlack(col)?16:32), nvgRGBA(0,0,0,nvgIsBlack(col)?16:32)); nvgBeginPath(vg); nvgRoundedRect(vg, x+1,y+1, w-2,h-2, cornerRadius-1); - if (col != 0) { + if (!nvgIsBlack(col)) { nvgFillColor(vg, col); nvgFill(vg); } diff --git a/src/nanovg.c b/src/nanovg.c index 8ef1837..d23dc21 100644 --- a/src/nanovg.c +++ b/src/nanovg.c @@ -278,35 +278,40 @@ void nvgEndFrame(struct NVGcontext* ctx) ctx->params.renderFlush(ctx->params.userPtr, ctx->alphaBlend); } -unsigned int nvgRGB(unsigned char r, unsigned char g, unsigned char b) +struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b) { return nvgRGBA(r,g,b,255); } -unsigned int nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - return (r) | (g << 8) | (b << 16) | (a << 24); + struct NVGcolor color = {r/255.0f, g/255.0f, b/255.0f, a/255.0f}; + return color; } -unsigned int nvgTransRGBA(unsigned int c, unsigned char a) +struct NVGcolor nvgTransRGBA(struct NVGcolor c, unsigned char a) { - int r = (c) & 0xff; - int g = (c>>8) & 0xff; - int b = (c>>16) & 0xff; - return nvgRGBA(r,g,b,a); + c.a = a / 255.0f; + return c; } -unsigned int nvgLerpRGBA(unsigned int c0, unsigned int c1, float u) +struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u) { - int iu = (int)(nvg__clampf(u, 0.0f, 1.0f) * 256.0f); - int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8; - int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8; - int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8; - int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8; - return nvgRGBA(r,g,b,a); + int i; + float oneminu; + struct NVGcolor cint; + + u = nvg__clampf(u, 0.0f, 1.0f); + oneminu = 1.0f - u; + for( i = 0; i <4; ++i ) + { + cint.rgba[i] = c0.rgba[i] * oneminu + c1.rgba[i] * u; + } + + return cint; } -unsigned int nvgHSL(float h, float s, float l) +struct NVGcolor nvgHSL(float h, float s, float l) { return nvgHSLA(h,s,l,255); } @@ -324,22 +329,31 @@ static float nvg__hue(float h, float m1, float m2) return m1; } -unsigned int nvgHSLA(float h, float s, float l, unsigned char a) +struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a) { float m1, m2; - unsigned char r,g,b; + struct NVGcolor col; h = nvg__modf(h, 1.0f); if (h < 0.0f) h += 1.0f; s = nvg__clampf(s, 0.0f, 1.0f); l = nvg__clampf(l, 0.0f, 1.0f); m2 = l <= 0.5f ? (l * (1 + s)) : (l + s - l * s); m1 = 2 * l - m2; - r = (unsigned char)nvg__clampf(nvg__hue(h + 1.0f/3.0f, m1, m2) * 255.0f, 0, 255); - g = (unsigned char)nvg__clampf(nvg__hue(h, m1, m2) * 255.0f, 0, 255); - b = (unsigned char)nvg__clampf(nvg__hue(h - 1.0f/3.0f, m1, m2) * 255.0f, 0, 255); - return nvgRGBA(r,g,b,a); + col.r = nvg__clampf(nvg__hue(h + 1.0f/3.0f, m1, m2), 0.0f, 1.0f); + col.g = nvg__clampf(nvg__hue(h, m1, m2), 0.0f, 1.0f); + col.b = nvg__clampf(nvg__hue(h - 1.0f/3.0f, m1, m2), 0.0f, 1.0f); + col.a = a/255.0f; + return col; } +nvgIsBlack( struct NVGcolor col ) +{ + if( col.r == 0.0f && col.g == 0.0f && col.b == 0.0f && col.a == 0.0f ) + { + return 1; + } + return 0; +} static struct NVGstate* nvg__getState(struct NVGcontext* ctx) { @@ -396,7 +410,7 @@ static void nvg__xformPremultiply(float* t, float* s) memcpy(t, s2, sizeof(float)*6); } -static void nvg__setPaintColor(struct NVGpaint* p, unsigned int color) +static void nvg__setPaintColor(struct NVGpaint* p, struct NVGcolor color) { memset(p, 0, sizeof(*p)); nvg__xformIdentity(p->xform); @@ -511,7 +525,7 @@ void nvgScale(struct NVGcontext* ctx, float x, float y) } -void nvgStrokeColor(struct NVGcontext* ctx, unsigned int color) +void nvgStrokeColor(struct NVGcontext* ctx, struct NVGcolor color) { struct NVGstate* state = nvg__getState(ctx); nvg__setPaintColor(&state->stroke, color); @@ -524,7 +538,7 @@ void nvgStrokePaint(struct NVGcontext* ctx, struct NVGpaint paint) nvg__xformMultiply(state->stroke.xform, state->xform); } -void nvgFillColor(struct NVGcontext* ctx, unsigned int color) +void nvgFillColor(struct NVGcontext* ctx, struct NVGcolor color) { struct NVGstate* state = nvg__getState(ctx); nvg__setPaintColor(&state->fill, color); @@ -587,7 +601,7 @@ void nvgDeleteImage(struct NVGcontext* ctx, int image) struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, float sx, float sy, float ex, float ey, - unsigned int icol, unsigned int ocol) + struct NVGcolor icol, struct NVGcolor ocol) { struct NVGpaint p; float dx, dy, d; @@ -626,7 +640,7 @@ struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, float cx, float cy, float inr, float outr, - unsigned int icol, unsigned int ocol) + struct NVGcolor icol, struct NVGcolor ocol) { struct NVGpaint p; float r = (inr+outr)*0.5f; @@ -653,7 +667,7 @@ struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, float x, float y, float w, float h, float r, float f, - unsigned int icol, unsigned int ocol) + struct NVGcolor icol, struct NVGcolor ocol) { struct NVGpaint p; diff --git a/src/nanovg.h b/src/nanovg.h index edb5d9f..cd19adf 100644 --- a/src/nanovg.h +++ b/src/nanovg.h @@ -27,14 +27,26 @@ extern "C" { struct NVGcontext; +struct NVGcolor +{ + union + { + float rgba[4]; + struct + { + float r,g,b,a; + }; + }; +}; + struct NVGpaint { float xform[6]; float extent[2]; float radius; float feather; - unsigned int innerColor; - unsigned int outerColor; + struct NVGcolor innerColor; + struct NVGcolor outerColor; int image; int repeat; }; @@ -102,24 +114,27 @@ void nvgEndFrame(struct NVGcontext* ctx); // Colors in NanoVG are stored as unsigned ints in ABGR format. // Returns a color value from red, green, blue values. Alpha will be set to 255. -unsigned int nvgRGB(unsigned char r, unsigned char g, unsigned char b); +struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b); // Returns a color value from red, green, blue and alpha values. -unsigned int nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a); +struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Linearly interpoaltes from color c0 to c1, and returns resulting color value. -unsigned int nvgLerpRGBA(unsigned int c0, unsigned int c1, float u); +struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u); // Sets transparency of a color value. -unsigned int nvgTransRGBA(unsigned int c0, unsigned char a); +struct NVGcolor nvgTransRGBA(struct NVGcolor c0, unsigned char a); // Returns color value specified by hue, saturation and lightness. // HSL values are all in range [0..1], alpha will be set to 255. -unsigned int nvgHSL(float h, float s, float l); +struct NVGcolor nvgHSL(float h, float s, float l); // Returns color value specified by hue, saturation and lightness and alpha. // HSL values are all in range [0..1], alpha in range [0..255] -unsigned int nvgHSLA(float h, float s, float l, unsigned char a); +struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a); + +// Returns 1 if col.rgba is 0.0f,0.0f,0.0f,0.0f, 0 otherwise +int nvgIsBlack( struct NVGcolor col ); // // State Handling @@ -148,13 +163,13 @@ void nvgReset(struct NVGcontext* ctx); // Current render style can be saved and restored using nvgSave() and nvgRestore(). // Sets current stroke style to a solid color. -void nvgStrokeColor(struct NVGcontext* ctx, unsigned int color); +void nvgStrokeColor(struct NVGcontext* ctx, struct NVGcolor color); // Sets current stroke style to a paint, which can be a one of the gradients or a pattern. void nvgStrokePaint(struct NVGcontext* ctx, struct NVGpaint paint); // Sets current fill cstyle to a solid color. -void nvgFillColor(struct NVGcontext* ctx, unsigned int color); +void nvgFillColor(struct NVGcontext* ctx, struct NVGcolor color); // Sets current fill style to a paint, which can be a one of the gradients or a pattern. void nvgFillPaint(struct NVGcontext* ctx, struct NVGpaint paint); @@ -247,7 +262,7 @@ void nvgDeleteImage(struct NVGcontext* ctx, int image); // of the linear gradient, icol specifies the start color and ocol the end color. // The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, float sx, float sy, float ex, float ey, - unsigned int icol, unsigned int ocol); + struct NVGcolor icol, struct NVGcolor ocol); // Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering // drop shadows or hilights for boxes. Parameters (x,y) define the top-left corner of the rectangle, @@ -255,13 +270,13 @@ struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, float sx, float sy, fl // the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient. // The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, float x, float y, float w, float h, - float r, float f, unsigned int icol, unsigned int ocol); + float r, float f, struct NVGcolor icol, struct NVGcolor ocol); // Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify // the inner and outer radius of the gradient, icol specifies the start color and ocol the end color. // The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, float cx, float cy, float inr, float outr, - unsigned int icol, unsigned int ocol); + struct NVGcolor icol, struct NVGcolor ocol); // Creates and returns an image patter. Parameters (ox,oy) specify the left-top location of the image pattern, // (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render, diff --git a/src/nanovg_gl3buf.h b/src/nanovg_gl3buf.h index 0d1e52f..3bad600 100644 --- a/src/nanovg_gl3buf.h +++ b/src/nanovg_gl3buf.h @@ -118,8 +118,8 @@ struct GLNVGpath { struct GLNVGfragUniforms { float scissorMat[12]; // matrices are actually 3 vec4s float paintMat[12]; - float innerCol[4]; - float outerCol[4]; + struct NVGcolor innerCol; + struct NVGcolor outerCol; float scissorExt[2]; float scissorScale[2]; float extent[2]; @@ -591,8 +591,8 @@ static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms struct GLNVGtexture* tex = NULL; float invxform[6]; - glnvg__toFloatColor(frag->innerCol, paint->innerColor); - glnvg__toFloatColor(frag->outerCol, paint->outerColor); + frag->innerCol = paint->innerColor; + frag->outerCol = paint->outerColor; glnvg__xformInverse(invxform, paint->xform); glnvg__xformToMat3x4(frag->paintMat, invxform);