Updated NanoVG and Blendish.

This commit is contained in:
Branimir Karadžić 2014-11-16 18:59:17 -08:00
parent 24df14f9f3
commit ff44d73480
11 changed files with 6201 additions and 5684 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
// stb_truetype.h - v0.6c - public domain // stb_truetype.h - v0.8 - public domain
// authored from 2009-2012 by Sean Barrett / RAD Game Tools // authored from 2009-2013 by Sean Barrett / RAD Game Tools
// //
// This library processes TrueType files: // This library processes TrueType files:
// parse files // parse files
@ -27,9 +27,15 @@
// stoiko (Haemimont Games) // stoiko (Haemimont Games)
// Brian Hook // Brian Hook
// Walter van Niftrik // Walter van Niftrik
// David Gow
// David Given
// Ivan-Assen Ivanov
// Anthony Pesch
// //
// VERSION HISTORY // VERSION HISTORY
// //
// 0.8 (2014-05-25) fix a few more warnings
// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
// 0.6c (2012-07-24) improve documentation // 0.6c (2012-07-24) improve documentation
// 0.6b (2012-07-20) fix a few more warnings // 0.6b (2012-07-20) fix a few more warnings
// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, // 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
@ -222,7 +228,7 @@ void my_stbtt_print(float x, float y, char *text)
while (*text) { while (*text) {
if (*text >= 32 && *text < 128) { if (*text >= 32 && *text < 128) {
stbtt_aligned_quad q; stbtt_aligned_quad q;
stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl,0=old d3d stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
@ -291,7 +297,7 @@ int main(int arg, char **argv)
{ {
stbtt_fontinfo font; stbtt_fontinfo font;
int i,j,ascent,baseline,ch=0; int i,j,ascent,baseline,ch=0;
float scale, xpos=0; float scale, xpos=2; // leave a little padding in case the character extends left
char *text = "Heljo World!"; char *text = "Heljo World!";
fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb"));
@ -363,10 +369,15 @@ int main(int arg, char **argv)
#define STBTT_iceil(x) ((int) ceil(x)) #define STBTT_iceil(x) ((int) ceil(x))
#endif #endif
#ifndef STBTT_sqrt
#include <math.h>
#define STBTT_sqrt(x) sqrt(x)
#endif
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
#ifndef STBTT_malloc #ifndef STBTT_malloc
#include <malloc.h> #include <stdlib.h>
#define STBTT_malloc(x,u) malloc(x) #define STBTT_malloc(x,u) ((void)(u),malloc(x))
#define STBTT_free(x,u) free(x) #define STBTT_free(x,u) free(x)
#endif #endif
@ -531,7 +542,6 @@ extern void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint
extern int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); extern int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
// an additional amount to add to the 'advance' value between ch1 and ch2 // an additional amount to add to the 'advance' value between ch1 and ch2
// @TODO; for now always returns 0!
extern int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); extern int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
// Gets the bounding box of the visible part of the glyph, in unscaled coordinates // Gets the bounding box of the visible part of the glyph, in unscaled coordinates
@ -573,6 +583,13 @@ extern int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codep
extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
// returns # of vertices and fills *vertices with the pointer to them // returns # of vertices and fills *vertices with the pointer to them
// these are expressed in "unscaled" coordinates // these are expressed in "unscaled" coordinates
//
// The shape is a series of countours. Each one starts with
// a STBTT_moveto, then consists of a series of mixed
// STBTT_lineto and STBTT_curveto segments. A lineto
// draws a line from previous endpoint to its x,y; a curveto
// draws a quadratic bezier from previous endpoint to
// its x,y, using cx,cy as the bezier control point.
extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
// frees the data allocated above // frees the data allocated above
@ -916,8 +933,6 @@ int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
search -= 2; search -= 2;
while (entrySelector) { while (entrySelector) {
searchRange >>= 1; searchRange >>= 1;
start = ttUSHORT(data + search + 2 + segcount*2 + 2);
end = ttUSHORT(data + search + 2);
start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2); start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2);
end = ttUSHORT(data + search + searchRange*2); end = ttUSHORT(data + search + searchRange*2);
if (unicode_codepoint > end) if (unicode_codepoint > end)
@ -1222,8 +1237,8 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
} }
// Find transformation scales. // Find transformation scales.
m = (float) sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
n = (float) sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
// Get indexed glyph. // Get indexed glyph.
comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
@ -1246,8 +1261,8 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
if (comp_verts) STBTT_free(comp_verts, info->userdata); if (comp_verts) STBTT_free(comp_verts, info->userdata);
return 0; return 0;
} }
if (num_vertices > 0) memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
if (vertices) STBTT_free(vertices, info->userdata); if (vertices) STBTT_free(vertices, info->userdata);
vertices = tmp; vertices = tmp;
STBTT_free(comp_verts, info->userdata); STBTT_free(comp_verts, info->userdata);
@ -1759,7 +1774,7 @@ unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float sc
scale_y = scale_x; scale_y = scale_x;
} }
stbtt_GetGlyphBitmapBox(info, glyph, scale_x, scale_y, &ix0,&iy0,&ix1,&iy1); stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
// now we get the size // now we get the size
gbm.w = (ix1 - ix0); gbm.w = (ix1 - ix0);
@ -1991,14 +2006,16 @@ static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name,
// is this a Unicode encoding? // is this a Unicode encoding?
if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
stbtt_int32 slen = ttUSHORT(fc+loc+8), off = ttUSHORT(fc+loc+10); stbtt_int32 slen = ttUSHORT(fc+loc+8);
stbtt_int32 off = ttUSHORT(fc+loc+10);
// check if there's a prefix match // check if there's a prefix match
stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
if (matchlen >= 0) { if (matchlen >= 0) {
// check for target_id+1 immediately following, with same encoding & language // check for target_id+1 immediately following, with same encoding & language
if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) {
stbtt_int32 slen = ttUSHORT(fc+loc+12+8), off = ttUSHORT(fc+loc+12+10); slen = ttUSHORT(fc+loc+12+8);
off = ttUSHORT(fc+loc+12+10);
if (slen == 0) { if (slen == 0) {
if (matchlen == nlen) if (matchlen == nlen)
return 1; return 1;

View file

@ -25,12 +25,6 @@ THE SOFTWARE.
#ifndef BLENDISH_H #ifndef BLENDISH_H
#define BLENDISH_H #define BLENDISH_H
#if BX_COMPILER_MSVC
# pragma warning(push)
# pragma warning(disable: 4305) // warning C4305: 'initializing' : truncation from 'double' to 'float'
# pragma warning(disable: 4244) // warning C4244: 'return' : conversion from 'int' to 'float', possible loss of data
#endif // BX_COMPILER_MSVC
#ifndef NANOVG_H #ifndef NANOVG_H
#error "nanovg.h must be included first." #error "nanovg.h must be included first."
#endif #endif
@ -808,6 +802,13 @@ BND_EXPORT void bndRadioButton(NVGcontext *ctx,
float x, float y, float w, float h, int flags, BNDwidgetState state, float x, float y, float w, float h, int flags, BNDwidgetState state,
int iconid, const char *label); int iconid, const char *label);
// Calculate the corresponding text position for given coordinates px/py
// in a text field.
// See bndTextField for more info.
BND_EXPORT int bndTextFieldTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
int iconid, const char *text, int px, int py);
// Draw a text field with its lower left origin at (x,y) and size of (w,h), // Draw a text field with its lower left origin at (x,y) and size of (w,h),
// where flags is one or multiple flags from BNDcornerFlags and state denotes // where flags is one or multiple flags from BNDcornerFlags and state denotes
// the widgets current UI state. // the widgets current UI state.
@ -916,6 +917,11 @@ BND_EXPORT void bndNodePort(NVGcontext *ctx, float x, float y, BNDwidgetState st
BND_EXPORT void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1, BND_EXPORT void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
BNDwidgetState state0, BNDwidgetState state1); BNDwidgetState state0, BNDwidgetState state1);
// Draw a node wire originating at (x0,y0) and floating to (x1,y1), with
// a colored gradient based on the two colors color0 and color1
BND_EXPORT void bndColoredNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
NVGcolor color0, NVGcolor color1);
// Draw a node background with its upper left origin at (x,y) and size of (w,h) // Draw a node background with its upper left origin at (x,y) and size of (w,h)
// where titleColor provides the base color for the title bar // where titleColor provides the base color for the title bar
BND_EXPORT void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h, BND_EXPORT void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h,
@ -1045,6 +1051,12 @@ BND_EXPORT void bndIconLabelValue(NVGcontext *ctx, float x, float y, float w, fl
BND_EXPORT void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h, BND_EXPORT void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h,
int iconid, NVGcolor color, NVGcolor shadowColor, int align, int iconid, NVGcolor color, NVGcolor shadowColor, int align,
float fontsize, const char *label); float fontsize, const char *label);
// Calculate the corresponding text position for given coordinates px/py
// in an iconLabel.
// See bndIconLabelCaret for more info.
BND_EXPORT int bndIconLabelTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
int iconid, float fontsize, const char *label, int px, int py);
// Draw an optional icon specified by <iconid>, an optional label and // Draw an optional icon specified by <iconid>, an optional label and
// a caret with given fontsize and color within a widget box. // a caret with given fontsize and color within a widget box.
@ -1095,6 +1107,8 @@ BND_EXPORT NVGcolor bndNodeWireColor(const BNDnodeTheme *theme, BNDwidgetState s
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4996) // Switch off security warnings #pragma warning (disable: 4996) // Switch off security warnings
#pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
#pragma warning (disable: 4244)
#pragma warning (disable: 4305)
#ifdef __cplusplus #ifdef __cplusplus
#define BND_INLINE inline #define BND_INLINE inline
#else #else
@ -1207,6 +1221,9 @@ inline double bnd_fmax ( double a, double b )
// max glyphs for position testing // max glyphs for position testing
#define BND_MAX_GLYPHS 1024 #define BND_MAX_GLYPHS 1024
// max rows for position testing
#define BND_MAX_ROWS 32
// text distance from bottom // text distance from bottom
#define BND_TEXT_PAD_DOWN 7 #define BND_TEXT_PAD_DOWN 7
@ -1444,6 +1461,12 @@ void bndRadioButton(NVGcontext *ctx,
BND_LABEL_FONT_SIZE, label, NULL); BND_LABEL_FONT_SIZE, label, NULL);
} }
int bndTextFieldTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
int iconid, const char *text, int px, int py) {
return bndIconLabelTextPosition(ctx, x, y, w, h,
iconid, BND_LABEL_FONT_SIZE, text, px, py);
}
void bndTextField(NVGcontext *ctx, void bndTextField(NVGcontext *ctx,
float x, float y, float w, float h, int flags, BNDwidgetState state, float x, float y, float w, float h, int flags, BNDwidgetState state,
int iconid, const char *text, int cbegin, int cend) { int iconid, const char *text, int cbegin, int cend) {
@ -1678,9 +1701,10 @@ void bndNodePort(NVGcontext *ctx, float x, float y, BNDwidgetState state,
nvgFill(ctx); nvgFill(ctx);
} }
void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1, void bndColoredNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
BNDwidgetState state0, BNDwidgetState state1) { NVGcolor color0, NVGcolor color1) {
float delta = fabsf(x1 - x0)*(float)bnd_theme.nodeTheme.noodleCurving/10.0f; float length = bnd_fmaxf(fabsf(x1 - x0),fabsf(y1 - y0));
float delta = length*(float)bnd_theme.nodeTheme.noodleCurving/10.0f;
nvgBeginPath(ctx); nvgBeginPath(ctx);
nvgMoveTo(ctx, x0, y0); nvgMoveTo(ctx, x0, y0);
@ -1688,17 +1712,26 @@ void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
x0 + delta, y0, x0 + delta, y0,
x1 - delta, y1, x1 - delta, y1,
x1, y1); x1, y1);
nvgStrokeColor(ctx, bnd_theme.nodeTheme.wiresColor); NVGcolor colorw = bnd_theme.nodeTheme.wiresColor;
colorw.a = (color0.a<color1.a)?color0.a:color1.a;
nvgStrokeColor(ctx, colorw);
nvgStrokeWidth(ctx, BND_NODE_WIRE_OUTLINE_WIDTH); nvgStrokeWidth(ctx, BND_NODE_WIRE_OUTLINE_WIDTH);
nvgStroke(ctx); nvgStroke(ctx);
nvgStrokePaint(ctx, nvgLinearGradient(ctx, nvgStrokePaint(ctx, nvgLinearGradient(ctx,
x0, y0, x1, y1, x0, y0, x1, y1,
bndNodeWireColor(&bnd_theme.nodeTheme, state0), color0,
bndNodeWireColor(&bnd_theme.nodeTheme, state1))); color1));
nvgStrokeWidth(ctx,BND_NODE_WIRE_WIDTH); nvgStrokeWidth(ctx,BND_NODE_WIRE_WIDTH);
nvgStroke(ctx); nvgStroke(ctx);
} }
void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
BNDwidgetState state0, BNDwidgetState state1) {
bndColoredNodeWire(ctx, x0, y0, x1, y1,
bndNodeWireColor(&bnd_theme.nodeTheme, state0),
bndNodeWireColor(&bnd_theme.nodeTheme, state1));
}
void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h, void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h,
BNDwidgetState state, int iconid, const char *label, NVGcolor titleColor) { BNDwidgetState state, int iconid, const char *label, NVGcolor titleColor) {
bndInnerBox(ctx,x,y,w,BND_NODE_TITLE_HEIGHT+2, bndInnerBox(ctx,x,y,w,BND_NODE_TITLE_HEIGHT+2,
@ -1735,9 +1768,11 @@ void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h,
bndOutlineBox(ctx,x,y,w,h+1, bndOutlineBox(ctx,x,y,w,h+1,
BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS, BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS,
bndTransparent(borderColor)); bndTransparent(borderColor));
/*
bndNodeArrowDown(ctx, bndNodeArrowDown(ctx,
x + BND_NODE_MARGIN_SIDE, y + BND_NODE_TITLE_HEIGHT-4, x + BND_NODE_MARGIN_SIDE, y + BND_NODE_TITLE_HEIGHT-4,
BND_NODE_ARROW_SIZE, arrowColor); BND_NODE_ARROW_SIZE, arrowColor);
*/
bndDropShadow(ctx,x,y,w,h,BND_NODE_RADIUS, bndDropShadow(ctx,x,y,w,h,BND_NODE_RADIUS,
BND_SHADOW_FEATHER,BND_SHADOW_ALPHA); BND_SHADOW_FEATHER,BND_SHADOW_ALPHA);
} }
@ -2118,17 +2153,17 @@ void bndIconLabelValue(NVGcontext *ctx, float x, float y, float w, float h,
+ nvgTextBounds(ctx, 1, 1, value, NULL, NULL); + nvgTextBounds(ctx, 1, 1, value, NULL, NULL);
x += ((w-BND_PAD_RIGHT-pleft)-width)*0.5f; x += ((w-BND_PAD_RIGHT-pleft)-width)*0.5f;
} }
y += h-BND_TEXT_PAD_DOWN; y += BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN;
nvgText(ctx, x, y, label, NULL); nvgText(ctx, x, y, label, NULL);
x += label_width; x += label_width;
nvgText(ctx, x, y, BND_LABEL_SEPARATOR, NULL); nvgText(ctx, x, y, BND_LABEL_SEPARATOR, NULL);
x += sep_width; x += sep_width;
nvgText(ctx, x, y, value, NULL); nvgText(ctx, x, y, value, NULL);
} else { } else {
nvgTextAlign(ctx, nvgTextAlign(ctx,
(align==BND_LEFT)?(NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE): (align==BND_LEFT)?(NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE):
(NVG_ALIGN_CENTER|NVG_ALIGN_BASELINE)); (NVG_ALIGN_CENTER|NVG_ALIGN_BASELINE));
nvgTextBox(ctx,x+pleft,y+h-BND_TEXT_PAD_DOWN, nvgTextBox(ctx,x+pleft,y+BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN,
w-BND_PAD_RIGHT-pleft,label, NULL); w-BND_PAD_RIGHT-pleft,label, NULL);
} }
} else if (iconid >= 0) { } else if (iconid >= 0) {
@ -2138,7 +2173,7 @@ void bndIconLabelValue(NVGcontext *ctx, float x, float y, float w, float h,
void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h, void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h,
int iconid, NVGcolor color, NVGcolor shadowColor, int iconid, NVGcolor color, NVGcolor shadowColor,
int /*align*/, float fontsize, const char *label) { int align, float fontsize, const char *label) {
if (label && (bnd_font >= 0)) { if (label && (bnd_font >= 0)) {
nvgFontFaceId(ctx, bnd_font); nvgFontFaceId(ctx, bnd_font);
nvgFontSize(ctx, fontsize); nvgFontSize(ctx, fontsize);
@ -2158,10 +2193,70 @@ void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h,
} }
} }
void bndIconLabelCaret(NVGcontext *ctx, float x, float y, float w, float /*h*/, int bndIconLabelTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
int iconid, float fontsize, const char *label, int px, int py) {
float bounds[4];
float pleft = BND_TEXT_RADIUS;
if (!label) return -1;
if (iconid >= 0)
pleft += BND_ICON_SHEET_RES;
if (bnd_font < 0) return -1;
x += pleft;
y += BND_WIDGET_HEIGHT - BND_TEXT_PAD_DOWN;
nvgFontFaceId(ctx, bnd_font);
nvgFontSize(ctx, fontsize);
nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
w -= BND_TEXT_RADIUS + pleft;
float asc, desc, lh;
static NVGtextRow rows[BND_MAX_ROWS];
int nrows = nvgTextBreakLines(
ctx, label, NULL, w, rows, BND_MAX_ROWS);
if (nrows == 0) return 0;
nvgTextBoxBounds(ctx, x, y, w, label, NULL, bounds);
nvgTextMetrics(ctx, &asc, &desc, &lh);
// calculate vertical position
int row = bnd_clamp((int)((float)(py - bounds[1]) / lh), 0, nrows - 1);
// search horizontal position
static NVGglyphPosition glyphs[BND_MAX_GLYPHS];
int nglyphs = nvgTextGlyphPositions(
ctx, x, y, rows[row].start, rows[row].end + 1, glyphs, BND_MAX_GLYPHS);
int col, p = 0;
for (col = 0; col < nglyphs && glyphs[col].x < px; ++col)
p = glyphs[col].str - label;
// see if we should move one character further
if (col > 0 && col < nglyphs && glyphs[col].x - px < px - glyphs[col - 1].x)
p = glyphs[col].str - label;
return p;
}
static void bndCaretPosition(NVGcontext *ctx, float x, float y,
float desc, float lineHeight, const char *caret, NVGtextRow *rows,int nrows,
int *cr, float *cx, float *cy) {
static NVGglyphPosition glyphs[BND_MAX_GLYPHS];
int r,nglyphs;
for (r=0; r < nrows && rows[r].end < caret; ++r);
*cr = r;
*cx = x;
*cy = y-lineHeight-desc + r*lineHeight;
if (nrows == 0) return;
*cx = rows[r].minx;
nglyphs = nvgTextGlyphPositions(
ctx, x, y, rows[r].start, rows[r].end+1, glyphs, BND_MAX_GLYPHS);
for (int i=0; i < nglyphs; ++i) {
*cx=glyphs[i].x;
if (glyphs[i].str == caret) break;
}
}
void bndIconLabelCaret(NVGcontext *ctx, float x, float y, float w, float h,
int iconid, NVGcolor color, float fontsize, const char *label, int iconid, NVGcolor color, float fontsize, const char *label,
NVGcolor caretcolor, int cbegin, int cend) { NVGcolor caretcolor, int cbegin, int cend) {
float bounds[4];
float pleft = BND_TEXT_RADIUS; float pleft = BND_TEXT_RADIUS;
if (!label) return; if (!label) return;
if (iconid >= 0) { if (iconid >= 0) {
@ -2181,70 +2276,37 @@ void bndIconLabelCaret(NVGcontext *ctx, float x, float y, float w, float /*h*/,
w -= BND_TEXT_RADIUS+pleft; w -= BND_TEXT_RADIUS+pleft;
if (cend >= cbegin) { if (cend >= cbegin) {
#if 1 int c0r,c1r;
float c0,c1; float c0x,c0y,c1x,c1y;
const char *cb;const char *ce; float desc,lh;
static NVGglyphPosition glyphs[BND_MAX_GLYPHS]; static NVGtextRow rows[BND_MAX_ROWS];
int nglyphs = nvgTextGlyphPositions( int nrows = nvgTextBreakLines(
ctx, x, y, label, label+cend+1, glyphs, BND_MAX_GLYPHS); ctx, label, label+cend+1, w, rows, BND_MAX_ROWS);
c0=glyphs[0].x; nvgTextMetrics(ctx, NULL, &desc, &lh);
c1=glyphs[nglyphs-1].x;
cb = label+cbegin; ce = label+cend; bndCaretPosition(ctx, x, y, desc, lh, label+cbegin,
// TODO: this is slow rows, nrows, &c0r, &c0x, &c0y);
for (int i=0; i < nglyphs; ++i) { bndCaretPosition(ctx, x, y, desc, lh, label+cend,
if (glyphs[i].str == cb) rows, nrows, &c1r, &c1x, &c1y);
c0 = glyphs[i].x;
if (glyphs[i].str == ce)
c1 = glyphs[i].x;
}
nvgTextBounds(ctx,x,y,label,NULL, bounds);
nvgBeginPath(ctx); nvgBeginPath(ctx);
if (cbegin == cend) { if (cbegin == cend) {
nvgFillColor(ctx, nvgRGBf(0.337,0.502,0.761)); nvgFillColor(ctx, nvgRGBf(0.337,0.502,0.761));
nvgRect(ctx, c0-1, bounds[1], 2, bounds[3]-bounds[1]); nvgRect(ctx, c0x-1, c0y, 2, lh+1);
} else { } else {
nvgFillColor(ctx, caretcolor); nvgFillColor(ctx, caretcolor);
nvgRect(ctx, c0-1, bounds[1], c1-c0+1, bounds[3]-bounds[1]); if (c0r == c1r) {
nvgRect(ctx, c0x-1, c0y, c1x-c0x+1, lh+1);
} else {
int blk=c1r-c0r-1;
nvgRect(ctx, c0x-1, c0y, x+w-c0x+1, lh+1);
nvgRect(ctx, x, c1y, c1x-x+1, lh+1);
if (blk)
nvgRect(ctx, x, c0y+lh, w, blk*lh+1);
}
} }
nvgFill(ctx); nvgFill(ctx);
#else
float c0,c1;
const char *cb;
const char *ce;
const char *line;
int numlines;
cb = label+cbegin; ce = label+cend;
line = label;
NVGtextRow rows[2];
numlines = nvgTextBreakLines(ctx, line, NULL, w, rows, 2);
/*
int nglyphs = nvgTextGlyphPositions(
ctx, x, y, label, label+cend+1, glyphs, BND_MAX_GLYPHS);
c0=glyphs[0].x;
c1=glyphs[nglyphs-1].x;
// TODO: this is slow
for (int i=0; i < nglyphs; ++i) {
if (glyphs[i].str == cb)
c0 = glyphs[i].x;
if (glyphs[i].str == ce)
c1 = glyphs[i].x;
}
nvgTextBounds(ctx,x,y,label,NULL, bounds);
nvgBeginPath(ctx);
if (cbegin == cend) {
nvgFillColor(ctx, nvgRGBf(0.337,0.502,0.761));
nvgRect(ctx, c0-1, bounds[1], 2, bounds[3]-bounds[1]);
} else {
nvgFillColor(ctx, caretcolor);
nvgRect(ctx, c0-1, bounds[1], c1-c0+1, bounds[3]-bounds[1]);
}
nvgFill(ctx);
*/
#endif
} }
nvgBeginPath(ctx); nvgBeginPath(ctx);
@ -2333,8 +2395,4 @@ NVGcolor bndNodeWireColor(const BNDnodeTheme *theme, BNDwidgetState state) {
#undef BND_INLINE #undef BND_INLINE
#endif #endif
#if BX_COMPILER_MSVC
# pragma warning(pop)
#endif // BX_COMPILER_MSVC
#endif // BLENDISH_IMPLEMENTATION #endif // BLENDISH_IMPLEMENTATION

View file

@ -32,8 +32,11 @@
#include "entry/entry.h" #include "entry/entry.h"
#include "nanovg/nanovg.h" #include "nanovg/nanovg.h"
BX_PRAGMA_DIAGNOSTIC_PUSH();
BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC("-Wunused-parameter");
#define BLENDISH_IMPLEMENTATION #define BLENDISH_IMPLEMENTATION
#include "blendish.h" #include "blendish.h"
BX_PRAGMA_DIAGNOSTIC_POP();
#define ICON_SEARCH 0x1F50D #define ICON_SEARCH 0x1F50D
#define ICON_CIRCLED_CROSS 0x2716 #define ICON_CIRCLED_CROSS 0x2716
@ -941,7 +944,7 @@ int loadDemoData(struct NVGcontext* vg, struct DemoData* data)
{ {
char file[128]; char file[128];
bx::snprintf(file, 128, "images/image%d.jpg", ii+1); bx::snprintf(file, 128, "images/image%d.jpg", ii+1);
data->images[ii] = nvgCreateImage(vg, file); data->images[ii] = nvgCreateImage(vg, file, 0);
if (data->images[ii] == bgfx::invalidHandle) if (data->images[ii] == bgfx::invalidHandle)
{ {
printf("Could not load %s.\n", file); printf("Could not load %s.\n", file);
@ -1218,14 +1221,14 @@ int _main_(int /*_argc*/, char** /*_argv*/)
, 0 , 0
); );
NVGcontext* nvg = nvgCreate(512, 512, 1, 0); NVGcontext* nvg = nvgCreate(1, 0);
bgfx::setViewSeq(0, true); bgfx::setViewSeq(0, true);
DemoData data; DemoData data;
loadDemoData(nvg, &data); loadDemoData(nvg, &data);
bndSetFont(nvgCreateFont(nvg, "droidsans", "font/droidsans.ttf")); bndSetFont(nvgCreateFont(nvg, "droidsans", "font/droidsans.ttf") );
bndSetIconImage(nvgCreateImage(nvg, "images/blender_icons16.png")); bndSetIconImage(nvgCreateImage(nvg, "images/blender_icons16.png", 0) );
int64_t timeOffset = bx::getHPCounter(); int64_t timeOffset = bx::getHPCounter();
@ -1248,7 +1251,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/20-nanovg"); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/20-nanovg");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: NanoVG is small antialiased vector graphics rendering library."); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: NanoVG is small antialiased vector graphics rendering library.");
nvgBeginFrame(nvg, width, height, 1.0f, NVG_STRAIGHT_ALPHA); nvgBeginFrame(nvg, width, height, 1.0f);
renderDemo(nvg, float(mouseState.m_mx), float(mouseState.m_my), float(width), float(height), time, 0, &data); renderDemo(nvg, float(mouseState.m_mx), float(mouseState.m_my), float(width), float(height), time, 0, &data);

View file

@ -12,8 +12,9 @@
#include "dbg.h" #include "dbg.h"
#include "cmd.h" #include "cmd.h"
#include <string>
#include <tinystl/allocator.h> #include <tinystl/allocator.h>
#include <tinystl/string.h>
#include <tinystl/unordered_map.h> #include <tinystl/unordered_map.h>
namespace stl = tinystl; namespace stl = tinystl;
@ -62,14 +63,14 @@ struct CmdContext
case -1: case -1:
{ {
std::string tmp(_cmd, next-_cmd - (*next == '\0' ? 0 : 1) ); stl::string tmp(_cmd, next-_cmd - (*next == '\0' ? 0 : 1) );
DBG("Command '%s' doesn't exist.", tmp.c_str() ); DBG("Command '%s' doesn't exist.", tmp.c_str() );
} }
break; break;
default: default:
{ {
std::string tmp(_cmd, next-_cmd - (*next == '\0' ? 0 : 1) ); stl::string tmp(_cmd, next-_cmd - (*next == '\0' ? 0 : 1) );
DBG("Failed '%s' err: %d.", tmp.c_str(), err); DBG("Failed '%s' err: %d.", tmp.c_str(), err);
} }
break; break;

View file

@ -5,18 +5,19 @@
#define USE_EDTAA3 0 #define USE_EDTAA3 0
#include "bx/platform.h" #include <bx/macros.h>
#if BX_COMPILER_MSVC #if BX_COMPILER_MSVC
#define generic GenericFromFreeType // WinRT language extensions see "generic" as a keyword... this is stupid # define generic GenericFromFreeType // WinRT language extensions see "generic" as a keyword... this is stupid
#define interface InterfaceFromFreeType #endif // BX_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable : 4245) // conversion from 'int' to 'FT_UInt', signed/unsigned mismatch BX_PRAGMA_DIAGNOSTIC_PUSH();
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4245) // error C4245: '=' : conversion from 'int' to 'FT_UInt', signed/unsigned mismatch
#pragma push_macro("interface")
#undef interface
#include <freetype/freetype.h> #include <freetype/freetype.h>
#pragma warning(pop) #pragma pop_macro("interface")
#else BX_PRAGMA_DIAGNOSTIC_POP();
#include <freetype/freetype.h>
#endif
#include "../common.h" #include "../common.h"

View file

@ -77,7 +77,7 @@ static void imguiFree(void* _ptr, void* /*_userptr*/)
#define STBTT_malloc(_x, _y) imguiMalloc(_x, _y) #define STBTT_malloc(_x, _y) imguiMalloc(_x, _y)
#define STBTT_free(_x, _y) imguiFree(_x, _y) #define STBTT_free(_x, _y) imguiFree(_x, _y)
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype/stb_truetype.h> #include <stb/stb_truetype.h>
namespace namespace
{ {
@ -441,7 +441,7 @@ struct Imgui
ImguiFontHandle create(const void* _data, float _fontSize) ImguiFontHandle create(const void* _data, float _fontSize)
{ {
m_nvg = nvgCreate(512, 512, 1, m_view); m_nvg = nvgCreate(1, m_view);
nvgCreateFontMem(m_nvg, "default", (unsigned char*)_data, INT32_MAX, 0); nvgCreateFontMem(m_nvg, "default", (unsigned char*)_data, INT32_MAX, 0);
nvgFontSize(m_nvg, _fontSize); nvgFontSize(m_nvg, _fontSize);
nvgFontFace(m_nvg, "default"); nvgFontFace(m_nvg, "default");
@ -768,7 +768,7 @@ struct Imgui
void beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar, uint8_t _view) void beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar, uint8_t _view)
{ {
nvgBeginFrame(m_nvg, _width, _height, 1.0f, NVG_STRAIGHT_ALPHA); nvgBeginFrame(m_nvg, _width, _height, 1.0f);
m_view = _view; m_view = _view;
m_viewWidth = _width; m_viewWidth = _width;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -25,7 +25,12 @@ extern "C" {
#define NVG_PI 3.14159265358979323846264338327f #define NVG_PI 3.14159265358979323846264338327f
struct NVGcontext; #ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
#endif
typedef struct NVGcontext NVGcontext;
struct NVGcolor { struct NVGcolor {
union { union {
@ -35,17 +40,18 @@ struct NVGcolor {
}; };
}; };
}; };
typedef struct NVGcolor NVGcolor;
struct NVGpaint { struct NVGpaint {
float xform[6]; float xform[6];
float extent[2]; float extent[2];
float radius; float radius;
float feather; float feather;
struct NVGcolor innerColor; NVGcolor innerColor;
struct NVGcolor outerColor; NVGcolor outerColor;
int image; int image;
int repeat;
}; };
typedef struct NVGpaint NVGpaint;
enum NVGwinding { enum NVGwinding {
NVG_CCW = 1, // Winding for solid shapes NVG_CCW = 1, // Winding for solid shapes
@ -65,11 +71,6 @@ enum NVGlineCap {
NVG_MITER, NVG_MITER,
}; };
enum NVGpatternRepeat {
NVG_REPEATX = 0x01, // Repeat image pattern in X direction
NVG_REPEATY = 0x02, // Repeat image pattern in Y direction
};
enum NVGalign { enum NVGalign {
// Horizontal align // Horizontal align
NVG_ALIGN_LEFT = 1<<0, // Default, align text horizontally to left. NVG_ALIGN_LEFT = 1<<0, // Default, align text horizontally to left.
@ -82,15 +83,12 @@ enum NVGalign {
NVG_ALIGN_BASELINE = 1<<6, // Default, align text vertically to baseline. NVG_ALIGN_BASELINE = 1<<6, // Default, align text vertically to baseline.
}; };
enum NVGalpha {
NVG_STRAIGHT_ALPHA,
NVG_PREMULTIPLIED_ALPHA,
};
struct NVGglyphPosition { struct NVGglyphPosition {
const char* str; // Position of the glyph in the input string. const char* str; // Position of the glyph in the input string.
float x; // The x- coordinate of the position of the glyph . float x; // The x-coordinate of the logical glyph position.
float minx, maxx; // The bounds of the glyph shape.
}; };
typedef struct NVGglyphPosition NVGglyphPosition;
struct NVGtextRow { struct NVGtextRow {
const char* start; // Pointer to the input text where the row starts. const char* start; // Pointer to the input text where the row starts.
@ -99,7 +97,15 @@ struct NVGtextRow {
float width; // Logical width of the row. float width; // Logical width of the row.
float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending. float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending.
}; };
typedef struct NVGtextRow NVGtextRow;
enum NVGimageFlags {
NVG_IMAGE_GENERATE_MIPMAPS = 1<<0, // Generate mipmaps during creation of the image.
NVG_IMAGE_REPEATX = 1<<1, // Repeat image in X direction.
NVG_IMAGE_REPEATY = 1<<2, // Repeat image in Y direction.
NVG_IMAGE_FLIPY = 1<<3, // Flips (inverses) image in Y direction when rendered.
NVG_IMAGE_PREMULTIPLIED = 1<<4, // Image data has premultiplied alpha.
};
// Begin drawing a new frame // Begin drawing a new frame
// Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame() // Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame()
@ -109,14 +115,13 @@ struct NVGtextRow {
// For example, GLFW returns two dimension for an opened window: window size and // For example, GLFW returns two dimension for an opened window: window size and
// frame buffer size. In that case you would set windowWidth/Height to the window size // frame buffer size. In that case you would set windowWidth/Height to the window size
// devicePixelRatio to: frameBufferWidth / windowWidth. // devicePixelRatio to: frameBufferWidth / windowWidth.
// AlphaBlend controls if drawing the shapes to the render target should be done using straight or void nvgBeginFrame(NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio);
// premultiplied alpha. If rendering directly to framebuffer you probably want to use NVG_STRAIGHT_ALPHA,
// if rendering to texture which should contain transparent regions NVG_PREMULTIPLIED_ALPHA is the // Cancels drawing the current frame.
// right choice. void nvgCancelFrame(NVGcontext* ctx);
void nvgBeginFrame(struct NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio, int alphaBlend);
// Ends drawing flushing remaining render state. // Ends drawing flushing remaining render state.
void nvgEndFrame(struct NVGcontext* ctx); void nvgEndFrame(NVGcontext* ctx);
// //
// Color utils // Color utils
@ -124,38 +129,35 @@ void nvgEndFrame(struct NVGcontext* ctx);
// Colors in NanoVG are stored as unsigned ints in ABGR format. // 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 (1.0f). // Returns a color value from red, green, blue values. Alpha will be set to 255 (1.0f).
struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b); NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b);
// Returns a color value from red, green, blue values. Alpha will be set to 1.0f. // Returns a color value from red, green, blue values. Alpha will be set to 1.0f.
struct NVGcolor nvgRGBf(float r, float g, float b); NVGcolor nvgRGBf(float r, float g, float b);
// Returns a color value from red, green, blue and alpha values. // Returns a color value from red, green, blue and alpha values.
struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a); NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
//
struct NVGcolor nvgRGBAu(unsigned int abgr);
// Returns a color value from red, green, blue and alpha values. // Returns a color value from red, green, blue and alpha values.
struct NVGcolor nvgRGBAf(float r, float g, float b, float a); NVGcolor nvgRGBAf(float r, float g, float b, float a);
// Linearly interpoaltes from color c0 to c1, and returns resulting color value. // Linearly interpoaltes from color c0 to c1, and returns resulting color value.
struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u); NVGcolor nvgLerpRGBA(NVGcolor c0, NVGcolor c1, float u);
// Sets transparency of a color value. // Sets transparency of a color value.
struct NVGcolor nvgTransRGBA(struct NVGcolor c0, unsigned char a); NVGcolor nvgTransRGBA(NVGcolor c0, unsigned char a);
// Sets transparency of a color value. // Sets transparency of a color value.
struct NVGcolor nvgTransRGBAf(struct NVGcolor c0, float a); NVGcolor nvgTransRGBAf(NVGcolor c0, float a);
// Returns color value specified by hue, saturation and lightness. // Returns color value specified by hue, saturation and lightness.
// HSL values are all in range [0..1], alpha will be set to 255. // HSL values are all in range [0..1], alpha will be set to 255.
struct NVGcolor nvgHSL(float h, float s, float l); NVGcolor nvgHSL(float h, float s, float l);
// Returns color value specified by hue, saturation and lightness and alpha. // Returns color value specified by hue, saturation and lightness and alpha.
// HSL values are all in range [0..1], alpha in range [0..255] // HSL values are all in range [0..1], alpha in range [0..255]
struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a); NVGcolor nvgHSLA(float h, float s, float l, unsigned char a);
// //
// State Handling // State Handling
@ -166,13 +168,13 @@ struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a);
// Pushes and saves the current render state into a state stack. // Pushes and saves the current render state into a state stack.
// A matching nvgRestore() must be used to restore the state. // A matching nvgRestore() must be used to restore the state.
void nvgSave(struct NVGcontext* ctx); void nvgSave(NVGcontext* ctx);
// Pops and restores current render state. // Pops and restores current render state.
void nvgRestore(struct NVGcontext* ctx); void nvgRestore(NVGcontext* ctx);
// Resets current render state to default values. Does not affect the render state stack. // Resets current render state to default values. Does not affect the render state stack.
void nvgReset(struct NVGcontext* ctx); void nvgReset(NVGcontext* ctx);
// //
// Render styles // Render styles
@ -184,31 +186,35 @@ void nvgReset(struct NVGcontext* ctx);
// Current render style can be saved and restored using nvgSave() and nvgRestore(). // Current render style can be saved and restored using nvgSave() and nvgRestore().
// Sets current stroke style to a solid color. // Sets current stroke style to a solid color.
void nvgStrokeColor(struct NVGcontext* ctx, struct NVGcolor color); void nvgStrokeColor(NVGcontext* ctx, NVGcolor color);
// Sets current stroke style to a paint, which can be a one of the gradients or a pattern. // 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); void nvgStrokePaint(NVGcontext* ctx, NVGpaint paint);
// Sets current fill cstyle to a solid color. // Sets current fill cstyle to a solid color.
void nvgFillColor(struct NVGcontext* ctx, struct NVGcolor color); void nvgFillColor(NVGcontext* ctx, NVGcolor color);
// Sets current fill style to a paint, which can be a one of the gradients or a pattern. // 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); void nvgFillPaint(NVGcontext* ctx, NVGpaint paint);
// Sets the miter limit of the stroke style. // Sets the miter limit of the stroke style.
// Miter limit controls when a sharp corner is beveled. // Miter limit controls when a sharp corner is beveled.
void nvgMiterLimit(struct NVGcontext* ctx, float limit); void nvgMiterLimit(NVGcontext* ctx, float limit);
// Sets the stroke witdth of the stroke style. // Sets the stroke witdth of the stroke style.
void nvgStrokeWidth(struct NVGcontext* ctx, float size); void nvgStrokeWidth(NVGcontext* ctx, float size);
// Sets how the end of the line (cap) is drawn, // Sets how the end of the line (cap) is drawn,
// Can be one of: NVG_BUTT (default), NVG_ROUND, NVG_SQUARE. // Can be one of: NVG_BUTT (default), NVG_ROUND, NVG_SQUARE.
void nvgLineCap(struct NVGcontext* ctx, int cap); void nvgLineCap(NVGcontext* ctx, int cap);
// Sets how sharp path corners are drawn. // Sets how sharp path corners are drawn.
// Can be one of NVG_MITER (default), NVG_ROUND, NVG_BEVEL. // Can be one of NVG_MITER (default), NVG_ROUND, NVG_BEVEL.
void nvgLineJoin(struct NVGcontext* ctx, int join); void nvgLineJoin(NVGcontext* ctx, int join);
// Sets the transparency applied to all rendered shapes.
// Alreade transparent paths will get proportionally more transparent as well.
void nvgGlobalAlpha(NVGcontext* ctx, float alpha);
// //
// Transforms // Transforms
@ -228,50 +234,103 @@ void nvgLineJoin(struct NVGcontext* ctx, int join);
// Current coordinate system (transformation) can be saved and restored using nvgSave() and nvgRestore(). // Current coordinate system (transformation) can be saved and restored using nvgSave() and nvgRestore().
// Resets current transform to a identity matrix. // Resets current transform to a identity matrix.
void nvgResetTransform(struct NVGcontext* ctx); void nvgResetTransform(NVGcontext* ctx);
// Premultiplies current coordinate system by specified matrix. // Premultiplies current coordinate system by specified matrix.
// The parameters are interpreted as matrix as follows: // The parameters are interpreted as matrix as follows:
// [a c e] // [a c e]
// [b d f] // [b d f]
// [0 0 1] // [0 0 1]
void nvgTransform(struct NVGcontext* ctx, float a, float b, float c, float d, float e, float f); void nvgTransform(NVGcontext* ctx, float a, float b, float c, float d, float e, float f);
// Translates current coordinate system. // Translates current coordinate system.
void nvgTranslate(struct NVGcontext* ctx, float x, float y); void nvgTranslate(NVGcontext* ctx, float x, float y);
// Rotates current coordinate system. // Rotates current coordinate system. Angle is specifid in radians.
void nvgRotate(struct NVGcontext* ctx, float angle); void nvgRotate(NVGcontext* ctx, float angle);
// Skews the current coordinate system along X axis. Angle is specifid in radians.
void nvgSkewX(NVGcontext* ctx, float angle);
// Skews the current coordinate system along Y axis. Angle is specifid in radians.
void nvgSkewY(NVGcontext* ctx, float angle);
// Scales the current coordinat system. // Scales the current coordinat system.
void nvgScale(struct NVGcontext* ctx, float x, float y); void nvgScale(NVGcontext* ctx, float x, float y);
// Stores the top part (a-f) of the current transformation matrix in to the specified buffer.
// [a c e]
// [b d f]
// [0 0 1]
// There should be space for 6 floats in the return buffer for the values a-f.
void nvgCurrentTransform(NVGcontext* ctx, float* xform);
// The following functions can be used to make calculations on 2x3 transformation matrices.
// A 2x3 matrix is representated as float[6].
// Sets the transform to identity matrix.
void nvgTransformIdentity(float* dst);
// Sets the transform to translation matrix matrix.
void nvgTransformTranslate(float* dst, float tx, float ty);
// Sets the transform to scale matrix.
void nvgTransformScale(float* dst, float sx, float sy);
// Sets the transform to rotate matrix. Angle is specifid in radians.
void nvgTransformRotate(float* dst, float a);
// Sets the transform to skew-x matrix. Angle is specifid in radians.
void nvgTransformSkewX(float* dst, float a);
// Sets the transform to skew-y matrix. Angle is specifid in radians.
void nvgTransformSkewY(float* dst, float a);
// Sets the transform to the result of multiplication of two transforms, of A = A*B.
void nvgTransformMultiply(float* dst, const float* src);
// Sets the transform to the result of multiplication of two transforms, of A = B*A.
void nvgTransformPremultiply(float* dst, const float* src);
// Sets the destination to inverse of specified transform.
// Returns 1 if the inverse could be calculated, else 0.
int nvgTransformInverse(float* dst, const float* src);
// Transform a point by given transform.
void nvgTransformPoint(float* dstx, float* dsty, const float* xform, float srcx, float srcy);
// Converts degress to radians and vice versa.
float nvgDegToRad(float deg);
float nvgRadToDeg(float rad);
// //
// Images // Images
// //
// NanoVG allows you to load jpg, png, psd, tga, pic and gif files to be used for rendering. // NanoVG allows you to load jpg, png, psd, tga, pic and gif files to be used for rendering.
// In addition you can upload your own image. The image loading is provided by stb_image. // In addition you can upload your own image. The image loading is provided by stb_image.
// The parameter imageFlags is combination of flags defined in NVGimageFlags.
// Creates image by loading it from the disk from specified file name. // Creates image by loading it from the disk from specified file name.
// Returns handle to the image. // Returns handle to the image.
int nvgCreateImage(struct NVGcontext* ctx, const char* filename); int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags);
// Creates image by loading it from the specified chunk of memory. // Creates image by loading it from the specified chunk of memory.
// Returns handle to the image. // Returns handle to the image.
int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata); int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int ndata);
// Creates image from specified image data. // Creates image from specified image data.
// Returns handle to the image. // Returns handle to the image.
int nvgCreateImageRGBA(struct NVGcontext* ctx, int w, int h, const unsigned char* data); int nvgCreateImageRGBA(NVGcontext* ctx, int w, int h, int imageFlags, const unsigned char* data);
// Updates image data specified by image handle. // Updates image data specified by image handle.
void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data); void nvgUpdateImage(NVGcontext* ctx, int image, const unsigned char* data);
// Returns the domensions of a created image. // Returns the domensions of a created image.
void nvgImageSize(struct NVGcontext* ctx, int image, int* w, int* h); void nvgImageSize(NVGcontext* ctx, int image, int* w, int* h);
// Deletes created image. // Deletes created image.
void nvgDeleteImage(struct NVGcontext* ctx, int image); void nvgDeleteImage(NVGcontext* ctx, int image);
// //
// Paints // Paints
@ -282,29 +341,28 @@ void nvgDeleteImage(struct NVGcontext* ctx, int image);
// Creates and returns a linear gradient. Parameters (sx,sy)-(ex,ey) specify the start and end coordinates // Creates and returns a linear gradient. Parameters (sx,sy)-(ex,ey) specify the start and end coordinates
// of the linear gradient, icol specifies the start color and ocol the end color. // 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(). // 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, NVGpaint nvgLinearGradient(NVGcontext* ctx, float sx, float sy, float ex, float ey,
struct NVGcolor icol, struct NVGcolor ocol); NVGcolor icol, NVGcolor ocol);
// Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering // 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, // drop shadows or hilights for boxes. Parameters (x,y) define the top-left corner of the rectangle,
// (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry // (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry
// the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient. // 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(). // 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, NVGpaint nvgBoxGradient(NVGcontext* ctx, float x, float y, float w, float h,
float r, float f, struct NVGcolor icol, struct NVGcolor ocol); float r, float f, NVGcolor icol, NVGcolor ocol);
// Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify // 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 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(). // 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, NVGpaint nvgRadialGradient(NVGcontext* ctx, float cx, float cy, float inr, float outr,
struct NVGcolor icol, struct NVGcolor ocol); NVGcolor icol, NVGcolor ocol);
// Creates and returns an image patter. Parameters (ox,oy) specify the left-top location of the image pattern, // 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, // (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render.
// and repeat is combination of NVG_REPEATX and NVG_REPEATY which tells if the image should be repeated across x or y.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). // The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, float ox, float oy, float ex, float ey, NVGpaint nvgImagePattern(NVGcontext* ctx, float ox, float oy, float ex, float ey,
float angle, int image, int repeat); float angle, int image, float alpha);
// //
// Scissoring // Scissoring
@ -312,12 +370,20 @@ struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, float ox, float oy, floa
// Scissoring allows you to clip the rendering into a rectangle. This is useful for varius // Scissoring allows you to clip the rendering into a rectangle. This is useful for varius
// user interface cases like rendering a text edit or a timeline. // user interface cases like rendering a text edit or a timeline.
// Sets the current // Sets the current scissor rectangle.
// The scissor rectangle is transformed by the current transform. // The scissor rectangle is transformed by the current transform.
void nvgScissor(struct NVGcontext* ctx, float x, float y, float w, float h); void nvgScissor(NVGcontext* ctx, float x, float y, float w, float h);
// Intersects current scissor rectangle with the specified rectangle.
// The scissor rectangle is transformed by the current transform.
// Note: in case the rotation of previous scissor rect differs from
// the current one, the intersection will be done between the specified
// rectangle and the previous scissor rectangle transformed in the current
// transform space. The resulting shape is always rectangle.
void nvgIntersectScissor(NVGcontext* ctx, float x, float y, float w, float h);
// Reset and disables scissoring. // Reset and disables scissoring.
void nvgResetScissor(struct NVGcontext* ctx); void nvgResetScissor(NVGcontext* ctx);
// //
// Paths // Paths
@ -337,46 +403,51 @@ void nvgResetScissor(struct NVGcontext* ctx);
// The curve segments and sub-paths are transformed by the current transform. // The curve segments and sub-paths are transformed by the current transform.
// Clears the current path and sub-paths. // Clears the current path and sub-paths.
void nvgBeginPath(struct NVGcontext* ctx); void nvgBeginPath(NVGcontext* ctx);
// Starts new sub-path with specified point as first point. // Starts new sub-path with specified point as first point.
void nvgMoveTo(struct NVGcontext* ctx, float x, float y); void nvgMoveTo(NVGcontext* ctx, float x, float y);
// Adds line segment from the last point in the path to the specified point. // Adds line segment from the last point in the path to the specified point.
void nvgLineTo(struct NVGcontext* ctx, float x, float y); void nvgLineTo(NVGcontext* ctx, float x, float y);
// Adds bezier segment from last point in the path via two control points to the specified point. // Adds cubic bezier segment from last point in the path via two control points to the specified point.
void nvgBezierTo(struct NVGcontext* ctx, float c1x, float c1y, float c2x, float c2y, float x, float y); void nvgBezierTo(NVGcontext* ctx, float c1x, float c1y, float c2x, float c2y, float x, float y);
// Adds quadratic bezier segment from last point in the path via a control point to the specified point.
void nvgQuadTo(NVGcontext* ctx, float cx, float cy, float x, float y);
// Adds an arc segment at the corner defined by the last path point, and two specified points. // Adds an arc segment at the corner defined by the last path point, and two specified points.
void nvgArcTo(struct NVGcontext* ctx, float x1, float y1, float x2, float y2, float radius); void nvgArcTo(NVGcontext* ctx, float x1, float y1, float x2, float y2, float radius);
// Closes current sub-path with a line segment. // Closes current sub-path with a line segment.
void nvgClosePath(struct NVGcontext* ctx); void nvgClosePath(NVGcontext* ctx);
// Sets the current sub-path winding, see NVGwinding and NVGsolidity. // Sets the current sub-path winding, see NVGwinding and NVGsolidity.
void nvgPathWinding(struct NVGcontext* ctx, int dir); void nvgPathWinding(NVGcontext* ctx, int dir);
// Creates new arc shaped sub-path. // Creates new circle arc shaped sub-path. The arc center is at cx,cy, the arc radius is r,
void nvgArc(struct NVGcontext* ctx, float cx, float cy, float r, float a0, float a1, int dir); // and the arc is drawn from angle a0 to a1, and swept in direction dir (NVG_CCW, or NVG_CW).
// Angles are specified in radians.
void nvgArc(NVGcontext* ctx, float cx, float cy, float r, float a0, float a1, int dir);
// Creates new rectangle shaped sub-path. // Creates new rectangle shaped sub-path.
void nvgRect(struct NVGcontext* ctx, float x, float y, float w, float h); void nvgRect(NVGcontext* ctx, float x, float y, float w, float h);
// Creates new rounded rectangle shaped sub-path. // Creates new rounded rectangle shaped sub-path.
void nvgRoundedRect(struct NVGcontext* ctx, float x, float y, float w, float h, float r); void nvgRoundedRect(NVGcontext* ctx, float x, float y, float w, float h, float r);
// Creates new ellipse shaped sub-path. // Creates new ellipse shaped sub-path.
void nvgEllipse(struct NVGcontext* ctx, float cx, float cy, float rx, float ry); void nvgEllipse(NVGcontext* ctx, float cx, float cy, float rx, float ry);
// Creates new circle shaped sub-path. // Creates new circle shaped sub-path.
void nvgCircle(struct NVGcontext* ctx, float cx, float cy, float r); void nvgCircle(NVGcontext* ctx, float cx, float cy, float r);
// Fills the current path with current fill style. // Fills the current path with current fill style.
void nvgFill(struct NVGcontext* ctx); void nvgFill(NVGcontext* ctx);
// Fills the current path with current stroke style. // Fills the current path with current stroke style.
void nvgStroke(struct NVGcontext* ctx); void nvgStroke(NVGcontext* ctx);
// //
@ -414,67 +485,67 @@ void nvgStroke(struct NVGcontext* ctx);
// Creates font by loading it from the disk from specified file name. // Creates font by loading it from the disk from specified file name.
// Returns handle to the font. // Returns handle to the font.
int nvgCreateFont(struct NVGcontext* ctx, const char* name, const char* filename); int nvgCreateFont(NVGcontext* ctx, const char* name, const char* filename);
// Creates image by loading it from the specified memory chunk. // Creates image by loading it from the specified memory chunk.
// Returns handle to the font. // Returns handle to the font.
int nvgCreateFontMem(struct NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData); int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData);
// Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found. // Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found.
int nvgFindFont(struct NVGcontext* ctx, const char* name); int nvgFindFont(NVGcontext* ctx, const char* name);
// Sets the font size of current text style. // Sets the font size of current text style.
void nvgFontSize(struct NVGcontext* ctx, float size); void nvgFontSize(NVGcontext* ctx, float size);
// Sets the blur of current text style. // Sets the blur of current text style.
void nvgFontBlur(struct NVGcontext* ctx, float blur); void nvgFontBlur(NVGcontext* ctx, float blur);
// Sets the letter spacing of current text style. // Sets the letter spacing of current text style.
void nvgTextLetterSpacing(struct NVGcontext* ctx, float spacing); void nvgTextLetterSpacing(NVGcontext* ctx, float spacing);
// Sets the proportional line height of current text style. The line height is specified as multiple of font size. // Sets the proportional line height of current text style. The line height is specified as multiple of font size.
void nvgTextLineHeight(struct NVGcontext* ctx, float lineHeight); void nvgTextLineHeight(NVGcontext* ctx, float lineHeight);
// Sets the text align of current text style, see NVGaling for options. // Sets the text align of current text style, see NVGaling for options.
void nvgTextAlign(struct NVGcontext* ctx, int align); void nvgTextAlign(NVGcontext* ctx, int align);
// Sets the font face based on specified id of current text style. // Sets the font face based on specified id of current text style.
void nvgFontFaceId(struct NVGcontext* ctx, int font); void nvgFontFaceId(NVGcontext* ctx, int font);
// Sets the font face based on specified name of current text style. // Sets the font face based on specified name of current text style.
void nvgFontFace(struct NVGcontext* ctx, const char* font); void nvgFontFace(NVGcontext* ctx, const char* font);
// Draws text string at specified location. If end is specified only the sub-string up to the end is drawn. // Draws text string at specified location. If end is specified only the sub-string up to the end is drawn.
float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, const char* end); float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char* end);
// Draws multi-line text string at specified location wrapped at the specified width. If end is specified only the sub-string up to the end is drawn. // Draws multi-line text string at specified location wrapped at the specified width. If end is specified only the sub-string up to the end is drawn.
// White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. // White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
// Words longer than the max width are slit at nearest character (i.e. no hyphenation). // Words longer than the max width are slit at nearest character (i.e. no hyphenation).
void nvgTextBox(struct NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end); void nvgTextBox(NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end);
// Measures the specified text string. Parameter bounds should be a pointer to float[4], // Measures the specified text string. Parameter bounds should be a pointer to float[4],
// if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax] // if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax]
// Returns the horizontal advance of the measured text (i.e. where the next character should drawn). // Returns the horizontal advance of the measured text (i.e. where the next character should drawn).
// Measured values are returned in local coordinate space. // Measured values are returned in local coordinate space.
float nvgTextBounds(struct NVGcontext* ctx, float x, float y, const char* string, const char* end, float* bounds); float nvgTextBounds(NVGcontext* ctx, float x, float y, const char* string, const char* end, float* bounds);
// Measures the specified multi-text string. Parameter bounds should be a pointer to float[4], // Measures the specified multi-text string. Parameter bounds should be a pointer to float[4],
// if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax] // if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax]
// Measured values are returned in local coordinate space. // Measured values are returned in local coordinate space.
void nvgTextBoxBounds(struct NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds); void nvgTextBoxBounds(NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds);
// Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used. // Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used.
// Measured values are returned in local coordinate space. // Measured values are returned in local coordinate space.
int nvgTextGlyphPositions(struct NVGcontext* ctx, float x, float y, const char* string, const char* end, struct NVGglyphPosition* positions, int maxPositions); int nvgTextGlyphPositions(NVGcontext* ctx, float x, float y, const char* string, const char* end, NVGglyphPosition* positions, int maxPositions);
// Returns the vertical metrics based on the current text style. // Returns the vertical metrics based on the current text style.
// Measured values are returned in local coordinate space. // Measured values are returned in local coordinate space.
void nvgTextMetrics(struct NVGcontext* ctx, float* ascender, float* descender, float* lineh); void nvgTextMetrics(NVGcontext* ctx, float* ascender, float* descender, float* lineh);
// Breaks the specified text into lines. If end is specified only the sub-string will be used. // Breaks the specified text into lines. If end is specified only the sub-string will be used.
// White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. // White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
// Words longer than the max width are slit at nearest character (i.e. no hyphenation). // Words longer than the max width are slit at nearest character (i.e. no hyphenation).
int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* end, float breakRowWidth, struct NVGtextRow* rows, int maxRows); int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, float breakRowWidth, NVGtextRow* rows, int maxRows);
// //
// Internal Render API // Internal Render API
@ -484,60 +555,66 @@ enum NVGtexture {
NVG_TEXTURE_RGBA = 0x02, NVG_TEXTURE_RGBA = 0x02,
}; };
struct NVGscissor struct NVGscissor {
{
float xform[6]; float xform[6];
float extent[2]; float extent[2];
}; };
typedef struct NVGscissor NVGscissor;
struct NVGvertex { struct NVGvertex {
float x,y,u,v; float x,y,u,v;
}; };
typedef struct NVGvertex NVGvertex;
struct NVGpath { struct NVGpath {
int first; int first;
int count; int count;
unsigned char closed; unsigned char closed;
int nbevel; int nbevel;
struct NVGvertex* fill; NVGvertex* fill;
int nfill; int nfill;
struct NVGvertex* stroke; NVGvertex* stroke;
int nstroke; int nstroke;
int winding; int winding;
int convex; int convex;
}; };
typedef struct NVGpath NVGpath;
struct NVGparams { struct NVGparams {
void* userPtr; void* userPtr;
int atlasWidth, atlasHeight;
int edgeAntiAlias; int edgeAntiAlias;
int (*renderCreate)(void* uptr); int (*renderCreate)(void* uptr);
int (*renderCreateTexture)(void* uptr, int type, int w, int h, const unsigned char* data); int (*renderCreateTexture)(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data);
int (*renderDeleteTexture)(void* uptr, int image); int (*renderDeleteTexture)(void* uptr, int image);
int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data);
int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h);
void (*renderViewport)(void* uptr, int width, int height, int alphaBlend); void (*renderViewport)(void* uptr, int width, int height);
void (*renderFlush)(void* uptr, int alphaBlend); void (*renderCancel)(void* uptr);
void (*renderFill)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, const float* bounds, const struct NVGpath* paths, int npaths); void (*renderFlush)(void* uptr);
void (*renderStroke)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, float strokeWidth, const struct NVGpath* paths, int npaths); void (*renderFill)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths);
void (*renderTriangles)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, const struct NVGvertex* verts, int nverts); void (*renderStroke)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths);
void (*renderTriangles)(void* uptr, NVGpaint* paint, NVGscissor* scissor, const NVGvertex* verts, int nverts);
void (*renderDelete)(void* uptr); void (*renderDelete)(void* uptr);
}; };
typedef struct NVGparams NVGparams;
// Contructor and destructor, called by the render back-end. NVGcontext* nvgCreate(int edgeaa, unsigned char viewid);
struct NVGcontext* nvgCreateInternal(struct NVGparams* params);
void nvgDeleteInternal(struct NVGcontext* ctx);
// Debug function to dump cached path data.
void nvgDebugDumpPathCache(struct NVGcontext* ctx);
//
struct NVGcontext* nvgCreate(int atlasw, int atlash, int edgeaa, unsigned char viewid);
//
void nvgDelete(struct NVGcontext* ctx); void nvgDelete(struct NVGcontext* ctx);
#define NVG_NOTUSED(v) for (;;) { (void)(true ? (void)0 : ( (void)(v) ) ); break; } // Contructor and destructor, called by the render back-end.
NVGcontext* nvgCreateInternal(NVGparams* params);
void nvgDeleteInternal(NVGcontext* ctx);
NVGparams* nvgInternalParams(NVGcontext* ctx);
// Debug function to dump cached path data.
void nvgDebugDumpPathCache(NVGcontext* ctx);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#define NVG_NOTUSED(v) for (;;) { (void)(1 ? (void)0 : ( (void)(v) ) ); break; }
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -45,11 +45,17 @@ namespace
NSVG_SHADER_IMG NSVG_SHADER_IMG
}; };
// These are additional flags on top of NVGimageFlags.
enum NVGimageFlagsGL {
NVG_IMAGE_NODELETE = 1<<16, // Do not delete GL texture handle.
};
struct GLNVGtexture struct GLNVGtexture
{ {
bgfx::TextureHandle id; bgfx::TextureHandle id;
int width, height; int width, height;
int type; int type;
int flags;
}; };
enum GLNVGcallType enum GLNVGcallType
@ -198,20 +204,21 @@ namespace
static int glnvg__deleteTexture(struct GLNVGcontext* gl, int id) static int glnvg__deleteTexture(struct GLNVGcontext* gl, int id)
{ {
int i; for (int ii = 0; ii < gl->ntextures; ii++)
for (i = 0; i < gl->ntextures; i++)
{ {
if (gl->textures[i].id.idx == id) if (gl->textures[ii].id.idx == id)
{ {
if (bgfx::isValid(gl->textures[i].id) ) if (bgfx::isValid(gl->textures[ii].id)
&& (gl->textures[ii].flags & NVG_IMAGE_NODELETE) == 0)
{ {
bgfx::destroyTexture(gl->textures[i].id); bgfx::destroyTexture(gl->textures[ii].id);
} }
memset(&gl->textures[i], 0, sizeof(gl->textures[i])); memset(&gl->textures[ii], 0, sizeof(gl->textures[ii]));
gl->textures[i].id.idx = bgfx::invalidHandle; gl->textures[ii].id.idx = bgfx::invalidHandle;
return 1; return 1;
} }
} }
return 0; return 0;
} }
@ -277,7 +284,7 @@ namespace
return 1; return 1;
} }
static int nvgRenderCreateTexture(void* _userPtr, int _type, int _width, int _height, const unsigned char* _rgba) static int nvgRenderCreateTexture(void* _userPtr, int _type, int _width, int _height, int _flags, const unsigned char* _rgba)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr;
struct GLNVGtexture* tex = glnvg__allocTexture(gl); struct GLNVGtexture* tex = glnvg__allocTexture(gl);
@ -290,6 +297,7 @@ namespace
tex->width = _width; tex->width = _width;
tex->height = _height; tex->height = _height;
tex->type = _type; tex->type = _type;
tex->flags = _flags;
uint32_t bytesPerPixel = NVG_TEXTURE_RGBA == tex->type ? 4 : 1; uint32_t bytesPerPixel = NVG_TEXTURE_RGBA == tex->type ? 4 : 1;
uint32_t pitch = tex->width * bytesPerPixel; uint32_t pitch = tex->width * bytesPerPixel;
@ -505,10 +513,9 @@ namespace
gl->th = handle; gl->th = handle;
} }
static void nvgRenderViewport(void* _userPtr, int width, int height, int alphaBlend) static void nvgRenderViewport(void* _userPtr, int width, int height)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr;
NVG_NOTUSED(alphaBlend);
gl->view[0] = (float)width; gl->view[0] = (float)width;
gl->view[1] = (float)height; gl->view[1] = (float)height;
bgfx::setViewRect(gl->viewid, 0, 0, width, height); bgfx::setViewRect(gl->viewid, 0, 0, width, height);
@ -672,7 +679,7 @@ namespace
} }
} }
static void nvgRenderFlush(void* _userPtr, int alphaBlend) static void nvgRenderFlush(void* _userPtr)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr;
@ -687,14 +694,14 @@ namespace
| BGFX_STATE_ALPHA_WRITE | BGFX_STATE_ALPHA_WRITE
; ;
if (alphaBlend == NVG_PREMULTIPLIED_ALPHA) // if (alphaBlend == NVG_PREMULTIPLIED_ALPHA)
{ // {
gl->state |= BGFX_STATE_BLEND_FUNC_SEPARATE( // gl->state |= BGFX_STATE_BLEND_FUNC_SEPARATE(
BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA // BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA
, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_INV_SRC_ALPHA // , BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_INV_SRC_ALPHA
); // );
} // }
else // else
{ {
gl->state |= BGFX_STATE_BLEND_FUNC( gl->state |= BGFX_STATE_BLEND_FUNC(
BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA
@ -977,7 +984,8 @@ namespace
for (uint32_t ii = 0, num = gl->ntextures; ii < num; ++ii) for (uint32_t ii = 0, num = gl->ntextures; ii < num; ++ii)
{ {
if (bgfx::isValid(gl->textures[ii].id) ) if (bgfx::isValid(gl->textures[ii].id)
&& (gl->textures[ii].flags & NVG_IMAGE_NODELETE) == 0)
{ {
bgfx::destroyTexture(gl->textures[ii].id); bgfx::destroyTexture(gl->textures[ii].id);
} }
@ -990,7 +998,7 @@ namespace
} // namespace } // namespace
struct NVGcontext* nvgCreate(int atlasw, int atlash, int edgeaa, unsigned char viewid) NVGcontext* nvgCreate(int edgeaa, unsigned char viewid)
{ {
struct NVGparams params; struct NVGparams params;
struct NVGcontext* ctx = NULL; struct NVGcontext* ctx = NULL;
@ -1011,8 +1019,6 @@ struct NVGcontext* nvgCreate(int atlasw, int atlash, int edgeaa, unsigned char v
params.renderTriangles = nvgRenderTriangles; params.renderTriangles = nvgRenderTriangles;
params.renderDelete = nvgRenderDelete; params.renderDelete = nvgRenderDelete;
params.userPtr = gl; params.userPtr = gl;
params.atlasWidth = atlasw;
params.atlasHeight = atlash;
params.edgeAntiAlias = edgeaa; params.edgeAntiAlias = edgeaa;
gl->edgeAntiAlias = edgeaa; gl->edgeAntiAlias = edgeaa;