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_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 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); }

// 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)
{
NVG_NOTUSED(times);
NVG_NOTUSED(maxTimes);
GLint available = 1;
int n = 0;
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 (*renderDelete)(void* uptr);
};
typedef struct FONSparams FONSparams;

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

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

typedef struct FONScontext FONScontext;

// 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.
void fonsGetAtlasSize(struct FONScontext* s, int* width, int* height);
void fonsGetAtlasSize(FONScontext* s, int* width, int* height);
// 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.
int fonsResetAtlas(struct FONScontext* stash, int width, int height);
int fonsResetAtlas(FONScontext* stash, int width, int height);

// 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
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
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
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
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
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
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
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
@@ -144,6 +149,7 @@ void fonsDrawDebug(struct FONScontext* s, float x, float y);
struct FONSttFontImpl {
FT_Face font;
};
typedef struct FONSttFontImpl FONSttFontImpl;

static FT_Library ftLibrary;

@@ -154,7 +160,7 @@ int fons__tt_init()
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;
FONS_NOTUSED(context);
@@ -164,24 +170,25 @@ int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font,
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;
*descent = font->font->descender;
*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);
}

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);
}

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_GlyphSlot ftGlyph;
@@ -202,7 +209,8 @@ int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size
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;
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_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning);
@@ -239,14 +247,15 @@ static void fons__tmpfree(void* ptr, void* up);
struct FONSttFontImpl {
stbtt_fontinfo font;
};
typedef struct FONSttFontImpl FONSttFontImpl;

int fons__tt_init(struct FONScontext *context)
int fons__tt_init(FONScontext *context)
{
FONS_NOTUSED(context);
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;
FONS_NOTUSED(dataSize);
@@ -256,22 +265,23 @@ int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font,
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);
}

float fons__tt_getPixelHeightScale(struct FONSttFontImpl *font, float size)
float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float 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);
}

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);
stbtt_GetGlyphHMetrics(&font->font, glyph, advance, lsb);
@@ -279,12 +289,13 @@ int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size
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);
}

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);
}
@@ -343,10 +354,11 @@ struct FONSglyph
short x0,y0,x1,y1;
short xadv,xoff,yoff;
};
typedef struct FONSglyph FONSglyph;

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

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

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

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

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

// 16-byte align the returned pointer
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

static void fons__deleteAtlas(struct FONSatlas* atlas)
static void fons__deleteAtlas(FONSatlas* atlas)
{
if (atlas == NULL) return;
if (atlas->nodes != NULL) free(atlas->nodes);
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.
atlas = (struct FONSatlas*)malloc(sizeof(struct FONSatlas));
atlas = (FONSatlas*)malloc(sizeof(FONSatlas));
if (atlas == NULL) goto error;
memset(atlas, 0, sizeof(struct FONSatlas));
memset(atlas, 0, sizeof(FONSatlas));

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

// 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;
memset(atlas->nodes, 0, sizeof(struct FONSatlasNode) * nnodes);
memset(atlas->nodes, 0, sizeof(FONSatlasNode) * nnodes);
atlas->nnodes = 0;
atlas->cnodes = nnodes;

@@ -509,13 +525,13 @@ error:
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;
// Insert node
if (atlas->nnodes+1 > atlas->cnodes) {
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)
return 0;
}
@@ -529,7 +545,7 @@ static int fons__atlasInsertNode(struct FONSatlas* atlas, int idx, int x, int y,
return 1;
}

static void fons__atlasRemoveNode(struct FONSatlas* atlas, int idx)
static void fons__atlasRemoveNode(FONSatlas* atlas, int idx)
{
int i;
if (atlas->nnodes == 0) return;
@@ -538,7 +554,7 @@ static void fons__atlasRemoveNode(struct FONSatlas* atlas, int idx)
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
if (w > atlas->width)
@@ -547,7 +563,7 @@ static void fons__atlasExpand(struct FONSatlas* atlas, int w, int 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->height = h;
@@ -560,7 +576,7 @@ static void fons__atlasReset(struct FONSatlas* atlas, int w, int h)
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;

@@ -597,7 +613,7 @@ static int fons__atlasAddSkylineLevel(struct FONSatlas* atlas, int idx, int x, i
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',
// 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;
}

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 bestx = -1, besty = -1, i;
@@ -650,7 +666,7 @@ static int fons__atlasAddRect(struct FONSatlas* atlas, int rw, int rh, int* rx,
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;
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);
}

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

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

stash->params = *params;

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

// 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;
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->nfonts = 0;

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

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

void fonsSetSize(struct FONScontext* stash, float size)
void fonsSetSize(FONScontext* stash, float 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;
}

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

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

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

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

void fonsPushState(struct FONScontext* stash)
void fonsPushState(FONScontext* stash)
{
if (stash->nstates >= FONS_MAX_STATES) {
if (stash->handleError)
@@ -772,11 +788,11 @@ void fonsPushState(struct FONScontext* stash)
return;
}
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++;
}

void fonsPopState(struct FONScontext* stash)
void fonsPopState(FONScontext* stash)
{
if (stash->nstates <= 1) {
if (stash->handleError)
@@ -786,9 +802,9 @@ void fonsPopState(struct FONScontext* stash)
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->color = 0xffffffff;
state->font = 0;
@@ -797,7 +813,7 @@ void fonsClearState(struct FONScontext* stash)
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->glyphs) free(font->glyphs);
@@ -805,20 +821,20 @@ static void fons__freeFont(struct FONSfont* 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) {
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)
return -1;
}
font = (struct FONSfont*)malloc(sizeof(struct FONSfont));
font = (FONSfont*)malloc(sizeof(FONSfont));
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;
font->cglyphs = FONS_INIT_GLYPHS;
font->nglyphs = 0;
@@ -832,7 +848,7 @@ error:
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;
int dataSize = 0;
@@ -858,10 +874,10 @@ error:
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;
struct FONSfont* font;
FONSfont* font;

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

int fonsGetFontByName(struct FONScontext* s, const char* name)
int fonsGetFontByName(FONScontext* s, const char* name)
{
int 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) {
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;
}
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;
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);
}

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;
float scale;
struct FONSglyph* glyph = NULL;
FONSglyph* glyph = NULL;
unsigned int h;
float size = isize/10.0f;
int pad, added;
@@ -1092,9 +1108,9 @@ static struct FONSglyph* fons__getGlyph(struct FONScontext* stash, struct FONSfo
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;

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

static void fons__flush(struct FONScontext* stash)
static void fons__flush(FONScontext* stash)
{
// Flush texture
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+1] = y;
@@ -1175,7 +1191,7 @@ static __inline void fons__vertex(struct FONScontext* stash, float x, float y, f
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 (align & FONS_ALIGN_TOP) {
@@ -1201,20 +1217,20 @@ static float fons__getVertAlign(struct FONScontext* stash, struct FONSfont* font
return 0.0;
}

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

if (stash == NULL) return x;
@@ -1265,10 +1281,10 @@ float fonsDrawText(struct FONScontext* stash,
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)
{
struct FONSstate* state = fons__getState(stash);
FONSstate* state = fons__getState(stash);
float width;

memset(iter, 0, sizeof(*iter));
@@ -1310,9 +1326,9 @@ int fonsTextIterInit(struct FONScontext* stash, struct FONStextIter* iter,
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;
iter->str = iter->next;

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

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

// Drawbug draw atlas
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)
fons__flush(stash);
@@ -1385,21 +1401,21 @@ void fonsDrawDebug(struct FONScontext* stash, float x, float y)
fons__flush(stash);
}

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

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

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

if (stash == NULL) return;
@@ -1483,10 +1499,10 @@ void fonsVertMetrics(struct FONScontext* stash,
*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;

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)
*width = stash->params.width;
@@ -1515,7 +1531,7 @@ const unsigned char* fonsGetTextureData(struct FONScontext* stash, int* width, i
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]) {
dirty[0] = stash->dirtyRect[0];
@@ -1532,7 +1548,7 @@ int fonsValidateTexture(struct FONScontext* stash, int* dirty)
return 0;
}

void fonsDeleteInternal(struct FONScontext* stash)
void fonsDeleteInternal(FONScontext* stash)
{
int i;
if (stash == NULL) return;
@@ -1550,21 +1566,21 @@ void fonsDeleteInternal(struct FONScontext* 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;
stash->handleError = callback;
stash->errorUptr = uptr;
}

void fonsGetAtlasSize(struct FONScontext* stash, int* width, int* height)
void fonsGetAtlasSize(FONScontext* stash, int* width, int* height)
{
if (stash == NULL) return;
*width = stash->params.width;
*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;
unsigned char* data = NULL;
@@ -1620,7 +1636,7 @@ int fonsExpandAtlas(struct FONScontext* stash, int width, int height)
return 1;
}

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

// Reset cached glyphs
for (i = 0; i < stash->nfonts; i++) {
struct FONSfont* font = stash->fonts[i];
FONSfont* font = stash->fonts[i];
font->nglyphs = 0;
for (j = 0; j < FONS_HASH_LUT_SIZE; j++)
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
#endif

struct NVGcontext;
typedef struct NVGcontext NVGcontext;

struct NVGcolor {
union {
@@ -40,17 +40,19 @@ struct NVGcolor {
};
};
};
typedef struct NVGcolor NVGcolor;

struct NVGpaint {
float xform[6];
float extent[2];
float radius;
float feather;
struct NVGcolor innerColor;
struct NVGcolor outerColor;
NVGcolor innerColor;
NVGcolor outerColor;
int image;
int repeat;
};
typedef struct NVGpaint NVGpaint;

enum NVGwinding {
NVG_CCW = 1, // Winding for solid shapes
@@ -93,6 +95,7 @@ struct NVGglyphPosition {
float x; // The x-coordinate of the logical glyph position.
float minx, maxx; // The bounds of the glyph shape.
};
typedef struct NVGglyphPosition NVGglyphPosition;

struct NVGtextRow {
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 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 {
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
// frame buffer size. In that case you would set windowWidth/Height to the window size
// 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.
void nvgEndFrame(struct NVGcontext* ctx);
void nvgEndFrame(NVGcontext* ctx);

//
// Color utils
@@ -125,35 +129,35 @@ void nvgEndFrame(struct NVGcontext* ctx);
// Colors in NanoVG are stored as unsigned ints in ABGR format.

// Returns a color value from red, green, blue values. Alpha will be set to 255 (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.
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.
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.
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.
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.
struct NVGcolor nvgTransRGBA(struct NVGcolor c0, unsigned char a);
NVGcolor nvgTransRGBA(NVGcolor c0, unsigned char a);

// 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.
// 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.
// 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
@@ -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.
// 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.
void nvgRestore(struct NVGcontext* ctx);
void nvgRestore(NVGcontext* ctx);

// 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
@@ -182,35 +186,35 @@ void nvgReset(struct NVGcontext* ctx);
// Current render style can be saved and restored using nvgSave() and nvgRestore().

// Sets current stroke style to a solid color.
void nvgStrokeColor(struct NVGcontext* ctx, 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.
void nvgStrokePaint(struct NVGcontext* ctx, struct NVGpaint paint);
void nvgStrokePaint(NVGcontext* ctx, NVGpaint paint);

// 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.
void nvgFillPaint(struct NVGcontext* ctx, struct NVGpaint paint);
void nvgFillPaint(NVGcontext* ctx, NVGpaint paint);

// Sets the miter limit of the stroke style.
// 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.
void nvgStrokeWidth(struct NVGcontext* ctx, float size);
void nvgStrokeWidth(NVGcontext* ctx, float size);

// Sets how the end of the line (cap) is drawn,
// 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.
// Can be one of NVG_MITER (default), NVG_ROUND, NVG_BEVEL.
void nvgLineJoin(struct NVGcontext* ctx, int join);
void nvgLineJoin(NVGcontext* ctx, int join);

// Sets the transparency applied to all rendered shapes.
// Alreade transparent paths will get proportionally more transparent as well.
void nvgGlobalAlpha(struct NVGcontext* ctx, float alpha);
void nvgGlobalAlpha(NVGcontext* ctx, float alpha);

//
// 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().

// Resets current transform to a identity matrix.
void nvgResetTransform(struct NVGcontext* ctx);
void nvgResetTransform(NVGcontext* ctx);

// Premultiplies current coordinate system by specified matrix.
// The parameters are interpreted as matrix as follows:
// [a c e]
// [b d f]
// [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.
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.
void nvgRotate(struct NVGcontext* ctx, float angle);
void nvgRotate(NVGcontext* ctx, float angle);

// Skews the current coordinate system along X axis. Angle is specifid in radians.
void nvgSkewX(struct NVGcontext* ctx, float angle);
void nvgSkewX(NVGcontext* ctx, float angle);

// 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.
void nvgScale(struct NVGcontext* ctx, float x, float y);
void nvgScale(NVGcontext* ctx, float x, float y);

// Stores the top part (a-f) of the current transformation matrix in to the specified buffer.
// [a c e]
// [b d f]
// [0 0 1]
// There should be space for 6 floats in the return buffer for the values a-f.
void nvgCurrentTransform(struct NVGcontext* ctx, float* xform);
void nvgCurrentTransform(NVGcontext* ctx, float* xform);


// 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.
// 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.
// 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.
// 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.
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.
void nvgImageSize(struct NVGcontext* ctx, int image, int* w, int* h);
void nvgImageSize(NVGcontext* ctx, int image, int* w, int* h);

// Deletes created image.
void nvgDeleteImage(struct NVGcontext* ctx, int image);
void nvgDeleteImage(NVGcontext* ctx, int image);

//
// 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
// of the linear gradient, icol specifies the start color and ocol the end color.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, float sx, float sy, float ex, float ey,
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
// 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
// the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, float x, float y, float w, float h,
float r, float f, 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
// the inner and outer radius of the gradient, icol specifies the start color and ocol the end color.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, float cx, float cy, float inr, float outr,
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,
// (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render,
// and repeat is combination of NVG_REPEATX and NVG_REPEATY which tells if the image should be repeated across x or y.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
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
@@ -368,10 +372,10 @@ struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, float ox, float oy, floa

// Sets the current
// 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.
void nvgResetScissor(struct NVGcontext* ctx);
void nvgResetScissor(NVGcontext* ctx);

//
// Paths
@@ -391,51 +395,51 @@ void nvgResetScissor(struct NVGcontext* ctx);
// The curve segments and sub-paths are transformed by the current transform.

// 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.
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.
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.
void nvgBezierTo(struct NVGcontext* ctx, float c1x, float c1y, float c2x, float c2y, float x, float y);
void nvgBezierTo(NVGcontext* ctx, float c1x, float c1y, float c2x, float c2y, float x, float y);

// Adds quadratic bezier segment from last point in the path via a control point to the specified point.
void nvgQuadTo(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.
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.
void nvgClosePath(struct NVGcontext* ctx);
void nvgClosePath(NVGcontext* ctx);

// 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,
// and the arc is drawn from angle a0 to a1, and swept in direction dir (NVG_CCW, or NVG_CW).
// Angles are specified in radians.
void nvgArc(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.
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.
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.
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.
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.
void nvgFill(struct NVGcontext* ctx);
void nvgFill(NVGcontext* ctx);

// 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.
// 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.
// 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.
int nvgFindFont(struct NVGcontext* ctx, const char* name);
int nvgFindFont(NVGcontext* ctx, const char* name);

// 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.
void nvgFontBlur(struct NVGcontext* ctx, float blur);
void nvgFontBlur(NVGcontext* ctx, float blur);

// 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.
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.
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.
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.
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.
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.
// 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).
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],
// 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).
// 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],
// 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.
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.
// 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.
// 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.
// 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).
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
@@ -543,28 +547,30 @@ enum NVGtexture {
NVG_TEXTURE_RGBA = 0x02,
};

struct NVGscissor
{
struct NVGscissor {
float xform[6];
float extent[2];
};
typedef struct NVGscissor NVGscissor;

struct NVGvertex {
float x,y,u,v;
};
typedef struct NVGvertex NVGvertex;

struct NVGpath {
int first;
int count;
unsigned char closed;
int nbevel;
struct NVGvertex* fill;
NVGvertex* fill;
int nfill;
struct NVGvertex* stroke;
NVGvertex* stroke;
int nstroke;
int winding;
int convex;
};
typedef struct NVGpath NVGpath;

struct NVGparams {
void* userPtr;
@@ -576,20 +582,21 @@ struct NVGparams {
int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h);
void (*renderViewport)(void* uptr, int width, int height);
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);
};
typedef struct NVGparams NVGparams;

// 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.
void nvgDebugDumpPathCache(struct NVGcontext* ctx);
void nvgDebugDumpPathCache(NVGcontext* ctx);

#ifdef _MSC_VER
#pragma warning(pop)


+ 124
- 118
src/nanovg_gl.h View File

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

#if defined NANOVG_GL2

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

#endif

#if defined NANOVG_GL3

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

#endif

#if defined NANOVG_GLES2

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

#endif

#if defined NANOVG_GLES3

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

#endif

@@ -84,9 +84,9 @@ enum NVGLtextureflags {
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
@@ -145,6 +145,7 @@ struct GLNVGshader {
GLuint vert;
GLint loc[GLNVG_MAX_LOCS];
};
typedef struct GLNVGshader GLNVGshader;

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

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

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

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

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

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

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;

for (i = 0; i < gl->ntextures; i++) {
@@ -242,9 +248,9 @@ static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
}
if (tex == NULL) {
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
textures = (struct GLNVGtexture*)realloc(gl->textures, sizeof(struct GLNVGtexture)*ctextures);
textures = (GLNVGtexture*)realloc(gl->textures, sizeof(GLNVGtexture)*ctextures);
if (textures == NULL) return NULL;
gl->textures = textures;
gl->ctextures = ctextures;
@@ -258,7 +264,7 @@ static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
return tex;
}

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

static int glnvg__deleteTexture(struct GLNVGcontext* gl, int id)
static int glnvg__deleteTexture(GLNVGcontext* gl, int id)
{
int i;
for (i = 0; i < gl->ntextures; i++) {
@@ -311,7 +317,7 @@ static int glnvg__checkError(const char* str)
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;
GLuint prog, vert, frag;
@@ -363,7 +369,7 @@ static int glnvg__createShader(struct GLNVGshader* shader, const char* name, con
return 1;
}

static void glnvg__deleteShader(struct GLNVGshader* shader)
static void glnvg__deleteShader(GLNVGshader* shader)
{
if (shader->prog != 0)
glDeleteProgram(shader->prog);
@@ -373,7 +379,7 @@ static void glnvg__deleteShader(struct GLNVGshader* shader)
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_TEX] = glGetUniformLocation(shader->prog, "tex");
@@ -399,7 +405,7 @@ static void glnvg__getUniforms(struct GLNVGshader* shader)

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

// 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);
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &align);
#endif
gl->fragSize = sizeof(struct GLNVGfragUniforms) + align - sizeof(struct GLNVGfragUniforms) % align;
gl->fragSize = sizeof(GLNVGfragUniforms) + align - sizeof(GLNVGfragUniforms) % align;

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)
{
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;

@@ -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)
{
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
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)
{
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;
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)
{
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;
*w = tex->width;
*h = tex->height;
@@ -757,7 +763,7 @@ static void glnvg__xformToMat3x4(float* m3, float* t)
m3[11] = 0.0f;
}

static struct NVGcolor glnvg__premulColor(struct NVGcolor c)
static NVGcolor glnvg__premulColor(NVGcolor c)
{
c.r *= c.a;
c.g *= c.a;
@@ -765,10 +771,10 @@ static struct NVGcolor glnvg__premulColor(struct NVGcolor 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];

memset(frag, 0, sizeof(*frag));
@@ -825,7 +831,7 @@ static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms
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
static void glnvg__mat3(float* dst, float* src)
@@ -844,12 +850,12 @@ static void glnvg__mat3(float* dst, float* src)
}
#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
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
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...
glnvg__mat3(tmp, frag->scissorMat);
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

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);
glnvg__checkError("tex paint tex");
} 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)
{
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
GLNVGcontext* gl = (GLNVGcontext*)uptr;
gl->view[0] = (float)width;
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;

// Draw shapes
@@ -928,9 +934,9 @@ static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call)
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;

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;

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__checkError("triangles fill");
@@ -1002,7 +1008,7 @@ static void glnvg__triangles(struct GLNVGcontext* gl, struct GLNVGcall* call)

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

if (gl->ncalls > 0) {
@@ -1034,11 +1040,11 @@ static void glnvg__renderFlush(void* uptr)
glBindVertexArray(gl->vertArr);
#endif
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(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.
glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0);
@@ -1049,7 +1055,7 @@ static void glnvg__renderFlush(void* uptr)
#endif

for (i = 0; i < gl->ncalls; i++) {
struct GLNVGcall* call = &gl->calls[i];
GLNVGcall* call = &gl->calls[i];
if (call->type == GLNVG_FILL)
glnvg__fill(gl, call);
else if (call->type == GLNVG_CONVEXFILL)
@@ -1076,7 +1082,7 @@ static void glnvg__renderFlush(void* uptr)
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;
for (i = 0; i < npaths; i++) {
@@ -1086,29 +1092,29 @@ static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths)
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) {
struct GLNVGcall* calls;
GLNVGcall* calls;
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;
gl->calls = calls;
gl->ccalls = ccalls;
}
ret = &gl->calls[gl->ncalls++];
memset(ret, 0, sizeof(struct GLNVGcall));
memset(ret, 0, sizeof(GLNVGcall));
return ret;
}

static int glnvg__allocPaths(struct GLNVGcontext* gl, int n)
static int glnvg__allocPaths(GLNVGcontext* gl, int n)
{
int ret = 0;
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
paths = (struct GLNVGpath*)realloc(gl->paths, sizeof(struct GLNVGpath) * cpaths);
paths = (GLNVGpath*)realloc(gl->paths, sizeof(GLNVGpath) * cpaths);
if (paths == NULL) return -1;
gl->paths = paths;
gl->cpaths = cpaths;
@@ -1118,13 +1124,13 @@ static int glnvg__allocPaths(struct GLNVGcontext* gl, int n)
return ret;
}

static int glnvg__allocVerts(struct GLNVGcontext* gl, int n)
static int glnvg__allocVerts(GLNVGcontext* gl, int n)
{
int ret = 0;
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
verts = (struct NVGvertex*)realloc(gl->verts, sizeof(struct NVGvertex) * cverts);
verts = (NVGvertex*)realloc(gl->verts, sizeof(NVGvertex) * cverts);
if (verts == NULL) return -1;
gl->verts = verts;
gl->cverts = cverts;
@@ -1134,7 +1140,7 @@ static int glnvg__allocVerts(struct GLNVGcontext* gl, int n)
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;
if (gl->nuniforms+n > gl->cuniforms) {
@@ -1150,12 +1156,12 @@ static int glnvg__allocFragUniforms(struct GLNVGcontext* gl, int n)
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->y = y;
@@ -1163,13 +1169,13 @@ static void glnvg__vset(struct NVGvertex* vtx, float x, float y, float u, float
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;

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

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) {
copy->fillOffset = offset;
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;
}
if (path->nstroke > 0) {
copy->strokeOffset = offset;
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;
}
}
@@ -1244,11 +1250,11 @@ error:
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;

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

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) {
copy->strokeOffset = offset;
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;
}
}
@@ -1299,12 +1305,12 @@ error:
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;

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

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

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

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

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


#if defined NANOVG_GL2
struct NVGcontext* nvgCreateGL2(int flags)
NVGcontext* nvgCreateGL2(int flags)
#elif defined NANOVG_GL3
struct NVGcontext* nvgCreateGL3(int flags)
NVGcontext* nvgCreateGL3(int flags)
#elif defined NANOVG_GLES2
struct NVGcontext* nvgCreateGLES2(int flags)
NVGcontext* nvgCreateGLES2(int flags)
#elif defined NANOVG_GLES3
struct NVGcontext* nvgCreateGLES3(int flags)
NVGcontext* nvgCreateGLES3(int flags)
#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;
memset(gl, 0, sizeof(struct GLNVGcontext));
memset(gl, 0, sizeof(GLNVGcontext));

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

#if NANOVG_GL2
void nvgDeleteGL2(struct NVGcontext* ctx)
void nvgDeleteGL2(NVGcontext* ctx)
#elif NANOVG_GL3
void nvgDeleteGL3(struct NVGcontext* ctx)
void nvgDeleteGL3(NVGcontext* ctx)
#elif NANOVG_GLES2
void nvgDeleteGLES2(struct NVGcontext* ctx)
void nvgDeleteGLES2(NVGcontext* ctx)
#elif NANOVG_GLES3
void nvgDeleteGLES3(struct NVGcontext* ctx)
void nvgDeleteGLES3(NVGcontext* ctx)
#endif
{
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;

@@ -1440,17 +1446,17 @@ int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int w, i
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;
}

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;
}



+ 10
- 9
src/nanovg_gl_utils.h View File

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

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

// 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

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

struct NVGLUframebuffer* nvgluCreateFramebuffer(struct NVGcontext* ctx, int w, int h)
NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h)
{
#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;
memset(fb, 0, sizeof(struct NVGLUframebuffer));
memset(fb, 0, sizeof(NVGLUframebuffer));

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

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

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


Loading…
Cancel
Save