Browse Source

Typedef'd structs.

- added typedefs for all structs
- fixed some compiler warnings
shared-context
Mikko Mononen 10 years ago
parent
commit
19f19847fe
7 changed files with 634 additions and 599 deletions
  1. +2
    -2
      example/demo.c
  2. +2
    -0
      example/perf.c
  3. +154
    -138
      src/fontstash.h
  4. +242
    -239
      src/nanovg.c
  5. +100
    -93
      src/nanovg.h
  6. +124
    -118
      src/nanovg_gl.h
  7. +10
    -9
      src/nanovg_gl_utils.h

+ 2
- 2
example/demo.c View File

@@ -24,9 +24,9 @@
#define ICON_LOGIN 0xE740 #define ICON_LOGIN 0xE740
#define ICON_TRASH 0xE729 #define ICON_TRASH 0xE729


static float minf(float a, float b) { return a < b ? a : b; }
//static float minf(float a, float b) { return a < b ? a : b; }
static float maxf(float a, float b) { return a > b ? a : b; } static float maxf(float a, float b) { return a > b ? a : b; }
static float absf(float a) { return a >= 0.0f ? a : -a; }
//static float absf(float a) { return a >= 0.0f ? a : -a; }
static float clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } static float clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); }


// Returns 1 if col.rgba is 0.0f,0.0f,0.0f,0.0f, 0 otherwise // Returns 1 if col.rgba is 0.0f,0.0f,0.0f,0.0f, 0 otherwise


+ 2
- 0
example/perf.c View File

@@ -49,6 +49,8 @@ void startGPUTimer(struct GPUtimer* timer)


int stopGPUTimer(struct GPUtimer* timer, float* times, int maxTimes) int stopGPUTimer(struct GPUtimer* timer, float* times, int maxTimes)
{ {
NVG_NOTUSED(times);
NVG_NOTUSED(maxTimes);
GLint available = 1; GLint available = 1;
int n = 0; int n = 0;
if (!timer->supported) if (!timer->supported)


+ 154
- 138
src/fontstash.h View File

@@ -59,12 +59,14 @@ struct FONSparams {
void (*renderDraw)(void* uptr, const float* verts, const float* tcoords, const unsigned int* colors, int nverts); void (*renderDraw)(void* uptr, const float* verts, const float* tcoords, const unsigned int* colors, int nverts);
void (*renderDelete)(void* uptr); void (*renderDelete)(void* uptr);
}; };
typedef struct FONSparams FONSparams;


struct FONSquad struct FONSquad
{ {
float x0,y0,s0,t0; float x0,y0,s0,t0;
float x1,y1,s1,t1; float x1,y1,s1,t1;
}; };
typedef struct FONSquad FONSquad;


struct FONStextIter { struct FONStextIter {
float x, y, nextx, nexty, scale, spacing; float x, y, nextx, nexty, scale, spacing;
@@ -77,57 +79,60 @@ struct FONStextIter {
const char* end; const char* end;
unsigned int utf8state; unsigned int utf8state;
}; };
typedef struct FONStextIter FONStextIter;

typedef struct FONScontext FONScontext;


// Contructor and destructor. // Contructor and destructor.
struct FONScontext* fonsCreateInternal(struct FONSparams* params);
void fonsDeleteInternal(struct FONScontext* s);
FONScontext* fonsCreateInternal(FONSparams* params);
void fonsDeleteInternal(FONScontext* s);


void fonsSetErrorCallback(struct FONScontext* s, void (*callback)(void* uptr, int error, int val), void* uptr);
void fonsSetErrorCallback(FONScontext* s, void (*callback)(void* uptr, int error, int val), void* uptr);
// Returns current atlas size. // Returns current atlas size.
void fonsGetAtlasSize(struct FONScontext* s, int* width, int* height);
void fonsGetAtlasSize(FONScontext* s, int* width, int* height);
// Expands the atlas size. // Expands the atlas size.
int fonsExpandAtlas(struct FONScontext* s, int width, int height);
int fonsExpandAtlas(FONScontext* s, int width, int height);
// Reseta the whole stash. // Reseta the whole stash.
int fonsResetAtlas(struct FONScontext* stash, int width, int height);
int fonsResetAtlas(FONScontext* stash, int width, int height);


// Add fonts // Add fonts
int fonsAddFont(struct FONScontext* s, const char* name, const char* path);
int fonsAddFontMem(struct FONScontext* s, const char* name, unsigned char* data, int ndata, int freeData);
int fonsGetFontByName(struct FONScontext* s, const char* name);
int fonsAddFont(FONScontext* s, const char* name, const char* path);
int fonsAddFontMem(FONScontext* s, const char* name, unsigned char* data, int ndata, int freeData);
int fonsGetFontByName(FONScontext* s, const char* name);


// State handling // State handling
void fonsPushState(struct FONScontext* s);
void fonsPopState(struct FONScontext* s);
void fonsClearState(struct FONScontext* s);
void fonsPushState(FONScontext* s);
void fonsPopState(FONScontext* s);
void fonsClearState(FONScontext* s);


// State setting // State setting
void fonsSetSize(struct FONScontext* s, float size);
void fonsSetColor(struct FONScontext* s, unsigned int color);
void fonsSetSpacing(struct FONScontext* s, float spacing);
void fonsSetBlur(struct FONScontext* s, float blur);
void fonsSetAlign(struct FONScontext* s, int align);
void fonsSetFont(struct FONScontext* s, int font);
void fonsSetSize(FONScontext* s, float size);
void fonsSetColor(FONScontext* s, unsigned int color);
void fonsSetSpacing(FONScontext* s, float spacing);
void fonsSetBlur(FONScontext* s, float blur);
void fonsSetAlign(FONScontext* s, int align);
void fonsSetFont(FONScontext* s, int font);


// Draw text // Draw text
float fonsDrawText(struct FONScontext* s, float x, float y, const char* string, const char* end);
float fonsDrawText(FONScontext* s, float x, float y, const char* string, const char* end);


// Measure text // Measure text
float fonsTextBounds(struct FONScontext* s, float x, float y, const char* string, const char* end, float* bounds);
void fonsLineBounds(struct FONScontext* s, float y, float* miny, float* maxy);
void fonsVertMetrics(struct FONScontext* s, float* ascender, float* descender, float* lineh);
float fonsTextBounds(FONScontext* s, float x, float y, const char* string, const char* end, float* bounds);
void fonsLineBounds(FONScontext* s, float y, float* miny, float* maxy);
void fonsVertMetrics(FONScontext* s, float* ascender, float* descender, float* lineh);


// Text iterator // Text iterator
int fonsTextIterInit(struct FONScontext* stash, struct FONStextIter* iter, float x, float y, const char* str, const char* end);
int fonsTextIterNext(struct FONScontext* stash, struct FONStextIter* iter, struct FONSquad* quad);
int fonsTextIterInit(FONScontext* stash, FONStextIter* iter, float x, float y, const char* str, const char* end);
int fonsTextIterNext(FONScontext* stash, FONStextIter* iter, struct FONSquad* quad);


// Pull texture changes // Pull texture changes
const unsigned char* fonsGetTextureData(struct FONScontext* stash, int* width, int* height);
int fonsValidateTexture(struct FONScontext* s, int* dirty);
const unsigned char* fonsGetTextureData(FONScontext* stash, int* width, int* height);
int fonsValidateTexture(FONScontext* s, int* dirty);


// Draws the stash texture for debugging // Draws the stash texture for debugging
void fonsDrawDebug(struct FONScontext* s, float x, float y);
void fonsDrawDebug(FONScontext* s, float x, float y);


#endif // FONS_H
#endif // FONTSTASH_H




#ifdef FONTSTASH_IMPLEMENTATION #ifdef FONTSTASH_IMPLEMENTATION
@@ -144,6 +149,7 @@ void fonsDrawDebug(struct FONScontext* s, float x, float y);
struct FONSttFontImpl { struct FONSttFontImpl {
FT_Face font; FT_Face font;
}; };
typedef struct FONSttFontImpl FONSttFontImpl;


static FT_Library ftLibrary; static FT_Library ftLibrary;


@@ -154,7 +160,7 @@ int fons__tt_init()
return ftError == 0; return ftError == 0;
} }


int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font, unsigned char *data, int dataSize)
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize)
{ {
FT_Error ftError; FT_Error ftError;
FONS_NOTUSED(context); FONS_NOTUSED(context);
@@ -164,24 +170,25 @@ int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font,
return ftError == 0; return ftError == 0;
} }


void fons__tt_getFontVMetrics(struct FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
{ {
*ascent = font->font->ascender; *ascent = font->font->ascender;
*descent = font->font->descender; *descent = font->font->descender;
*lineGap = font->font->height - (*ascent - *descent); *lineGap = font->font->height - (*ascent - *descent);
} }


float fons__tt_getPixelHeightScale(struct FONSttFontImpl *font, float size)
float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size)
{ {
return size / (font->font->ascender - font->font->descender); return size / (font->font->ascender - font->font->descender);
} }


int fons__tt_getGlyphIndex(struct FONSttFontImpl *font, int codepoint)
int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint)
{ {
return FT_Get_Char_Index(font->font, codepoint); return FT_Get_Char_Index(font->font, codepoint);
} }


int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale,
int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
{ {
FT_Error ftError; FT_Error ftError;
FT_GlyphSlot ftGlyph; FT_GlyphSlot ftGlyph;
@@ -202,7 +209,8 @@ int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size
return 1; return 1;
} }


void fons__tt_renderGlyphBitmap(struct FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph)
void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride,
float scaleX, float scaleY, int glyph)
{ {
FT_GlyphSlot ftGlyph = font->font->glyph; FT_GlyphSlot ftGlyph = font->font->glyph;
int ftGlyphOffset = 0; int ftGlyphOffset = 0;
@@ -220,7 +228,7 @@ void fons__tt_renderGlyphBitmap(struct FONSttFontImpl *font, unsigned char *outp
} }
} }


int fons__tt_getGlyphKernAdvance(struct FONSttFontImpl *font, int glyph1, int glyph2)
int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2)
{ {
FT_Vector ftKerning; FT_Vector ftKerning;
FT_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning); FT_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning);
@@ -239,14 +247,15 @@ static void fons__tmpfree(void* ptr, void* up);
struct FONSttFontImpl { struct FONSttFontImpl {
stbtt_fontinfo font; stbtt_fontinfo font;
}; };
typedef struct FONSttFontImpl FONSttFontImpl;


int fons__tt_init(struct FONScontext *context)
int fons__tt_init(FONScontext *context)
{ {
FONS_NOTUSED(context); FONS_NOTUSED(context);
return 1; return 1;
} }


int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font, unsigned char *data, int dataSize)
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize)
{ {
int stbError; int stbError;
FONS_NOTUSED(dataSize); FONS_NOTUSED(dataSize);
@@ -256,22 +265,23 @@ int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font,
return stbError; return stbError;
} }


void fons__tt_getFontVMetrics(struct FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap)
{ {
stbtt_GetFontVMetrics(&font->font, ascent, descent, lineGap); stbtt_GetFontVMetrics(&font->font, ascent, descent, lineGap);
} }


float fons__tt_getPixelHeightScale(struct FONSttFontImpl *font, float size)
float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size)
{ {
return stbtt_ScaleForPixelHeight(&font->font, size); return stbtt_ScaleForPixelHeight(&font->font, size);
} }


int fons__tt_getGlyphIndex(struct FONSttFontImpl *font, int codepoint)
int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint)
{ {
return stbtt_FindGlyphIndex(&font->font, codepoint); return stbtt_FindGlyphIndex(&font->font, codepoint);
} }


int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale,
int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1)
{ {
FONS_NOTUSED(size); FONS_NOTUSED(size);
stbtt_GetGlyphHMetrics(&font->font, glyph, advance, lsb); stbtt_GetGlyphHMetrics(&font->font, glyph, advance, lsb);
@@ -279,12 +289,13 @@ int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size
return 1; return 1;
} }


void fons__tt_renderGlyphBitmap(struct FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph)
void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride,
float scaleX, float scaleY, int glyph)
{ {
stbtt_MakeGlyphBitmap(&font->font, output, outWidth, outHeight, outStride, scaleX, scaleY, glyph); stbtt_MakeGlyphBitmap(&font->font, output, outWidth, outHeight, outStride, scaleX, scaleY, glyph);
} }


int fons__tt_getGlyphKernAdvance(struct FONSttFontImpl *font, int glyph1, int glyph2)
int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2)
{ {
return stbtt_GetGlyphKernAdvance(&font->font, glyph1, glyph2); return stbtt_GetGlyphKernAdvance(&font->font, glyph1, glyph2);
} }
@@ -343,10 +354,11 @@ struct FONSglyph
short x0,y0,x1,y1; short x0,y0,x1,y1;
short xadv,xoff,yoff; short xadv,xoff,yoff;
}; };
typedef struct FONSglyph FONSglyph;


struct FONSfont struct FONSfont
{ {
struct FONSttFontImpl font;
FONSttFontImpl font;
char name[64]; char name[64];
unsigned char* data; unsigned char* data;
int dataSize; int dataSize;
@@ -354,11 +366,12 @@ struct FONSfont
float ascender; float ascender;
float descender; float descender;
float lineh; float lineh;
struct FONSglyph* glyphs;
FONSglyph* glyphs;
int cglyphs; int cglyphs;
int nglyphs; int nglyphs;
int lut[FONS_HASH_LUT_SIZE]; int lut[FONS_HASH_LUT_SIZE];
}; };
typedef struct FONSfont FONSfont;


struct FONSstate struct FONSstate
{ {
@@ -369,27 +382,30 @@ struct FONSstate
float blur; float blur;
float spacing; float spacing;
}; };
typedef struct FONSstate FONSstate;


struct FONSatlasNode { struct FONSatlasNode {
short x, y, width; short x, y, width;
}; };
typedef struct FONSatlasNode FONSatlasNode;


struct FONSatlas struct FONSatlas
{ {
int width, height; int width, height;
struct FONSatlasNode* nodes;
FONSatlasNode* nodes;
int nnodes; int nnodes;
int cnodes; int cnodes;
}; };
typedef struct FONSatlas FONSatlas;


struct FONScontext struct FONScontext
{ {
struct FONSparams params;
FONSparams params;
float itw,ith; float itw,ith;
unsigned char* texData; unsigned char* texData;
int dirtyRect[4]; int dirtyRect[4];
struct FONSfont** fonts;
struct FONSatlas* atlas;
FONSfont** fonts;
FONSatlas* atlas;
int cfonts; int cfonts;
int nfonts; int nfonts;
float verts[FONS_VERTEX_COUNT*2]; float verts[FONS_VERTEX_COUNT*2];
@@ -398,7 +414,7 @@ struct FONScontext
int nverts; int nverts;
unsigned char* scratch; unsigned char* scratch;
int nscratch; int nscratch;
struct FONSstate states[FONS_MAX_STATES];
FONSstate states[FONS_MAX_STATES];
int nstates; int nstates;
void (*handleError)(void* uptr, int error, int val); void (*handleError)(void* uptr, int error, int val);
void* errorUptr; void* errorUptr;
@@ -407,7 +423,7 @@ struct FONScontext
static void* fons__tmpalloc(size_t size, void* up) static void* fons__tmpalloc(size_t size, void* up)
{ {
unsigned char* ptr; unsigned char* ptr;
struct FONScontext* stash = (struct FONScontext*)up;
FONScontext* stash = (FONScontext*)up;


// 16-byte align the returned pointer // 16-byte align the returned pointer
size = (size + 0xf) & ~0xf; size = (size + 0xf) & ~0xf;
@@ -470,29 +486,29 @@ static unsigned int fons__decutf8(unsigned int* state, unsigned int* codep, unsi


// Atlas based on Skyline Bin Packer by Jukka Jylänki // Atlas based on Skyline Bin Packer by Jukka Jylänki


static void fons__deleteAtlas(struct FONSatlas* atlas)
static void fons__deleteAtlas(FONSatlas* atlas)
{ {
if (atlas == NULL) return; if (atlas == NULL) return;
if (atlas->nodes != NULL) free(atlas->nodes); if (atlas->nodes != NULL) free(atlas->nodes);
free(atlas); free(atlas);
} }


static struct FONSatlas* fons__allocAtlas(int w, int h, int nnodes)
static FONSatlas* fons__allocAtlas(int w, int h, int nnodes)
{ {
struct FONSatlas* atlas = NULL;
FONSatlas* atlas = NULL;


// Allocate memory for the font stash. // Allocate memory for the font stash.
atlas = (struct FONSatlas*)malloc(sizeof(struct FONSatlas));
atlas = (FONSatlas*)malloc(sizeof(FONSatlas));
if (atlas == NULL) goto error; if (atlas == NULL) goto error;
memset(atlas, 0, sizeof(struct FONSatlas));
memset(atlas, 0, sizeof(FONSatlas));


atlas->width = w; atlas->width = w;
atlas->height = h; atlas->height = h;


// Allocate space for skyline nodes // Allocate space for skyline nodes
atlas->nodes = (struct FONSatlasNode*)malloc(sizeof(struct FONSatlasNode) * nnodes);
atlas->nodes = (FONSatlasNode*)malloc(sizeof(FONSatlasNode) * nnodes);
if (atlas->nodes == NULL) goto error; if (atlas->nodes == NULL) goto error;
memset(atlas->nodes, 0, sizeof(struct FONSatlasNode) * nnodes);
memset(atlas->nodes, 0, sizeof(FONSatlasNode) * nnodes);
atlas->nnodes = 0; atlas->nnodes = 0;
atlas->cnodes = nnodes; atlas->cnodes = nnodes;


@@ -509,13 +525,13 @@ error:
return NULL; return NULL;
} }


static int fons__atlasInsertNode(struct FONSatlas* atlas, int idx, int x, int y, int w)
static int fons__atlasInsertNode(FONSatlas* atlas, int idx, int x, int y, int w)
{ {
int i; int i;
// Insert node // Insert node
if (atlas->nnodes+1 > atlas->cnodes) { if (atlas->nnodes+1 > atlas->cnodes) {
atlas->cnodes = atlas->cnodes == 0 ? 8 : atlas->cnodes * 2; atlas->cnodes = atlas->cnodes == 0 ? 8 : atlas->cnodes * 2;
atlas->nodes = (struct FONSatlasNode*)realloc(atlas->nodes, sizeof(struct FONSatlasNode) * atlas->cnodes);
atlas->nodes = (FONSatlasNode*)realloc(atlas->nodes, sizeof(FONSatlasNode) * atlas->cnodes);
if (atlas->nodes == NULL) if (atlas->nodes == NULL)
return 0; return 0;
} }
@@ -529,7 +545,7 @@ static int fons__atlasInsertNode(struct FONSatlas* atlas, int idx, int x, int y,
return 1; return 1;
} }


static void fons__atlasRemoveNode(struct FONSatlas* atlas, int idx)
static void fons__atlasRemoveNode(FONSatlas* atlas, int idx)
{ {
int i; int i;
if (atlas->nnodes == 0) return; if (atlas->nnodes == 0) return;
@@ -538,7 +554,7 @@ static void fons__atlasRemoveNode(struct FONSatlas* atlas, int idx)
atlas->nnodes--; atlas->nnodes--;
} }


static void fons__atlasExpand(struct FONSatlas* atlas, int w, int h)
static void fons__atlasExpand(FONSatlas* atlas, int w, int h)
{ {
// Insert node for empty space // Insert node for empty space
if (w > atlas->width) if (w > atlas->width)
@@ -547,7 +563,7 @@ static void fons__atlasExpand(struct FONSatlas* atlas, int w, int h)
atlas->height = h; atlas->height = h;
} }


static void fons__atlasReset(struct FONSatlas* atlas, int w, int h)
static void fons__atlasReset(FONSatlas* atlas, int w, int h)
{ {
atlas->width = w; atlas->width = w;
atlas->height = h; atlas->height = h;
@@ -560,7 +576,7 @@ static void fons__atlasReset(struct FONSatlas* atlas, int w, int h)
atlas->nnodes++; atlas->nnodes++;
} }


static int fons__atlasAddSkylineLevel(struct FONSatlas* atlas, int idx, int x, int y, int w, int h)
static int fons__atlasAddSkylineLevel(FONSatlas* atlas, int idx, int x, int y, int w, int h)
{ {
int i; int i;


@@ -597,7 +613,7 @@ static int fons__atlasAddSkylineLevel(struct FONSatlas* atlas, int idx, int x, i
return 1; return 1;
} }


static int fons__atlasRectFits(struct FONSatlas* atlas, int i, int w, int h)
static int fons__atlasRectFits(FONSatlas* atlas, int i, int w, int h)
{ {
// Checks if there is enough space at the location of skyline span 'i', // Checks if there is enough space at the location of skyline span 'i',
// and return the max height of all skyline spans under that at that location, // and return the max height of all skyline spans under that at that location,
@@ -618,7 +634,7 @@ static int fons__atlasRectFits(struct FONSatlas* atlas, int i, int w, int h)
return y; return y;
} }


static int fons__atlasAddRect(struct FONSatlas* atlas, int rw, int rh, int* rx, int* ry)
static int fons__atlasAddRect(FONSatlas* atlas, int rw, int rh, int* rx, int* ry)
{ {
int besth = atlas->height, bestw = atlas->width, besti = -1; int besth = atlas->height, bestw = atlas->width, besti = -1;
int bestx = -1, besty = -1, i; int bestx = -1, besty = -1, i;
@@ -650,7 +666,7 @@ static int fons__atlasAddRect(struct FONSatlas* atlas, int rw, int rh, int* rx,
return 1; return 1;
} }


static void fons__addWhiteRect(struct FONScontext* stash, int w, int h)
static void fons__addWhiteRect(FONScontext* stash, int w, int h)
{ {
int x, y, gx, gy; int x, y, gx, gy;
unsigned char* dst; unsigned char* dst;
@@ -671,14 +687,14 @@ static void fons__addWhiteRect(struct FONScontext* stash, int w, int h)
stash->dirtyRect[3] = fons__maxi(stash->dirtyRect[3], gy+h); stash->dirtyRect[3] = fons__maxi(stash->dirtyRect[3], gy+h);
} }


struct FONScontext* fonsCreateInternal(struct FONSparams* params)
FONScontext* fonsCreateInternal(FONSparams* params)
{ {
struct FONScontext* stash = NULL;
FONScontext* stash = NULL;


// Allocate memory for the font stash. // Allocate memory for the font stash.
stash = (struct FONScontext*)malloc(sizeof(struct FONScontext));
stash = (FONScontext*)malloc(sizeof(FONScontext));
if (stash == NULL) goto error; if (stash == NULL) goto error;
memset(stash, 0, sizeof(struct FONScontext));
memset(stash, 0, sizeof(FONScontext));


stash->params = *params; stash->params = *params;


@@ -698,9 +714,9 @@ struct FONScontext* fonsCreateInternal(struct FONSparams* params)
if (stash->atlas == NULL) goto error; if (stash->atlas == NULL) goto error;


// Allocate space for fonts. // Allocate space for fonts.
stash->fonts = (struct FONSfont**)malloc(sizeof(struct FONSfont*) * FONS_INIT_FONTS);
stash->fonts = (FONSfont**)malloc(sizeof(FONSfont*) * FONS_INIT_FONTS);
if (stash->fonts == NULL) goto error; if (stash->fonts == NULL) goto error;
memset(stash->fonts, 0, sizeof(struct FONSfont*) * FONS_INIT_FONTS);
memset(stash->fonts, 0, sizeof(FONSfont*) * FONS_INIT_FONTS);
stash->cfonts = FONS_INIT_FONTS; stash->cfonts = FONS_INIT_FONTS;
stash->nfonts = 0; stash->nfonts = 0;


@@ -729,42 +745,42 @@ error:
return NULL; return NULL;
} }


static struct FONSstate* fons__getState(struct FONScontext* stash)
static FONSstate* fons__getState(FONScontext* stash)
{ {
return &stash->states[stash->nstates-1]; return &stash->states[stash->nstates-1];
} }


void fonsSetSize(struct FONScontext* stash, float size)
void fonsSetSize(FONScontext* stash, float size)
{ {
fons__getState(stash)->size = size; fons__getState(stash)->size = size;
} }


void fonsSetColor(struct FONScontext* stash, unsigned int color)
void fonsSetColor(FONScontext* stash, unsigned int color)
{ {
fons__getState(stash)->color = color; fons__getState(stash)->color = color;
} }


void fonsSetSpacing(struct FONScontext* stash, float spacing)
void fonsSetSpacing(FONScontext* stash, float spacing)
{ {
fons__getState(stash)->spacing = spacing; fons__getState(stash)->spacing = spacing;
} }


void fonsSetBlur(struct FONScontext* stash, float blur)
void fonsSetBlur(FONScontext* stash, float blur)
{ {
fons__getState(stash)->blur = blur; fons__getState(stash)->blur = blur;
} }


void fonsSetAlign(struct FONScontext* stash, int align)
void fonsSetAlign(FONScontext* stash, int align)
{ {
fons__getState(stash)->align = align; fons__getState(stash)->align = align;
} }


void fonsSetFont(struct FONScontext* stash, int font)
void fonsSetFont(FONScontext* stash, int font)
{ {
fons__getState(stash)->font = font; fons__getState(stash)->font = font;
} }


void fonsPushState(struct FONScontext* stash)
void fonsPushState(FONScontext* stash)
{ {
if (stash->nstates >= FONS_MAX_STATES) { if (stash->nstates >= FONS_MAX_STATES) {
if (stash->handleError) if (stash->handleError)
@@ -772,11 +788,11 @@ void fonsPushState(struct FONScontext* stash)
return; return;
} }
if (stash->nstates > 0) if (stash->nstates > 0)
memcpy(&stash->states[stash->nstates], &stash->states[stash->nstates-1], sizeof(struct FONSstate));
memcpy(&stash->states[stash->nstates], &stash->states[stash->nstates-1], sizeof(FONSstate));
stash->nstates++; stash->nstates++;
} }


void fonsPopState(struct FONScontext* stash)
void fonsPopState(FONScontext* stash)
{ {
if (stash->nstates <= 1) { if (stash->nstates <= 1) {
if (stash->handleError) if (stash->handleError)
@@ -786,9 +802,9 @@ void fonsPopState(struct FONScontext* stash)
stash->nstates--; stash->nstates--;
} }


void fonsClearState(struct FONScontext* stash)
void fonsClearState(FONScontext* stash)
{ {
struct FONSstate* state = fons__getState(stash);
FONSstate* state = fons__getState(stash);
state->size = 12.0f; state->size = 12.0f;
state->color = 0xffffffff; state->color = 0xffffffff;
state->font = 0; state->font = 0;
@@ -797,7 +813,7 @@ void fonsClearState(struct FONScontext* stash)
state->align = FONS_ALIGN_LEFT | FONS_ALIGN_BASELINE; state->align = FONS_ALIGN_LEFT | FONS_ALIGN_BASELINE;
} }


static void fons__freeFont(struct FONSfont* font)
static void fons__freeFont(FONSfont* font)
{ {
if (font == NULL) return; if (font == NULL) return;
if (font->glyphs) free(font->glyphs); if (font->glyphs) free(font->glyphs);
@@ -805,20 +821,20 @@ static void fons__freeFont(struct FONSfont* font)
free(font); free(font);
} }


static int fons__allocFont(struct FONScontext* stash)
static int fons__allocFont(FONScontext* stash)
{ {
struct FONSfont* font = NULL;
FONSfont* font = NULL;
if (stash->nfonts+1 > stash->cfonts) { if (stash->nfonts+1 > stash->cfonts) {
stash->cfonts = stash->cfonts == 0 ? 8 : stash->cfonts * 2; stash->cfonts = stash->cfonts == 0 ? 8 : stash->cfonts * 2;
stash->fonts = (struct FONSfont**)realloc(stash->fonts, sizeof(struct FONSfont*) * stash->cfonts);
stash->fonts = (FONSfont**)realloc(stash->fonts, sizeof(FONSfont*) * stash->cfonts);
if (stash->fonts == NULL) if (stash->fonts == NULL)
return -1; return -1;
} }
font = (struct FONSfont*)malloc(sizeof(struct FONSfont));
font = (FONSfont*)malloc(sizeof(FONSfont));
if (font == NULL) goto error; if (font == NULL) goto error;
memset(font, 0, sizeof(struct FONSfont));
memset(font, 0, sizeof(FONSfont));


font->glyphs = (struct FONSglyph*)malloc(sizeof(struct FONSglyph) * FONS_INIT_GLYPHS);
font->glyphs = (FONSglyph*)malloc(sizeof(FONSglyph) * FONS_INIT_GLYPHS);
if (font->glyphs == NULL) goto error; if (font->glyphs == NULL) goto error;
font->cglyphs = FONS_INIT_GLYPHS; font->cglyphs = FONS_INIT_GLYPHS;
font->nglyphs = 0; font->nglyphs = 0;
@@ -832,7 +848,7 @@ error:
return FONS_INVALID; return FONS_INVALID;
} }


int fonsAddFont(struct FONScontext* stash, const char* name, const char* path)
int fonsAddFont(FONScontext* stash, const char* name, const char* path)
{ {
FILE* fp = 0; FILE* fp = 0;
int dataSize = 0; int dataSize = 0;
@@ -858,10 +874,10 @@ error:
return FONS_INVALID; return FONS_INVALID;
} }


int fonsAddFontMem(struct FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData)
int fonsAddFontMem(FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData)
{ {
int i, ascent, descent, fh, lineGap; int i, ascent, descent, fh, lineGap;
struct FONSfont* font;
FONSfont* font;


int idx = fons__allocFont(stash); int idx = fons__allocFont(stash);
if (idx == FONS_INVALID) if (idx == FONS_INVALID)
@@ -901,7 +917,7 @@ error:
return FONS_INVALID; return FONS_INVALID;
} }


int fonsGetFontByName(struct FONScontext* s, const char* name)
int fonsGetFontByName(FONScontext* s, const char* name)
{ {
int i; int i;
for (i = 0; i < s->nfonts; i++) { for (i = 0; i < s->nfonts; i++) {
@@ -912,11 +928,11 @@ int fonsGetFontByName(struct FONScontext* s, const char* name)
} }




static struct FONSglyph* fons__allocGlyph(struct FONSfont* font)
static FONSglyph* fons__allocGlyph(FONSfont* font)
{ {
if (font->nglyphs+1 > font->cglyphs) { if (font->nglyphs+1 > font->cglyphs) {
font->cglyphs = font->cglyphs == 0 ? 8 : font->cglyphs * 2; font->cglyphs = font->cglyphs == 0 ? 8 : font->cglyphs * 2;
font->glyphs = (struct FONSglyph*)realloc(font->glyphs, sizeof(struct FONSglyph) * font->cglyphs);
font->glyphs = (FONSglyph*)realloc(font->glyphs, sizeof(FONSglyph) * font->cglyphs);
if (font->glyphs == NULL) return NULL; if (font->glyphs == NULL) return NULL;
} }
font->nglyphs++; font->nglyphs++;
@@ -970,7 +986,7 @@ static void fons__blurRows(unsigned char* dst, int w, int h, int dstStride, int
} }




static void fons__blur(struct FONScontext* stash, unsigned char* dst, int w, int h, int dstStride, int blur)
static void fons__blur(FONScontext* stash, unsigned char* dst, int w, int h, int dstStride, int blur)
{ {
int alpha; int alpha;
float sigma; float sigma;
@@ -989,12 +1005,12 @@ static void fons__blur(struct FONScontext* stash, unsigned char* dst, int w, int
// fons__blurcols(dst, w, h, dstStride, alpha); // fons__blurcols(dst, w, h, dstStride, alpha);
} }


static struct FONSglyph* fons__getGlyph(struct FONScontext* stash, struct FONSfont* font, unsigned int codepoint,
short isize, short iblur)
static FONSglyph* fons__getGlyph(FONScontext* stash, FONSfont* font, unsigned int codepoint,
short isize, short iblur)
{ {
int i, g, advance, lsb, x0, y0, x1, y1, gw, gh, gx, gy, x, y; int i, g, advance, lsb, x0, y0, x1, y1, gw, gh, gx, gy, x, y;
float scale; float scale;
struct FONSglyph* glyph = NULL;
FONSglyph* glyph = NULL;
unsigned int h; unsigned int h;
float size = isize/10.0f; float size = isize/10.0f;
int pad, added; int pad, added;
@@ -1092,9 +1108,9 @@ static struct FONSglyph* fons__getGlyph(struct FONScontext* stash, struct FONSfo
return glyph; return glyph;
} }


static void fons__getQuad(struct FONScontext* stash, struct FONSfont* font,
int prevGlyphIndex, struct FONSglyph* glyph,
float scale, float spacing, float* x, float* y, struct FONSquad* q)
static void fons__getQuad(FONScontext* stash, FONSfont* font,
int prevGlyphIndex, FONSglyph* glyph,
float scale, float spacing, float* x, float* y, FONSquad* q)
{ {
float rx,ry,xoff,yoff,x0,y0,x1,y1; float rx,ry,xoff,yoff,x0,y0,x1,y1;


@@ -1144,7 +1160,7 @@ static void fons__getQuad(struct FONScontext* stash, struct FONSfont* font,
*x += (int)(glyph->xadv / 10.0f + 0.5f); *x += (int)(glyph->xadv / 10.0f + 0.5f);
} }


static void fons__flush(struct FONScontext* stash)
static void fons__flush(FONScontext* stash)
{ {
// Flush texture // Flush texture
if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) { if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) {
@@ -1165,7 +1181,7 @@ static void fons__flush(struct FONScontext* stash)
} }
} }


static __inline void fons__vertex(struct FONScontext* stash, float x, float y, float s, float t, unsigned int c)
static __inline void fons__vertex(FONScontext* stash, float x, float y, float s, float t, unsigned int c)
{ {
stash->verts[stash->nverts*2+0] = x; stash->verts[stash->nverts*2+0] = x;
stash->verts[stash->nverts*2+1] = y; stash->verts[stash->nverts*2+1] = y;
@@ -1175,7 +1191,7 @@ static __inline void fons__vertex(struct FONScontext* stash, float x, float y, f
stash->nverts++; stash->nverts++;
} }


static float fons__getVertAlign(struct FONScontext* stash, struct FONSfont* font, int align, short isize)
static float fons__getVertAlign(FONScontext* stash, FONSfont* font, int align, short isize)
{ {
if (stash->params.flags & FONS_ZERO_TOPLEFT) { if (stash->params.flags & FONS_ZERO_TOPLEFT) {
if (align & FONS_ALIGN_TOP) { if (align & FONS_ALIGN_TOP) {
@@ -1201,20 +1217,20 @@ static float fons__getVertAlign(struct FONScontext* stash, struct FONSfont* font
return 0.0; return 0.0;
} }


float fonsDrawText(struct FONScontext* stash,
float fonsDrawText(FONScontext* stash,
float x, float y, float x, float y,
const char* str, const char* end) const char* str, const char* end)
{ {
struct FONSstate* state = fons__getState(stash);
FONSstate* state = fons__getState(stash);
unsigned int codepoint; unsigned int codepoint;
unsigned int utf8state = 0; unsigned int utf8state = 0;
struct FONSglyph* glyph = NULL;
struct FONSquad q;
FONSglyph* glyph = NULL;
FONSquad q;
int prevGlyphIndex = -1; int prevGlyphIndex = -1;
short isize = (short)(state->size*10.0f); short isize = (short)(state->size*10.0f);
short iblur = (short)state->blur; short iblur = (short)state->blur;
float scale; float scale;
struct FONSfont* font;
FONSfont* font;
float width; float width;


if (stash == NULL) return x; if (stash == NULL) return x;
@@ -1265,10 +1281,10 @@ float fonsDrawText(struct FONScontext* stash,
return x; return x;
} }


int fonsTextIterInit(struct FONScontext* stash, struct FONStextIter* iter,
int fonsTextIterInit(FONScontext* stash, FONStextIter* iter,
float x, float y, const char* str, const char* end) float x, float y, const char* str, const char* end)
{ {
struct FONSstate* state = fons__getState(stash);
FONSstate* state = fons__getState(stash);
float width; float width;


memset(iter, 0, sizeof(*iter)); memset(iter, 0, sizeof(*iter));
@@ -1310,9 +1326,9 @@ int fonsTextIterInit(struct FONScontext* stash, struct FONStextIter* iter,
return 1; return 1;
} }


int fonsTextIterNext(struct FONScontext* stash, struct FONStextIter* iter, struct FONSquad* quad)
int fonsTextIterNext(FONScontext* stash, FONStextIter* iter, FONSquad* quad)
{ {
struct FONSglyph* glyph = NULL;
FONSglyph* glyph = NULL;
const char* str = iter->next; const char* str = iter->next;
iter->str = iter->next; iter->str = iter->next;


@@ -1337,7 +1353,7 @@ int fonsTextIterNext(struct FONScontext* stash, struct FONStextIter* iter, struc
return 1; return 1;
} }


void fonsDrawDebug(struct FONScontext* stash, float x, float y)
void fonsDrawDebug(FONScontext* stash, float x, float y)
{ {
int i; int i;
int w = stash->params.width; int w = stash->params.width;
@@ -1368,7 +1384,7 @@ void fonsDrawDebug(struct FONScontext* stash, float x, float y)


// Drawbug draw atlas // Drawbug draw atlas
for (i = 0; i < stash->atlas->nnodes; i++) { for (i = 0; i < stash->atlas->nnodes; i++) {
struct FONSatlasNode* n = &stash->atlas->nodes[i];
FONSatlasNode* n = &stash->atlas->nodes[i];


if (stash->nverts+6 > FONS_VERTEX_COUNT) if (stash->nverts+6 > FONS_VERTEX_COUNT)
fons__flush(stash); fons__flush(stash);
@@ -1385,21 +1401,21 @@ void fonsDrawDebug(struct FONScontext* stash, float x, float y)
fons__flush(stash); fons__flush(stash);
} }


float fonsTextBounds(struct FONScontext* stash,
float fonsTextBounds(FONScontext* stash,
float x, float y, float x, float y,
const char* str, const char* end, const char* str, const char* end,
float* bounds) float* bounds)
{ {
struct FONSstate* state = fons__getState(stash);
FONSstate* state = fons__getState(stash);
unsigned int codepoint; unsigned int codepoint;
unsigned int utf8state = 0; unsigned int utf8state = 0;
struct FONSquad q;
struct FONSglyph* glyph = NULL;
FONSquad q;
FONSglyph* glyph = NULL;
int prevGlyphIndex = -1; int prevGlyphIndex = -1;
short isize = (short)(state->size*10.0f); short isize = (short)(state->size*10.0f);
short iblur = (short)state->blur; short iblur = (short)state->blur;
float scale; float scale;
struct FONSfont* font;
FONSfont* font;
float startx, advance; float startx, advance;
float minx, miny, maxx, maxy; float minx, miny, maxx, maxy;


@@ -1462,11 +1478,11 @@ float fonsTextBounds(struct FONScontext* stash,
return advance; return advance;
} }


void fonsVertMetrics(struct FONScontext* stash,
void fonsVertMetrics(FONScontext* stash,
float* ascender, float* descender, float* lineh) float* ascender, float* descender, float* lineh)
{ {
struct FONSfont* font;
struct FONSstate* state = fons__getState(stash);
FONSfont* font;
FONSstate* state = fons__getState(stash);
short isize; short isize;


if (stash == NULL) return; if (stash == NULL) return;
@@ -1483,10 +1499,10 @@ void fonsVertMetrics(struct FONScontext* stash,
*lineh = font->lineh*isize/10.0f; *lineh = font->lineh*isize/10.0f;
} }


void fonsLineBounds(struct FONScontext* stash, float y, float* miny, float* maxy)
void fonsLineBounds(FONScontext* stash, float y, float* miny, float* maxy)
{ {
struct FONSfont* font;
struct FONSstate* state = fons__getState(stash);
FONSfont* font;
FONSstate* state = fons__getState(stash);
short isize; short isize;


if (stash == NULL) return; if (stash == NULL) return;
@@ -1506,7 +1522,7 @@ void fonsLineBounds(struct FONScontext* stash, float y, float* miny, float* maxy
} }
} }


const unsigned char* fonsGetTextureData(struct FONScontext* stash, int* width, int* height)
const unsigned char* fonsGetTextureData(FONScontext* stash, int* width, int* height)
{ {
if (width != NULL) if (width != NULL)
*width = stash->params.width; *width = stash->params.width;
@@ -1515,7 +1531,7 @@ const unsigned char* fonsGetTextureData(struct FONScontext* stash, int* width, i
return stash->texData; return stash->texData;
} }


int fonsValidateTexture(struct FONScontext* stash, int* dirty)
int fonsValidateTexture(FONScontext* stash, int* dirty)
{ {
if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) { if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) {
dirty[0] = stash->dirtyRect[0]; dirty[0] = stash->dirtyRect[0];
@@ -1532,7 +1548,7 @@ int fonsValidateTexture(struct FONScontext* stash, int* dirty)
return 0; return 0;
} }


void fonsDeleteInternal(struct FONScontext* stash)
void fonsDeleteInternal(FONScontext* stash)
{ {
int i; int i;
if (stash == NULL) return; if (stash == NULL) return;
@@ -1550,21 +1566,21 @@ void fonsDeleteInternal(struct FONScontext* stash)
free(stash); free(stash);
} }


void fonsSetErrorCallback(struct FONScontext* stash, void (*callback)(void* uptr, int error, int val), void* uptr)
void fonsSetErrorCallback(FONScontext* stash, void (*callback)(void* uptr, int error, int val), void* uptr)
{ {
if (stash == NULL) return; if (stash == NULL) return;
stash->handleError = callback; stash->handleError = callback;
stash->errorUptr = uptr; stash->errorUptr = uptr;
} }


void fonsGetAtlasSize(struct FONScontext* stash, int* width, int* height)
void fonsGetAtlasSize(FONScontext* stash, int* width, int* height)
{ {
if (stash == NULL) return; if (stash == NULL) return;
*width = stash->params.width; *width = stash->params.width;
*height = stash->params.height; *height = stash->params.height;
} }


int fonsExpandAtlas(struct FONScontext* stash, int width, int height)
int fonsExpandAtlas(FONScontext* stash, int width, int height)
{ {
int i, maxy = 0; int i, maxy = 0;
unsigned char* data = NULL; unsigned char* data = NULL;
@@ -1620,7 +1636,7 @@ int fonsExpandAtlas(struct FONScontext* stash, int width, int height)
return 1; return 1;
} }


int fonsResetAtlas(struct FONScontext* stash, int width, int height)
int fonsResetAtlas(FONScontext* stash, int width, int height)
{ {
int i, j; int i, j;
if (stash == NULL) return 0; if (stash == NULL) return 0;
@@ -1650,7 +1666,7 @@ int fonsResetAtlas(struct FONScontext* stash, int width, int height)


// Reset cached glyphs // Reset cached glyphs
for (i = 0; i < stash->nfonts; i++) { for (i = 0; i < stash->nfonts; i++) {
struct FONSfont* font = stash->fonts[i];
FONSfont* font = stash->fonts[i];
font->nglyphs = 0; font->nglyphs = 0;
for (j = 0; j < FONS_HASH_LUT_SIZE; j++) for (j = 0; j < FONS_HASH_LUT_SIZE; j++)
font->lut[j] = -1; font->lut[j] = -1;


+ 242
- 239
src/nanovg.c
File diff suppressed because it is too large
View File


+ 100
- 93
src/nanovg.h View File

@@ -30,7 +30,7 @@ extern "C" {
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
#endif #endif


struct NVGcontext;
typedef struct NVGcontext NVGcontext;


struct NVGcolor { struct NVGcolor {
union { union {
@@ -40,17 +40,19 @@ 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;
struct NVGcolor outerColor;
NVGcolor innerColor;
NVGcolor outerColor;
int image; int image;
int repeat; int repeat;
}; };
typedef struct NVGpaint NVGpaint;


enum NVGwinding { enum NVGwinding {
NVG_CCW = 1, // Winding for solid shapes NVG_CCW = 1, // Winding for solid shapes
@@ -93,6 +95,7 @@ struct NVGglyphPosition {
float x; // The x-coordinate of the logical glyph position. float x; // The x-coordinate of the logical glyph position.
float minx, maxx; // The bounds of the glyph shape. 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.
@@ -101,6 +104,7 @@ 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 NVGimage { enum NVGimage {
NVG_IMAGE_GENERATE_MIPMAPS = 1 << 0 // Generate mipmaps during creation of the image. NVG_IMAGE_GENERATE_MIPMAPS = 1 << 0 // Generate mipmaps during creation of the image.
@@ -114,10 +118,10 @@ enum NVGimage {
// 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.
void nvgBeginFrame(struct NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio);
void nvgBeginFrame(NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio);


// 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
@@ -125,35 +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);


// 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
@@ -164,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
@@ -182,35 +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. // Sets the transparency applied to all rendered shapes.
// Alreade transparent paths will get proportionally more transparent as well. // Alreade transparent paths will get proportionally more transparent as well.
void nvgGlobalAlpha(struct NVGcontext* ctx, float alpha);
void nvgGlobalAlpha(NVGcontext* ctx, float alpha);


// //
// Transforms // Transforms
@@ -230,36 +234,36 @@ void nvgGlobalAlpha(struct NVGcontext* ctx, float alpha);
// 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. Angle is specifid in radians. // 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. // Skews the current coordinate system along X axis. Angle is specifid in radians.
void nvgSkewX(struct NVGcontext* ctx, float angle);
void nvgSkewX(NVGcontext* ctx, float angle);


// Skews the current coordinate system along Y axis. Angle is specifid in radians. // Skews the current coordinate system along Y axis. Angle is specifid in radians.
void nvgSkewY(struct NVGcontext* ctx, float angle);
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. // Stores the top part (a-f) of the current transformation matrix in to the specified buffer.
// [a c e] // [a c e]
// [b d f] // [b d f]
// [0 0 1] // [0 0 1]
// There should be space for 6 floats in the return buffer for the values a-f. // There should be space for 6 floats in the return buffer for the values a-f.
void nvgCurrentTransform(struct NVGcontext* ctx, float* xform);
void nvgCurrentTransform(NVGcontext* ctx, float* xform);




// The following functions can be used to make calculations on 2x3 transformation matrices. // The following functions can be used to make calculations on 2x3 transformation matrices.
@@ -308,24 +312,24 @@ float nvgRadToDeg(float rad);


// 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 imageFlags);
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, int imageFlags, 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, int imageFlags, 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
@@ -336,29 +340,29 @@ 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,
struct NVGcolor icol, struct NVGcolor ocol);
NVGpaint nvgLinearGradient(NVGcontext* ctx, float sx, float sy, float ex, float ey,
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,
float r, float f, struct NVGcolor icol, struct NVGcolor ocol);
NVGpaint nvgBoxGradient(NVGcontext* ctx, float x, float y, float w, float h,
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,
struct NVGcolor icol, struct NVGcolor ocol);
NVGpaint nvgRadialGradient(NVGcontext* ctx, float cx, float cy, float inr, float outr,
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. // 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,
float angle, int image, int repeat, float alpha);
NVGpaint nvgImagePattern(NVGcontext* ctx, float ox, float oy, float ex, float ey,
float angle, int image, int repeat, float alpha);


// //
// Scissoring // Scissoring
@@ -368,10 +372,10 @@ struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, float ox, float oy, floa


// Sets the current // Sets the current
// 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);


// Reset and disables scissoring. // Reset and disables scissoring.
void nvgResetScissor(struct NVGcontext* ctx);
void nvgResetScissor(NVGcontext* ctx);


// //
// Paths // Paths
@@ -391,51 +395,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 cubic 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. // Adds quadratic bezier segment from last point in the path via a control point to the specified point.
void nvgQuadTo(struct NVGcontext* ctx, float cx, float cy, float x, float y);
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 circle arc shaped sub-path. The arc center is at cx,cy, the arc radius is r, // Creates new circle arc shaped sub-path. The arc center is at cx,cy, the arc radius is r,
// and the arc is drawn from angle a0 to a1, and swept in direction dir (NVG_CCW, or NVG_CW). // 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. // Angles are specified in radians.
void nvgArc(struct NVGcontext* ctx, float cx, float cy, float r, float a0, float a1, int dir);
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);




// //
@@ -473,67 +477,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
@@ -543,28 +547,30 @@ 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;
@@ -576,20 +582,21 @@ struct NVGparams {
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); void (*renderViewport)(void* uptr, int width, int height);
void (*renderFlush)(void* uptr); void (*renderFlush)(void* uptr);
void (*renderFill)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, const float* bounds, const struct NVGpath* paths, int npaths);
void (*renderStroke)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, float strokeWidth, const struct NVGpath* paths, int npaths);
void (*renderTriangles)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, const struct NVGvertex* verts, int nverts);
void (*renderFill)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths);
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. // Contructor and destructor, called by the render back-end.
struct NVGcontext* nvgCreateInternal(struct NVGparams* params);
void nvgDeleteInternal(struct NVGcontext* ctx);
NVGcontext* nvgCreateInternal(NVGparams* params);
void nvgDeleteInternal(NVGcontext* ctx);


struct NVGparams* nvgInternalParams(struct NVGcontext* ctx);
NVGparams* nvgInternalParams(NVGcontext* ctx);


// Debug function to dump cached path data. // Debug function to dump cached path data.
void nvgDebugDumpPathCache(struct NVGcontext* ctx);
void nvgDebugDumpPathCache(NVGcontext* ctx);


#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)


+ 124
- 118
src/nanovg_gl.h View File

@@ -52,29 +52,29 @@ extern "C" {


#if defined NANOVG_GL2 #if defined NANOVG_GL2


struct NVGcontext* nvgCreateGL2(int flags);
void nvgDeleteGL2(struct NVGcontext* ctx);
NVGcontext* nvgCreateGL2(int flags);
void nvgDeleteGL2(NVGcontext* ctx);


#endif #endif


#if defined NANOVG_GL3 #if defined NANOVG_GL3


struct NVGcontext* nvgCreateGL3(int flags);
void nvgDeleteGL3(struct NVGcontext* ctx);
NVGcontext* nvgCreateGL3(int flags);
void nvgDeleteGL3(NVGcontext* ctx);


#endif #endif


#if defined NANOVG_GLES2 #if defined NANOVG_GLES2


struct NVGcontext* nvgCreateGLES2(int flags);
void nvgDeleteGLES2(struct NVGcontext* ctx);
NVGcontext* nvgCreateGLES2(int flags);
void nvgDeleteGLES2(NVGcontext* ctx);


#endif #endif


#if defined NANOVG_GLES3 #if defined NANOVG_GLES3


struct NVGcontext* nvgCreateGLES3(int flags);
void nvgDeleteGLES3(struct NVGcontext* ctx);
NVGcontext* nvgCreateGLES3(int flags);
void nvgDeleteGLES3(NVGcontext* ctx);


#endif #endif


@@ -84,9 +84,9 @@ enum NVGLtextureflags {
NVGL_TEXTURE_PREMULTIPLIED = 0x04 NVGL_TEXTURE_PREMULTIPLIED = 0x04
}; };


int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
GLuint nvglImageHandle(struct NVGcontext* ctx, int image);
void nvglImageFlags(struct NVGcontext* ctx, int image, int flags);
int nvglCreateImageFromHandle(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
GLuint nvglImageHandle(NVGcontext* ctx, int image);
void nvglImageFlags(NVGcontext* ctx, int image, int flags);




#ifdef __cplusplus #ifdef __cplusplus
@@ -145,6 +145,7 @@ struct GLNVGshader {
GLuint vert; GLuint vert;
GLint loc[GLNVG_MAX_LOCS]; GLint loc[GLNVG_MAX_LOCS];
}; };
typedef struct GLNVGshader GLNVGshader;


struct GLNVGtexture { struct GLNVGtexture {
int id; int id;
@@ -153,6 +154,7 @@ struct GLNVGtexture {
int type; int type;
int flags; int flags;
}; };
typedef struct GLNVGtexture GLNVGtexture;


enum GLNVGcallType { enum GLNVGcallType {
GLNVG_NONE = 0, GLNVG_NONE = 0,
@@ -171,6 +173,7 @@ struct GLNVGcall {
int triangleCount; int triangleCount;
int uniformOffset; int uniformOffset;
}; };
typedef struct GLNVGcall GLNVGcall;


struct GLNVGpath { struct GLNVGpath {
int fillOffset; int fillOffset;
@@ -178,6 +181,7 @@ struct GLNVGpath {
int strokeOffset; int strokeOffset;
int strokeCount; int strokeCount;
}; };
typedef struct GLNVGpath GLNVGpath;


struct GLNVGfragUniforms { struct GLNVGfragUniforms {
float scissorMat[12]; // matrices are actually 3 vec4s float scissorMat[12]; // matrices are actually 3 vec4s
@@ -194,10 +198,11 @@ struct GLNVGfragUniforms {
int texType; int texType;
int type; int type;
}; };
typedef struct GLNVGfragUniforms GLNVGfragUniforms;


struct GLNVGcontext { struct GLNVGcontext {
struct GLNVGshader shader;
struct GLNVGtexture* textures;
GLNVGshader shader;
GLNVGtexture* textures;
float view[2]; float view[2];
int ntextures; int ntextures;
int ctextures; int ctextures;
@@ -213,10 +218,10 @@ struct GLNVGcontext {
int flags; int flags;


// Per frame buffers // Per frame buffers
struct GLNVGcall* calls;
GLNVGcall* calls;
int ccalls; int ccalls;
int ncalls; int ncalls;
struct GLNVGpath* paths;
GLNVGpath* paths;
int cpaths; int cpaths;
int npaths; int npaths;
struct NVGvertex* verts; struct NVGvertex* verts;
@@ -226,12 +231,13 @@ struct GLNVGcontext {
int cuniforms; int cuniforms;
int nuniforms; int nuniforms;
}; };
typedef struct GLNVGcontext GLNVGcontext;


static int glnvg__maxi(int a, int b) { return a > b ? a : b; } static int glnvg__maxi(int a, int b) { return a > b ? a : b; }


static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
{ {
struct GLNVGtexture* tex = NULL;
GLNVGtexture* tex = NULL;
int i; int i;


for (i = 0; i < gl->ntextures; i++) { for (i = 0; i < gl->ntextures; i++) {
@@ -242,9 +248,9 @@ static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
} }
if (tex == NULL) { if (tex == NULL) {
if (gl->ntextures+1 > gl->ctextures) { if (gl->ntextures+1 > gl->ctextures) {
struct GLNVGtexture* textures;
GLNVGtexture* textures;
int ctextures = glnvg__maxi(gl->ntextures+1, 4) + gl->ctextures/2; // 1.5x Overallocate int ctextures = glnvg__maxi(gl->ntextures+1, 4) + gl->ctextures/2; // 1.5x Overallocate
textures = (struct GLNVGtexture*)realloc(gl->textures, sizeof(struct GLNVGtexture)*ctextures);
textures = (GLNVGtexture*)realloc(gl->textures, sizeof(GLNVGtexture)*ctextures);
if (textures == NULL) return NULL; if (textures == NULL) return NULL;
gl->textures = textures; gl->textures = textures;
gl->ctextures = ctextures; gl->ctextures = ctextures;
@@ -258,7 +264,7 @@ static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
return tex; return tex;
} }


static struct GLNVGtexture* glnvg__findTexture(struct GLNVGcontext* gl, int id)
static GLNVGtexture* glnvg__findTexture(GLNVGcontext* gl, int id)
{ {
int i; int i;
for (i = 0; i < gl->ntextures; i++) for (i = 0; i < gl->ntextures; i++)
@@ -267,7 +273,7 @@ static struct GLNVGtexture* glnvg__findTexture(struct GLNVGcontext* gl, int id)
return NULL; return NULL;
} }


static int glnvg__deleteTexture(struct GLNVGcontext* gl, int id)
static int glnvg__deleteTexture(GLNVGcontext* gl, int id)
{ {
int i; int i;
for (i = 0; i < gl->ntextures; i++) { for (i = 0; i < gl->ntextures; i++) {
@@ -311,7 +317,7 @@ static int glnvg__checkError(const char* str)
return 0; return 0;
} }


static int glnvg__createShader(struct GLNVGshader* shader, const char* name, const char* header, const char* opts, const char* vshader, const char* fshader)
static int glnvg__createShader(GLNVGshader* shader, const char* name, const char* header, const char* opts, const char* vshader, const char* fshader)
{ {
GLint status; GLint status;
GLuint prog, vert, frag; GLuint prog, vert, frag;
@@ -363,7 +369,7 @@ static int glnvg__createShader(struct GLNVGshader* shader, const char* name, con
return 1; return 1;
} }


static void glnvg__deleteShader(struct GLNVGshader* shader)
static void glnvg__deleteShader(GLNVGshader* shader)
{ {
if (shader->prog != 0) if (shader->prog != 0)
glDeleteProgram(shader->prog); glDeleteProgram(shader->prog);
@@ -373,7 +379,7 @@ static void glnvg__deleteShader(struct GLNVGshader* shader)
glDeleteShader(shader->frag); glDeleteShader(shader->frag);
} }


static void glnvg__getUniforms(struct GLNVGshader* shader)
static void glnvg__getUniforms(GLNVGshader* shader)
{ {
shader->loc[GLNVG_LOC_VIEWSIZE] = glGetUniformLocation(shader->prog, "viewSize"); shader->loc[GLNVG_LOC_VIEWSIZE] = glGetUniformLocation(shader->prog, "viewSize");
shader->loc[GLNVG_LOC_TEX] = glGetUniformLocation(shader->prog, "tex"); shader->loc[GLNVG_LOC_TEX] = glGetUniformLocation(shader->prog, "tex");
@@ -399,7 +405,7 @@ static void glnvg__getUniforms(struct GLNVGshader* shader)


static int glnvg__renderCreate(void* uptr) static int glnvg__renderCreate(void* uptr)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
int align = 4; int align = 4;


// TODO: mediump float may not be enough for GLES2 in iOS. // TODO: mediump float may not be enough for GLES2 in iOS.
@@ -602,7 +608,7 @@ static int glnvg__renderCreate(void* uptr)
glGenBuffers(1, &gl->fragBuf); glGenBuffers(1, &gl->fragBuf);
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &align); glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &align);
#endif #endif
gl->fragSize = sizeof(struct GLNVGfragUniforms) + align - sizeof(struct GLNVGfragUniforms) % align;
gl->fragSize = sizeof(GLNVGfragUniforms) + align - sizeof(GLNVGfragUniforms) % align;


glnvg__checkError("create done"); glnvg__checkError("create done");


@@ -613,8 +619,8 @@ static int glnvg__renderCreate(void* uptr)


static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data) static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGtexture* tex = glnvg__allocTexture(gl);
GLNVGcontext* gl = (GLNVGcontext*)uptr;
GLNVGtexture* tex = glnvg__allocTexture(gl);


if (tex == NULL) return 0; if (tex == NULL) return 0;


@@ -682,14 +688,14 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im


static int glnvg__renderDeleteTexture(void* uptr, int image) static int glnvg__renderDeleteTexture(void* uptr, int image)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
return glnvg__deleteTexture(gl, image); return glnvg__deleteTexture(gl, image);
} }


static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data) static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
GLNVGcontext* gl = (GLNVGcontext*)uptr;
GLNVGtexture* tex = glnvg__findTexture(gl, image);


if (tex == NULL) return 0; if (tex == NULL) return 0;
glBindTexture(GL_TEXTURE_2D, tex->tex); glBindTexture(GL_TEXTURE_2D, tex->tex);
@@ -733,8 +739,8 @@ static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w


static int glnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h) static int glnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
GLNVGcontext* gl = (GLNVGcontext*)uptr;
GLNVGtexture* tex = glnvg__findTexture(gl, image);
if (tex == NULL) return 0; if (tex == NULL) return 0;
*w = tex->width; *w = tex->width;
*h = tex->height; *h = tex->height;
@@ -757,7 +763,7 @@ static void glnvg__xformToMat3x4(float* m3, float* t)
m3[11] = 0.0f; m3[11] = 0.0f;
} }


static struct NVGcolor glnvg__premulColor(struct NVGcolor c)
static NVGcolor glnvg__premulColor(NVGcolor c)
{ {
c.r *= c.a; c.r *= c.a;
c.g *= c.a; c.g *= c.a;
@@ -765,10 +771,10 @@ static struct NVGcolor glnvg__premulColor(struct NVGcolor c)
return c; return c;
} }


static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms* frag, struct NVGpaint* paint,
struct NVGscissor* scissor, float width, float fringe, float strokeThr)
static int glnvg__convertPaint(GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGpaint* paint,
NVGscissor* scissor, float width, float fringe, float strokeThr)
{ {
struct GLNVGtexture* tex = NULL;
GLNVGtexture* tex = NULL;
float invxform[6]; float invxform[6];


memset(frag, 0, sizeof(*frag)); memset(frag, 0, sizeof(*frag));
@@ -825,7 +831,7 @@ static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms
return 1; return 1;
} }


static struct GLNVGfragUniforms* nvg__fragUniformPtr(struct GLNVGcontext* gl, int i);
static GLNVGfragUniforms* nvg__fragUniformPtr(GLNVGcontext* gl, int i);


#if !NANOVG_GL_USE_UNIFORMBUFFER #if !NANOVG_GL_USE_UNIFORMBUFFER
static void glnvg__mat3(float* dst, float* src) static void glnvg__mat3(float* dst, float* src)
@@ -844,12 +850,12 @@ static void glnvg__mat3(float* dst, float* src)
} }
#endif #endif


static void glnvg__setUniforms(struct GLNVGcontext* gl, int uniformOffset, int image)
static void glnvg__setUniforms(GLNVGcontext* gl, int uniformOffset, int image)
{ {
#if NANOVG_GL_USE_UNIFORMBUFFER #if NANOVG_GL_USE_UNIFORMBUFFER
glBindBufferRange(GL_UNIFORM_BUFFER, GLNVG_FRAG_BINDING, gl->fragBuf, uniformOffset, sizeof(struct GLNVGfragUniforms));
glBindBufferRange(GL_UNIFORM_BUFFER, GLNVG_FRAG_BINDING, gl->fragBuf, uniformOffset, sizeof(GLNVGfragUniforms));
#else #else
struct GLNVGfragUniforms* frag = nvg__fragUniformPtr(gl, uniformOffset);
GLNVGfragUniforms* frag = nvg__fragUniformPtr(gl, uniformOffset);
float tmp[9]; // Maybe there's a way to get rid of this... float tmp[9]; // Maybe there's a way to get rid of this...
glnvg__mat3(tmp, frag->scissorMat); glnvg__mat3(tmp, frag->scissorMat);
glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, tmp); glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, tmp);
@@ -869,7 +875,7 @@ static void glnvg__setUniforms(struct GLNVGcontext* gl, int uniformOffset, int i
#endif #endif


if (image != 0) { if (image != 0) {
struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
GLNVGtexture* tex = glnvg__findTexture(gl, image);
glBindTexture(GL_TEXTURE_2D, tex != NULL ? tex->tex : 0); glBindTexture(GL_TEXTURE_2D, tex != NULL ? tex->tex : 0);
glnvg__checkError("tex paint tex"); glnvg__checkError("tex paint tex");
} else { } else {
@@ -879,14 +885,14 @@ static void glnvg__setUniforms(struct GLNVGcontext* gl, int uniformOffset, int i


static void glnvg__renderViewport(void* uptr, int width, int height) static void glnvg__renderViewport(void* uptr, int width, int height)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
gl->view[0] = (float)width; gl->view[0] = (float)width;
gl->view[1] = (float)height; gl->view[1] = (float)height;
} }


static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call)
static void glnvg__fill(GLNVGcontext* gl, GLNVGcall* call)
{ {
struct GLNVGpath* paths = &gl->paths[call->pathOffset];
GLNVGpath* paths = &gl->paths[call->pathOffset];
int i, npaths = call->pathCount; int i, npaths = call->pathCount;


// Draw shapes // Draw shapes
@@ -928,9 +934,9 @@ static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call)
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
} }


static void glnvg__convexFill(struct GLNVGcontext* gl, struct GLNVGcall* call)
static void glnvg__convexFill(GLNVGcontext* gl, GLNVGcall* call)
{ {
struct GLNVGpath* paths = &gl->paths[call->pathOffset];
GLNVGpath* paths = &gl->paths[call->pathOffset];
int i, npaths = call->pathCount; int i, npaths = call->pathCount;


glnvg__setUniforms(gl, call->uniformOffset, call->image); glnvg__setUniforms(gl, call->uniformOffset, call->image);
@@ -945,9 +951,9 @@ static void glnvg__convexFill(struct GLNVGcontext* gl, struct GLNVGcall* call)
} }
} }


static void glnvg__stroke(struct GLNVGcontext* gl, struct GLNVGcall* call)
static void glnvg__stroke(GLNVGcontext* gl, GLNVGcall* call)
{ {
struct GLNVGpath* paths = &gl->paths[call->pathOffset];
GLNVGpath* paths = &gl->paths[call->pathOffset];
int npaths = call->pathCount, i; int npaths = call->pathCount, i;


if (gl->flags & NVG_STENCIL_STROKES) { if (gl->flags & NVG_STENCIL_STROKES) {
@@ -992,7 +998,7 @@ static void glnvg__stroke(struct GLNVGcontext* gl, struct GLNVGcall* call)
} }
} }


static void glnvg__triangles(struct GLNVGcontext* gl, struct GLNVGcall* call)
static void glnvg__triangles(GLNVGcontext* gl, GLNVGcall* call)
{ {
glnvg__setUniforms(gl, call->uniformOffset, call->image); glnvg__setUniforms(gl, call->uniformOffset, call->image);
glnvg__checkError("triangles fill"); glnvg__checkError("triangles fill");
@@ -1002,7 +1008,7 @@ static void glnvg__triangles(struct GLNVGcontext* gl, struct GLNVGcall* call)


static void glnvg__renderFlush(void* uptr) static void glnvg__renderFlush(void* uptr)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
int i; int i;


if (gl->ncalls > 0) { if (gl->ncalls > 0) {
@@ -1034,11 +1040,11 @@ static void glnvg__renderFlush(void* uptr)
glBindVertexArray(gl->vertArr); glBindVertexArray(gl->vertArr);
#endif #endif
glBindBuffer(GL_ARRAY_BUFFER, gl->vertBuf); glBindBuffer(GL_ARRAY_BUFFER, gl->vertBuf);
glBufferData(GL_ARRAY_BUFFER, gl->nverts * sizeof(struct NVGvertex), gl->verts, GL_STREAM_DRAW);
glBufferData(GL_ARRAY_BUFFER, gl->nverts * sizeof(NVGvertex), gl->verts, GL_STREAM_DRAW);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(0 + 2*sizeof(float)));
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(NVGvertex), (const GLvoid*)(size_t)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(NVGvertex), (const GLvoid*)(0 + 2*sizeof(float)));


// Set view and texture just once per frame. // Set view and texture just once per frame.
glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0); glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0);
@@ -1049,7 +1055,7 @@ static void glnvg__renderFlush(void* uptr)
#endif #endif


for (i = 0; i < gl->ncalls; i++) { for (i = 0; i < gl->ncalls; i++) {
struct GLNVGcall* call = &gl->calls[i];
GLNVGcall* call = &gl->calls[i];
if (call->type == GLNVG_FILL) if (call->type == GLNVG_FILL)
glnvg__fill(gl, call); glnvg__fill(gl, call);
else if (call->type == GLNVG_CONVEXFILL) else if (call->type == GLNVG_CONVEXFILL)
@@ -1076,7 +1082,7 @@ static void glnvg__renderFlush(void* uptr)
gl->nuniforms = 0; gl->nuniforms = 0;
} }


static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths)
static int glnvg__maxVertCount(const NVGpath* paths, int npaths)
{ {
int i, count = 0; int i, count = 0;
for (i = 0; i < npaths; i++) { for (i = 0; i < npaths; i++) {
@@ -1086,29 +1092,29 @@ static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths)
return count; return count;
} }


static struct GLNVGcall* glnvg__allocCall(struct GLNVGcontext* gl)
static GLNVGcall* glnvg__allocCall(GLNVGcontext* gl)
{ {
struct GLNVGcall* ret = NULL;
GLNVGcall* ret = NULL;
if (gl->ncalls+1 > gl->ccalls) { if (gl->ncalls+1 > gl->ccalls) {
struct GLNVGcall* calls;
GLNVGcall* calls;
int ccalls = glnvg__maxi(gl->ncalls+1, 128) + gl->ccalls/2; // 1.5x Overallocate int ccalls = glnvg__maxi(gl->ncalls+1, 128) + gl->ccalls/2; // 1.5x Overallocate
calls = (struct GLNVGcall*)realloc(gl->calls, sizeof(struct GLNVGcall) * ccalls);
calls = (GLNVGcall*)realloc(gl->calls, sizeof(GLNVGcall) * ccalls);
if (calls == NULL) return NULL; if (calls == NULL) return NULL;
gl->calls = calls; gl->calls = calls;
gl->ccalls = ccalls; gl->ccalls = ccalls;
} }
ret = &gl->calls[gl->ncalls++]; ret = &gl->calls[gl->ncalls++];
memset(ret, 0, sizeof(struct GLNVGcall));
memset(ret, 0, sizeof(GLNVGcall));
return ret; return ret;
} }


static int glnvg__allocPaths(struct GLNVGcontext* gl, int n)
static int glnvg__allocPaths(GLNVGcontext* gl, int n)
{ {
int ret = 0; int ret = 0;
if (gl->npaths+n > gl->cpaths) { if (gl->npaths+n > gl->cpaths) {
struct GLNVGpath* paths;
GLNVGpath* paths;
int cpaths = glnvg__maxi(gl->npaths + n, 128) + gl->cpaths/2; // 1.5x Overallocate int cpaths = glnvg__maxi(gl->npaths + n, 128) + gl->cpaths/2; // 1.5x Overallocate
paths = (struct GLNVGpath*)realloc(gl->paths, sizeof(struct GLNVGpath) * cpaths);
paths = (GLNVGpath*)realloc(gl->paths, sizeof(GLNVGpath) * cpaths);
if (paths == NULL) return -1; if (paths == NULL) return -1;
gl->paths = paths; gl->paths = paths;
gl->cpaths = cpaths; gl->cpaths = cpaths;
@@ -1118,13 +1124,13 @@ static int glnvg__allocPaths(struct GLNVGcontext* gl, int n)
return ret; return ret;
} }


static int glnvg__allocVerts(struct GLNVGcontext* gl, int n)
static int glnvg__allocVerts(GLNVGcontext* gl, int n)
{ {
int ret = 0; int ret = 0;
if (gl->nverts+n > gl->cverts) { if (gl->nverts+n > gl->cverts) {
struct NVGvertex* verts;
NVGvertex* verts;
int cverts = glnvg__maxi(gl->nverts + n, 4096) + gl->cverts/2; // 1.5x Overallocate int cverts = glnvg__maxi(gl->nverts + n, 4096) + gl->cverts/2; // 1.5x Overallocate
verts = (struct NVGvertex*)realloc(gl->verts, sizeof(struct NVGvertex) * cverts);
verts = (NVGvertex*)realloc(gl->verts, sizeof(NVGvertex) * cverts);
if (verts == NULL) return -1; if (verts == NULL) return -1;
gl->verts = verts; gl->verts = verts;
gl->cverts = cverts; gl->cverts = cverts;
@@ -1134,7 +1140,7 @@ static int glnvg__allocVerts(struct GLNVGcontext* gl, int n)
return ret; return ret;
} }


static int glnvg__allocFragUniforms(struct GLNVGcontext* gl, int n)
static int glnvg__allocFragUniforms(GLNVGcontext* gl, int n)
{ {
int ret = 0, structSize = gl->fragSize; int ret = 0, structSize = gl->fragSize;
if (gl->nuniforms+n > gl->cuniforms) { if (gl->nuniforms+n > gl->cuniforms) {
@@ -1150,12 +1156,12 @@ static int glnvg__allocFragUniforms(struct GLNVGcontext* gl, int n)
return ret; return ret;
} }


static struct GLNVGfragUniforms* nvg__fragUniformPtr(struct GLNVGcontext* gl, int i)
static GLNVGfragUniforms* nvg__fragUniformPtr(GLNVGcontext* gl, int i)
{ {
return (struct GLNVGfragUniforms*)&gl->uniforms[i];
return (GLNVGfragUniforms*)&gl->uniforms[i];
} }


static void glnvg__vset(struct NVGvertex* vtx, float x, float y, float u, float v)
static void glnvg__vset(NVGvertex* vtx, float x, float y, float u, float v)
{ {
vtx->x = x; vtx->x = x;
vtx->y = y; vtx->y = y;
@@ -1163,13 +1169,13 @@ static void glnvg__vset(struct NVGvertex* vtx, float x, float y, float u, float
vtx->v = v; vtx->v = v;
} }


static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe,
const float* bounds, const struct NVGpath* paths, int npaths)
static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe,
const float* bounds, const NVGpath* paths, int npaths)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGcall* call = glnvg__allocCall(gl);
struct NVGvertex* quad;
struct GLNVGfragUniforms* frag;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
GLNVGcall* call = glnvg__allocCall(gl);
NVGvertex* quad;
GLNVGfragUniforms* frag;
int i, maxverts, offset; int i, maxverts, offset;


if (call == NULL) return; if (call == NULL) return;
@@ -1189,19 +1195,19 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis
if (offset == -1) goto error; if (offset == -1) goto error;


for (i = 0; i < npaths; i++) { for (i = 0; i < npaths; i++) {
struct GLNVGpath* copy = &gl->paths[call->pathOffset + i];
const struct NVGpath* path = &paths[i];
memset(copy, 0, sizeof(struct GLNVGpath));
GLNVGpath* copy = &gl->paths[call->pathOffset + i];
const NVGpath* path = &paths[i];
memset(copy, 0, sizeof(GLNVGpath));
if (path->nfill > 0) { if (path->nfill > 0) {
copy->fillOffset = offset; copy->fillOffset = offset;
copy->fillCount = path->nfill; copy->fillCount = path->nfill;
memcpy(&gl->verts[offset], path->fill, sizeof(struct NVGvertex) * path->nfill);
memcpy(&gl->verts[offset], path->fill, sizeof(NVGvertex) * path->nfill);
offset += path->nfill; offset += path->nfill;
} }
if (path->nstroke > 0) { if (path->nstroke > 0) {
copy->strokeOffset = offset; copy->strokeOffset = offset;
copy->strokeCount = path->nstroke; copy->strokeCount = path->nstroke;
memcpy(&gl->verts[offset], path->stroke, sizeof(struct NVGvertex) * path->nstroke);
memcpy(&gl->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke);
offset += path->nstroke; offset += path->nstroke;
} }
} }
@@ -1244,11 +1250,11 @@ error:
if (gl->ncalls > 0) gl->ncalls--; if (gl->ncalls > 0) gl->ncalls--;
} }


static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe,
float strokeWidth, const struct NVGpath* paths, int npaths)
static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe,
float strokeWidth, const NVGpath* paths, int npaths)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGcall* call = glnvg__allocCall(gl);
GLNVGcontext* gl = (GLNVGcontext*)uptr;
GLNVGcall* call = glnvg__allocCall(gl);
int i, maxverts, offset; int i, maxverts, offset;


if (call == NULL) return; if (call == NULL) return;
@@ -1265,13 +1271,13 @@ static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGsc
if (offset == -1) goto error; if (offset == -1) goto error;


for (i = 0; i < npaths; i++) { for (i = 0; i < npaths; i++) {
struct GLNVGpath* copy = &gl->paths[call->pathOffset + i];
const struct NVGpath* path = &paths[i];
memset(copy, 0, sizeof(struct GLNVGpath));
GLNVGpath* copy = &gl->paths[call->pathOffset + i];
const NVGpath* path = &paths[i];
memset(copy, 0, sizeof(GLNVGpath));
if (path->nstroke) { if (path->nstroke) {
copy->strokeOffset = offset; copy->strokeOffset = offset;
copy->strokeCount = path->nstroke; copy->strokeCount = path->nstroke;
memcpy(&gl->verts[offset], path->stroke, sizeof(struct NVGvertex) * path->nstroke);
memcpy(&gl->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke);
offset += path->nstroke; offset += path->nstroke;
} }
} }
@@ -1299,12 +1305,12 @@ error:
if (gl->ncalls > 0) gl->ncalls--; if (gl->ncalls > 0) gl->ncalls--;
} }


static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor,
const struct NVGvertex* verts, int nverts)
static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGscissor* scissor,
const NVGvertex* verts, int nverts)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
struct GLNVGcall* call = glnvg__allocCall(gl);
struct GLNVGfragUniforms* frag;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
GLNVGcall* call = glnvg__allocCall(gl);
GLNVGfragUniforms* frag;


if (call == NULL) return; if (call == NULL) return;


@@ -1316,7 +1322,7 @@ static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NV
if (call->triangleOffset == -1) goto error; if (call->triangleOffset == -1) goto error;
call->triangleCount = nverts; call->triangleCount = nverts;


memcpy(&gl->verts[call->triangleOffset], verts, sizeof(struct NVGvertex) * nverts);
memcpy(&gl->verts[call->triangleOffset], verts, sizeof(NVGvertex) * nverts);


// Fill shader // Fill shader
call->uniformOffset = glnvg__allocFragUniforms(gl, 1); call->uniformOffset = glnvg__allocFragUniforms(gl, 1);
@@ -1335,7 +1341,7 @@ error:


static void glnvg__renderDelete(void* uptr) static void glnvg__renderDelete(void* uptr)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
int i; int i;
if (gl == NULL) return; if (gl == NULL) return;


@@ -1368,20 +1374,20 @@ static void glnvg__renderDelete(void* uptr)




#if defined NANOVG_GL2 #if defined NANOVG_GL2
struct NVGcontext* nvgCreateGL2(int flags)
NVGcontext* nvgCreateGL2(int flags)
#elif defined NANOVG_GL3 #elif defined NANOVG_GL3
struct NVGcontext* nvgCreateGL3(int flags)
NVGcontext* nvgCreateGL3(int flags)
#elif defined NANOVG_GLES2 #elif defined NANOVG_GLES2
struct NVGcontext* nvgCreateGLES2(int flags)
NVGcontext* nvgCreateGLES2(int flags)
#elif defined NANOVG_GLES3 #elif defined NANOVG_GLES3
struct NVGcontext* nvgCreateGLES3(int flags)
NVGcontext* nvgCreateGLES3(int flags)
#endif #endif
{ {
struct NVGparams params;
struct NVGcontext* ctx = NULL;
struct GLNVGcontext* gl = (struct GLNVGcontext*)malloc(sizeof(struct GLNVGcontext));
NVGparams params;
NVGcontext* ctx = NULL;
GLNVGcontext* gl = (GLNVGcontext*)malloc(sizeof(GLNVGcontext));
if (gl == NULL) goto error; if (gl == NULL) goto error;
memset(gl, 0, sizeof(struct GLNVGcontext));
memset(gl, 0, sizeof(GLNVGcontext));


memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.renderCreate = glnvg__renderCreate; params.renderCreate = glnvg__renderCreate;
@@ -1412,22 +1418,22 @@ error:
} }


#if NANOVG_GL2 #if NANOVG_GL2
void nvgDeleteGL2(struct NVGcontext* ctx)
void nvgDeleteGL2(NVGcontext* ctx)
#elif NANOVG_GL3 #elif NANOVG_GL3
void nvgDeleteGL3(struct NVGcontext* ctx)
void nvgDeleteGL3(NVGcontext* ctx)
#elif NANOVG_GLES2 #elif NANOVG_GLES2
void nvgDeleteGLES2(struct NVGcontext* ctx)
void nvgDeleteGLES2(NVGcontext* ctx)
#elif NANOVG_GLES3 #elif NANOVG_GLES3
void nvgDeleteGLES3(struct NVGcontext* ctx)
void nvgDeleteGLES3(NVGcontext* ctx)
#endif #endif
{ {
nvgDeleteInternal(ctx); nvgDeleteInternal(ctx);
} }


int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int w, int h, int flags)
int nvglCreateImageFromHandle(NVGcontext* ctx, GLuint textureId, int w, int h, int flags)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
struct GLNVGtexture* tex = glnvg__allocTexture(gl);
GLNVGcontext* gl = (GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
GLNVGtexture* tex = glnvg__allocTexture(gl);


if (tex == NULL) return 0; if (tex == NULL) return 0;


@@ -1440,17 +1446,17 @@ int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int w, i
return tex->id; return tex->id;
} }


GLuint nvglImageHandle(struct NVGcontext* ctx, int image)
GLuint nvglImageHandle(NVGcontext* ctx, int image)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
GLNVGcontext* gl = (GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
GLNVGtexture* tex = glnvg__findTexture(gl, image);
return tex->tex; return tex->tex;
} }


void nvglImageFlags(struct NVGcontext* ctx, int image, int flags)
void nvglImageFlags(NVGcontext* ctx, int image, int flags)
{ {
struct GLNVGcontext* gl = (struct GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
GLNVGcontext* gl = (GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
GLNVGtexture* tex = glnvg__findTexture(gl, image);
tex->flags = flags; tex->flags = flags;
} }




+ 10
- 9
src/nanovg_gl_utils.h View File

@@ -19,16 +19,17 @@
#define NANOVG_GL_UTILS_H #define NANOVG_GL_UTILS_H


struct NVGLUframebuffer { struct NVGLUframebuffer {
struct NVGcontext* ctx;
NVGcontext* ctx;
GLuint fbo; GLuint fbo;
GLuint rbo; GLuint rbo;
GLuint texture; GLuint texture;
int image; int image;
}; };
typedef struct NVGLUframebuffer NVGLUframebuffer;


// Helper function to create GL frame buffer to render to. // Helper function to create GL frame buffer to render to.
struct NVGLUframebuffer* nvgluCreateFramebuffer(struct NVGcontext* ctx, int w, int h);
void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb);
NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h);
void nvgluDeleteFramebuffer(NVGcontext* ctx, NVGLUframebuffer* fb);


#endif // NANOVG_GL_UTILS_H #endif // NANOVG_GL_UTILS_H


@@ -45,13 +46,13 @@ void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb)
# endif # endif
#endif #endif


struct NVGLUframebuffer* nvgluCreateFramebuffer(struct NVGcontext* ctx, int w, int h)
NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h)
{ {
#ifdef NANOVG_FBO_VALID #ifdef NANOVG_FBO_VALID
struct NVGLUframebuffer* fb = NULL;
fb = (struct NVGLUframebuffer*)malloc(sizeof(struct NVGLUframebuffer));
NVGLUframebuffer* fb = NULL;
fb = (NVGLUframebuffer*)malloc(sizeof(NVGLUframebuffer));
if (fb == NULL) goto error; if (fb == NULL) goto error;
memset(fb, 0, sizeof(struct NVGLUframebuffer));
memset(fb, 0, sizeof(NVGLUframebuffer));


fb->image = nvgCreateImageRGBA(ctx, w, h, 0, NULL); fb->image = nvgCreateImageRGBA(ctx, w, h, 0, NULL);
fb->texture = nvglImageHandle(ctx, fb->image); fb->texture = nvglImageHandle(ctx, fb->image);
@@ -84,7 +85,7 @@ error:
#endif #endif
} }


void nvgluBindFramebuffer(struct NVGLUframebuffer* fb)
void nvgluBindFramebuffer(NVGLUframebuffer* fb)
{ {
#ifdef NANOVG_FBO_VALID #ifdef NANOVG_FBO_VALID
glBindFramebuffer(GL_FRAMEBUFFER, fb != NULL ? fb->fbo : 0); glBindFramebuffer(GL_FRAMEBUFFER, fb != NULL ? fb->fbo : 0);
@@ -93,7 +94,7 @@ void nvgluBindFramebuffer(struct NVGLUframebuffer* fb)
#endif #endif
} }


void nvgluDeleteFramebuffer(struct NVGcontext* ctx, struct NVGLUframebuffer* fb)
void nvgluDeleteFramebuffer(NVGcontext* ctx, NVGLUframebuffer* fb)
{ {
#ifdef NANOVG_FBO_VALID #ifdef NANOVG_FBO_VALID
if (fb == NULL) return; if (fb == NULL) return;


Loading…
Cancel
Save