Browse Source

Update NanoVG and stb-image sources, bring all VCV goodies too

Signed-off-by: falkTX <falktx@falktx.com>
pull/338/head
falkTX 3 years ago
parent
commit
a1322bc0c5
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
5 changed files with 944 additions and 1900 deletions
  1. +1
    -0
      dgl/NanoVG.hpp
  2. +140
    -102
      dgl/src/nanovg/nanovg.c
  3. +3
    -3
      dgl/src/nanovg/nanovg.h
  4. +75
    -28
      dgl/src/nanovg/nanovg_gl.h
  5. +725
    -1767
      dgl/src/nanovg/stb_image.h

+ 1
- 0
dgl/NanoVG.hpp View File

@@ -943,6 +943,7 @@ private:
inline void onDisplay() override
{
// NOTE maybe should use BaseWidget::getWindow().getScaleFactor() as 3rd arg ?
NanoVG::reset();
NanoVG::beginFrame(BaseWidget::getWidth(), BaseWidget::getHeight());
onNanoDisplay();
NanoVG::endFrame();


+ 140
- 102
dgl/src/nanovg/nanovg.c View File

@@ -24,8 +24,11 @@
#include "nanovg.h"
#define FONTSTASH_IMPLEMENTATION
#include "fontstash.h"

#ifndef NVG_NO_STB
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#endif

#ifdef _MSC_VER
#pragma warning(disable: 4100) // unreferenced formal parameter
@@ -109,6 +112,14 @@ struct NVGpathCache {
};
typedef struct NVGpathCache NVGpathCache;

struct NVGfontContext { // Fontstash context plus font images; shared between shared NanoVG contexts.
int refCount;
struct FONScontext* fs;
int fontImages[NVG_MAX_FONTIMAGES];
int fontImageIdx;
};
typedef struct NVGfontContext NVGfontContext;

struct NVGcontext {
NVGparams params;
float* commands;
@@ -122,9 +133,7 @@ struct NVGcontext {
float distTol;
float fringeWidth;
float devicePxRatio;
struct FONScontext* fs;
int fontImages[NVG_MAX_FONTIMAGES];
int fontImageIdx;
NVGfontContext* fontContext;
int drawCallCount;
int fillTriCount;
int strokeTriCount;
@@ -283,7 +292,7 @@ static NVGstate* nvg__getState(NVGcontext* ctx)
return &ctx->states[ctx->nstates-1];
}

NVGcontext* nvgCreateInternal(NVGparams* params)
NVGcontext* nvgCreateInternal(NVGparams* params, NVGcontext* other) // Share the fonts and images of 'other' if it's non-NULL.
{
FONSparams fontParams;
NVGcontext* ctx = (NVGcontext*)malloc(sizeof(NVGcontext));
@@ -292,8 +301,16 @@ NVGcontext* nvgCreateInternal(NVGparams* params)
memset(ctx, 0, sizeof(NVGcontext));

ctx->params = *params;
for (i = 0; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontImages[i] = 0;
if (other) {
ctx->fontContext = other->fontContext;
ctx->fontContext->refCount++;
} else {
ctx->fontContext = (NVGfontContext*)malloc(sizeof(NVGfontContext));
if (ctx->fontContext == NULL) goto error;
for (i = 0; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontContext->fontImages[i] = 0;
ctx->fontContext->refCount = 1;
}

ctx->commands = (float*)malloc(sizeof(float)*NVG_INIT_COMMANDS_SIZE);
if (!ctx->commands) goto error;
@@ -308,25 +325,27 @@ NVGcontext* nvgCreateInternal(NVGparams* params)

nvg__setDevicePixelRatio(ctx, 1.0f);

if (ctx->params.renderCreate(ctx->params.userPtr) == 0) goto error;
if (ctx->params.renderCreate(ctx->params.userPtr, other ? other->params.userPtr : NULL) == 0) goto error;

// Init font rendering
memset(&fontParams, 0, sizeof(fontParams));
fontParams.width = NVG_INIT_FONTIMAGE_SIZE;
fontParams.height = NVG_INIT_FONTIMAGE_SIZE;
fontParams.flags = FONS_ZERO_TOPLEFT;
fontParams.renderCreate = NULL;
fontParams.renderUpdate = NULL;
fontParams.renderDraw = NULL;
fontParams.renderDelete = NULL;
fontParams.userPtr = NULL;
ctx->fs = fonsCreateInternal(&fontParams);
if (ctx->fs == NULL) goto error;

// Create font texture
ctx->fontImages[0] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, 0, NULL);
if (ctx->fontImages[0] == 0) goto error;
ctx->fontImageIdx = 0;
if (!other) {
memset(&fontParams, 0, sizeof(fontParams));
fontParams.width = NVG_INIT_FONTIMAGE_SIZE;
fontParams.height = NVG_INIT_FONTIMAGE_SIZE;
fontParams.flags = FONS_ZERO_TOPLEFT;
fontParams.renderCreate = NULL;
fontParams.renderUpdate = NULL;
fontParams.renderDraw = NULL;
fontParams.renderDelete = NULL;
fontParams.userPtr = NULL;
ctx->fontContext->fs = fonsCreateInternal(&fontParams);
if (ctx->fontContext->fs == NULL) goto error;

// Create font texture
ctx->fontContext->fontImages[0] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, 0, NULL);
if (ctx->fontContext->fontImages[0] == 0) goto error;
ctx->fontContext->fontImageIdx = 0;
}

return ctx;

@@ -347,14 +366,18 @@ void nvgDeleteInternal(NVGcontext* ctx)
if (ctx->commands != NULL) free(ctx->commands);
if (ctx->cache != NULL) nvg__deletePathCache(ctx->cache);

if (ctx->fs)
fonsDeleteInternal(ctx->fs);
if (ctx->fontContext != NULL && --ctx->fontContext->refCount == 0) {
if (ctx->fontContext->fs)
fonsDeleteInternal(ctx->fontContext->fs);

for (i = 0; i < NVG_MAX_FONTIMAGES; i++) {
if (ctx->fontImages[i] != 0) {
nvgDeleteImage(ctx, ctx->fontImages[i]);
ctx->fontImages[i] = 0;
for (i = 0; i < NVG_MAX_FONTIMAGES; i++) {
if (ctx->fontContext->fontImages[i] != 0) {
nvgDeleteImage(ctx, ctx->fontContext->fontImages[i]);
ctx->fontContext->fontImages[i] = 0;
}
}

free(ctx->fontContext);
}

if (ctx->params.renderDelete != NULL)
@@ -391,30 +414,30 @@ void nvgCancelFrame(NVGcontext* ctx)
void nvgEndFrame(NVGcontext* ctx)
{
ctx->params.renderFlush(ctx->params.userPtr);
if (ctx->fontImageIdx != 0) {
int fontImage = ctx->fontImages[ctx->fontImageIdx];
if (ctx->fontContext->fontImageIdx != 0) {
int fontImage = ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx];
int i, j, iw, ih;
// delete images that smaller than current one
if (fontImage == 0)
return;
nvgImageSize(ctx, fontImage, &iw, &ih);
for (i = j = 0; i < ctx->fontImageIdx; i++) {
if (ctx->fontImages[i] != 0) {
for (i = j = 0; i < ctx->fontContext->fontImageIdx; i++) {
if (ctx->fontContext->fontImages[i] != 0) {
int nw, nh;
nvgImageSize(ctx, ctx->fontImages[i], &nw, &nh);
nvgImageSize(ctx, ctx->fontContext->fontImages[i], &nw, &nh);
if (nw < iw || nh < ih)
nvgDeleteImage(ctx, ctx->fontImages[i]);
nvgDeleteImage(ctx, ctx->fontContext->fontImages[i]);
else
ctx->fontImages[j++] = ctx->fontImages[i];
ctx->fontContext->fontImages[j++] = ctx->fontContext->fontImages[i];
}
}
// make current font image to first
ctx->fontImages[j++] = ctx->fontImages[0];
ctx->fontImages[0] = fontImage;
ctx->fontImageIdx = 0;
ctx->fontContext->fontImages[j++] = ctx->fontContext->fontImages[0];
ctx->fontContext->fontImages[0] = fontImage;
ctx->fontContext->fontImageIdx = 0;
// clear all images after j
for (i = j; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontImages[i] = 0;
ctx->fontContext->fontImages[i] = 0;
}
}

@@ -814,6 +837,7 @@ void nvgFillPaint(NVGcontext* ctx, NVGpaint paint)
nvgTransformMultiply(state->fill.xform, state->xform);
}

#ifndef NVG_NO_STB
int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags)
{
int w, h, n, image;
@@ -842,6 +866,7 @@ int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int
stbi_image_free(img);
return image;
}
#endif

int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data)
{
@@ -2324,35 +2349,35 @@ void nvgStroke(NVGcontext* ctx)
// Add fonts
int nvgCreateFont(NVGcontext* ctx, const char* name, const char* filename)
{
return fonsAddFont(ctx->fs, name, filename, 0);
return fonsAddFont(ctx->fontContext->fs, name, filename, 0);
}

int nvgCreateFontAtIndex(NVGcontext* ctx, const char* name, const char* filename, const int fontIndex)
{
return fonsAddFont(ctx->fs, name, filename, fontIndex);
return fonsAddFont(ctx->fontContext->fs, name, filename, fontIndex);
}

int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData)
{
return fonsAddFontMem(ctx->fs, name, data, ndata, freeData, 0);
return fonsAddFontMem(ctx->fontContext->fs, name, data, ndata, freeData, 0);
}

int nvgCreateFontMemAtIndex(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData, const int fontIndex)
{
return fonsAddFontMem(ctx->fs, name, data, ndata, freeData, fontIndex);
return fonsAddFontMem(ctx->fontContext->fs, name, data, ndata, freeData, fontIndex);
}

int nvgFindFont(NVGcontext* ctx, const char* name)
{
if (name == NULL) return -1;
return fonsGetFontByName(ctx->fs, name);
return fonsGetFontByName(ctx->fontContext->fs, name);
}


int nvgAddFallbackFontId(NVGcontext* ctx, int baseFont, int fallbackFont)
{
if(baseFont == -1 || fallbackFont == -1) return 0;
return fonsAddFallbackFont(ctx->fs, baseFont, fallbackFont);
return fonsAddFallbackFont(ctx->fontContext->fs, baseFont, fallbackFont);
}

int nvgAddFallbackFont(NVGcontext* ctx, const char* baseFont, const char* fallbackFont)
@@ -2362,7 +2387,7 @@ int nvgAddFallbackFont(NVGcontext* ctx, const char* baseFont, const char* fallba

void nvgResetFallbackFontsId(NVGcontext* ctx, int baseFont)
{
fonsResetFallbackFont(ctx->fs, baseFont);
fonsResetFallbackFont(ctx->fontContext->fs, baseFont);
}

void nvgResetFallbackFonts(NVGcontext* ctx, const char* baseFont)
@@ -2410,7 +2435,7 @@ void nvgFontFaceId(NVGcontext* ctx, int font)
void nvgFontFace(NVGcontext* ctx, const char* font)
{
NVGstate* state = nvg__getState(ctx);
state->fontId = fonsGetFontByName(ctx->fs, font);
state->fontId = fonsGetFontByName(ctx->fontContext->fs, font);
}

static float nvg__quantize(float a, float d)
@@ -2427,12 +2452,12 @@ static void nvg__flushTextTexture(NVGcontext* ctx)
{
int dirty[4];

if (fonsValidateTexture(ctx->fs, dirty)) {
int fontImage = ctx->fontImages[ctx->fontImageIdx];
if (fonsValidateTexture(ctx->fontContext->fs, dirty)) {
int fontImage = ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx];
// Update texture
if (fontImage != 0) {
int iw, ih;
const unsigned char* data = fonsGetTextureData(ctx->fs, &iw, &ih);
const unsigned char* data = fonsGetTextureData(ctx->fontContext->fs, &iw, &ih);
int x = dirty[0];
int y = dirty[1];
int w = dirty[2] - dirty[0];
@@ -2446,23 +2471,23 @@ static int nvg__allocTextAtlas(NVGcontext* ctx)
{
int iw, ih;
nvg__flushTextTexture(ctx);
if (ctx->fontImageIdx >= NVG_MAX_FONTIMAGES-1)
if (ctx->fontContext->fontImageIdx >= NVG_MAX_FONTIMAGES-1)
return 0;
// if next fontImage already have a texture
if (ctx->fontImages[ctx->fontImageIdx+1] != 0)
nvgImageSize(ctx, ctx->fontImages[ctx->fontImageIdx+1], &iw, &ih);
if (ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx+1] != 0)
nvgImageSize(ctx, ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx+1], &iw, &ih);
else { // calculate the new font image size and create it.
nvgImageSize(ctx, ctx->fontImages[ctx->fontImageIdx], &iw, &ih);
nvgImageSize(ctx, ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx], &iw, &ih);
if (iw > ih)
ih *= 2;
else
iw *= 2;
if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE)
iw = ih = NVG_MAX_FONTIMAGE_SIZE;
ctx->fontImages[ctx->fontImageIdx+1] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, iw, ih, 0, NULL);
ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx+1] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, iw, ih, 0, NULL);
}
++ctx->fontImageIdx;
fonsResetAtlas(ctx->fs, iw, ih);
++ctx->fontContext->fontImageIdx;
fonsResetAtlas(ctx->fontContext->fs, iw, ih);
return 1;
}

@@ -2473,7 +2498,7 @@ static void nvg__renderText(NVGcontext* ctx, NVGvertex* verts, int nverts)
NVGpaint paint = state->fill;

// Render triangles.
paint.image = ctx->fontImages[ctx->fontImageIdx];
paint.image = ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx];

// Apply global tint
for (i = 0; i < 4; i++) {
@@ -2487,6 +2512,12 @@ static void nvg__renderText(NVGcontext* ctx, NVGvertex* verts, int nverts)
ctx->textTriCount += nverts/3;
}

static int nvg__isTransformFlipped(const float *xform)
{
float det = xform[0] * xform[3] - xform[2] * xform[1];
return( det < 0);
}

float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char* end)
{
NVGstate* state = nvg__getState(ctx);
@@ -2497,25 +2528,26 @@ float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char*
float invscale = 1.0f / scale;
int cverts = 0;
int nverts = 0;
int isFlipped = nvg__isTransformFlipped(state->xform);

if (end == NULL)
end = string + strlen(string);

if (state->fontId == FONS_INVALID) return x;

fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);

cverts = nvg__maxi(2, (int)(end - string)) * 6; // conservative estimate.
verts = nvg__allocTempVerts(ctx, cverts);
if (verts == NULL) return x;

fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_REQUIRED);
fonsTextIterInit(ctx->fontContext->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_REQUIRED);
prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) {
while (fonsTextIterNext(ctx->fontContext->fs, &iter, &q)) {
float c[4*2];
if (iter.prevGlyphIndex == -1) { // can not retrieve glyph?
if (nverts != 0) {
@@ -2525,11 +2557,17 @@ float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char*
if (!nvg__allocTextAtlas(ctx))
break; // no memory :(
iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
fonsTextIterNext(ctx->fontContext->fs, &iter, &q); // try again
if (iter.prevGlyphIndex == -1) // still can not find glyph?
break;
}
prevIter = iter;
if(isFlipped) {
float tmp;

tmp = q.y0; q.y0 = q.y1; q.y1 = tmp;
tmp = q.t0; q.t0 = q.t1; q.t1 = tmp;
}
// Transform corners.
nvgTransformPoint(&c[0],&c[1], state->xform, q.x0*invscale, q.y0*invscale);
nvgTransformPoint(&c[2],&c[3], state->xform, q.x1*invscale, q.y0*invscale);
@@ -2604,18 +2642,18 @@ int nvgTextGlyphPositions(NVGcontext* ctx, float x, float y, const char* string,
if (string == end)
return 0;

fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);

fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
fonsTextIterInit(ctx->fontContext->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) {
while (fonsTextIterNext(ctx->fontContext->fs, &iter, &q)) {
if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph?
iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
fonsTextIterNext(ctx->fontContext->fs, &iter, &q); // try again
}
prevIter = iter;
positions[npos].str = iter.str;
@@ -2668,20 +2706,20 @@ int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, floa

if (string == end) return 0;

fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);

breakRowWidth *= scale;

fonsTextIterInit(ctx->fs, &iter, 0, 0, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
fonsTextIterInit(ctx->fontContext->fs, &iter, 0, 0, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) {
while (fonsTextIterNext(ctx->fontContext->fs, &iter, &q)) {
if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph?
iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
fonsTextIterNext(ctx->fontContext->fs, &iter, &q); // try again
}
prevIter = iter;
switch (iter.codepoint) {
@@ -2852,16 +2890,16 @@ float nvgTextBounds(NVGcontext* ctx, float x, float y, const char* string, const

if (state->fontId == FONS_INVALID) return 0;

fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);

width = fonsTextBounds(ctx->fs, x*scale, y*scale, string, end, bounds);
width = fonsTextBounds(ctx->fontContext->fs, x*scale, y*scale, string, end, bounds);
if (bounds != NULL) {
// Use line bounds for height.
fonsLineBounds(ctx->fs, y*scale, &bounds[1], &bounds[3]);
fonsLineBounds(ctx->fontContext->fs, y*scale, &bounds[1], &bounds[3]);
bounds[0] *= invscale;
bounds[1] *= invscale;
bounds[2] *= invscale;
@@ -2896,12 +2934,12 @@ void nvgTextBoxBounds(NVGcontext* ctx, float x, float y, float breakRowWidth, co
minx = maxx = x;
miny = maxy = y;

fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsLineBounds(ctx->fs, 0, &rminy, &rmaxy);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);
fonsLineBounds(ctx->fontContext->fs, 0, &rminy, &rmaxy);
rminy *= invscale;
rmaxy *= invscale;

@@ -2947,13 +2985,13 @@ void nvgTextMetrics(NVGcontext* ctx, float* ascender, float* descender, float* l

if (state->fontId == FONS_INVALID) return;

fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);

fonsVertMetrics(ctx->fs, ascender, descender, lineh);
fonsVertMetrics(ctx->fontContext->fs, ascender, descender, lineh);
if (ascender != NULL)
*ascender *= invscale;
if (descender != NULL)


+ 3
- 3
dgl/src/nanovg/nanovg.h View File

@@ -430,7 +430,7 @@ NVGpaint nvgBoxGradient(NVGcontext* ctx, float x, float y, float w, float h,
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 pattern. 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.
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
NVGpaint nvgImagePattern(NVGcontext* ctx, float ox, float oy, float ex, float ey,
@@ -671,7 +671,7 @@ typedef struct NVGpath NVGpath;
struct NVGparams {
void* userPtr;
int edgeAntiAlias;
int (*renderCreate)(void* uptr);
int (*renderCreate)(void* uptr, void* otherUptr);
int (*renderCreateTexture)(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data);
int (*renderDeleteTexture)(void* uptr, int image);
int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data);
@@ -687,7 +687,7 @@ struct NVGparams {
typedef struct NVGparams NVGparams;

// Constructor and destructor, called by the render back-end.
NVGcontext* nvgCreateInternal(NVGparams* params);
NVGcontext* nvgCreateInternal(NVGparams* params, NVGcontext* other);
void nvgDeleteInternal(NVGcontext* ctx);

NVGparams* nvgInternalParams(NVGcontext* ctx);


+ 75
- 28
dgl/src/nanovg/nanovg_gl.h View File

@@ -40,9 +40,7 @@ enum NVGcreateFlags {
#elif defined NANOVG_GL3_IMPLEMENTATION
# define NANOVG_GL3 1
# define NANOVG_GL_IMPLEMENTATION 1
# ifndef __APPLE__
# define NANOVG_GL_USE_UNIFORMBUFFER 1
# endif
# define NANOVG_GL_USE_UNIFORMBUFFER 1
#elif defined NANOVG_GLES2_IMPLEMENTATION
# define NANOVG_GLES2 1
# define NANOVG_GL_IMPLEMENTATION 1
@@ -59,6 +57,7 @@ enum NVGcreateFlags {
#if defined NANOVG_GL2

NVGcontext* nvgCreateGL2(int flags);
NVGcontext* nvgCreateSharedGL2(NVGcontext* other, int flags);
void nvgDeleteGL2(NVGcontext* ctx);

int nvglCreateImageFromHandleGL2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -69,6 +68,7 @@ GLuint nvglImageHandleGL2(NVGcontext* ctx, int image);
#if defined NANOVG_GL3

NVGcontext* nvgCreateGL3(int flags);
NVGcontext* nvgCreateSharedGL3(NVGcontext* other, int flags);
void nvgDeleteGL3(NVGcontext* ctx);

int nvglCreateImageFromHandleGL3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -79,6 +79,7 @@ GLuint nvglImageHandleGL3(NVGcontext* ctx, int image);
#if defined NANOVG_GLES2

NVGcontext* nvgCreateGLES2(int flags);
NVGcontext* nvgCreateSharedGLES2(NVGcontext* other, int flags);
void nvgDeleteGLES2(NVGcontext* ctx);

int nvglCreateImageFromHandleGLES2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -89,6 +90,7 @@ GLuint nvglImageHandleGLES2(NVGcontext* ctx, int image);
#if defined NANOVG_GLES3

NVGcontext* nvgCreateGLES3(int flags);
NVGcontext* nvgCreateSharedGLES3(NVGcontext* other, int flags);
void nvgDeleteGLES3(NVGcontext* ctx);

int nvglCreateImageFromHandleGLES3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -230,9 +232,18 @@ struct GLNVGfragUniforms {
};
typedef struct GLNVGfragUniforms GLNVGfragUniforms;

struct GLNVGtextureContext { // Textures; shared between shared NanoVG contexts.
int refCount;
GLNVGtexture* textures;
int ntextures;
int ctextures;
int textureId;
};
typedef struct GLNVGtextureContext GLNVGtextureContext;

struct GLNVGcontext {
GLNVGshader shader;
GLNVGtexture* textures;
GLNVGtextureContext* textureContext;
float view[2];
int ntextures;
int ctextures;
@@ -352,26 +363,26 @@ static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
GLNVGtexture* tex = NULL;
int i;

for (i = 0; i < gl->ntextures; i++) {
if (gl->textures[i].id == 0) {
tex = &gl->textures[i];
for (i = 0; i < gl->textureContext->ntextures; i++) {
if (gl->textureContext->textures[i].id == 0) {
tex = &gl->textureContext->textures[i];
break;
}
}
if (tex == NULL) {
if (gl->ntextures+1 > gl->ctextures) {
if (gl->textureContext->ntextures+1 > gl->textureContext->ctextures) {
GLNVGtexture* textures;
int ctextures = glnvg__maxi(gl->ntextures+1, 4) + gl->ctextures/2; // 1.5x Overallocate
textures = (GLNVGtexture*)realloc(gl->textures, sizeof(GLNVGtexture)*ctextures);
int ctextures = glnvg__maxi(gl->textureContext->ntextures+1, 4) + gl->textureContext->ctextures/2; // 1.5x Overallocate
textures = (GLNVGtexture*)realloc(gl->textureContext->textures, sizeof(GLNVGtexture)*ctextures);
if (textures == NULL) return NULL;
gl->textures = textures;
gl->ctextures = ctextures;
gl->textureContext->textures = textures;
gl->textureContext->ctextures = ctextures;
}
tex = &gl->textures[gl->ntextures++];
tex = &gl->textureContext->textures[gl->textureContext->ntextures++];
}

memset(tex, 0, sizeof(*tex));
tex->id = ++gl->textureId;
tex->id = ++gl->textureContext->textureId;

return tex;
}
@@ -379,20 +390,20 @@ static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
static GLNVGtexture* glnvg__findTexture(GLNVGcontext* gl, int id)
{
int i;
for (i = 0; i < gl->ntextures; i++)
if (gl->textures[i].id == id)
return &gl->textures[i];
for (i = 0; i < gl->textureContext->ntextures; i++)
if (gl->textureContext->textures[i].id == id)
return &gl->textureContext->textures[i];
return NULL;
}

static int glnvg__deleteTexture(GLNVGcontext* gl, int id)
{
int i;
for (i = 0; i < gl->ntextures; i++) {
if (gl->textures[i].id == id) {
if (gl->textures[i].tex != 0 && (gl->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textures[i].tex);
memset(&gl->textures[i], 0, sizeof(gl->textures[i]));
for (i = 0; i < gl->textureContext->ntextures; i++) {
if (gl->textureContext->textures[i].id == id) {
if (gl->textureContext->textures[i].tex != 0 && (gl->textureContext->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textureContext->textures[i].tex);
memset(&gl->textureContext->textures[i], 0, sizeof(gl->textureContext->textures[i]));
return 1;
}
}
@@ -506,9 +517,20 @@ static void glnvg__getUniforms(GLNVGshader* shader)

static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data);

static int glnvg__renderCreate(void* uptr)
static int glnvg__renderCreate(void* uptr, void* otherUptr) // Share the textures of GLNVGcontext 'otherUptr' if it's non-NULL.
{
GLNVGcontext* gl = (GLNVGcontext*)uptr;

if (otherUptr) {
GLNVGcontext* other = (GLNVGcontext*)otherUptr;
gl->textureContext = other->textureContext;
gl->textureContext->refCount++;
} else {
gl->textureContext = (GLNVGtextureContext*)malloc(sizeof(GLNVGtextureContext));
memset(gl->textureContext, 0, sizeof(GLNVGtextureContext));
gl->textureContext->refCount = 1;
}

int align = 4;

// TODO: mediump float may not be enough for GLES2 in iOS.
@@ -1605,11 +1627,14 @@ static void glnvg__renderDelete(void* uptr)
if (gl->vertBuf != 0)
glDeleteBuffers(1, &gl->vertBuf);

for (i = 0; i < gl->ntextures; i++) {
if (gl->textures[i].tex != 0 && (gl->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textures[i].tex);
if (gl->textureContext != NULL && --gl->textureContext->refCount == 0) {
for (i = 0; i < gl->textureContext->ntextures; i++) {
if (gl->textureContext->textures[i].tex != 0 && (gl->textureContext->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textureContext->textures[i].tex);
}
free(gl->textureContext->textures);
free(gl->textureContext);
}
free(gl->textures);

free(gl->paths);
free(gl->verts);
@@ -1629,6 +1654,28 @@ NVGcontext* nvgCreateGLES2(int flags)
#elif defined NANOVG_GLES3
NVGcontext* nvgCreateGLES3(int flags)
#endif
{
#if defined NANOVG_GL2
return nvgCreateSharedGL2(NULL, flags);
#elif defined NANOVG_GL3
return nvgCreateSharedGL3(NULL, flags);
#elif defined NANOVG_GLES2
return nvgCreateSharedGLES2(NULL, flags);
#elif defined NANOVG_GLES3
return nvgCreateSharedGLES3(NULL, flags);
#endif
}

// Share the fonts and textures of 'other' if it's non-NULL.
#if defined NANOVG_GL2
NVGcontext* nvgCreateSharedGL2(NVGcontext* other, int flags)
#elif defined NANOVG_GL3
NVGcontext* nvgCreateSharedGL3(NVGcontext* other, int flags)
#elif defined NANOVG_GLES2
NVGcontext* nvgCreateSharedGLES2(NVGcontext* other, int flags)
#elif defined NANOVG_GLES3
NVGcontext* nvgCreateSharedGLES3(NVGcontext* other, int flags)
#endif
{
NVGparams params;
NVGcontext* ctx = NULL;
@@ -1654,7 +1701,7 @@ NVGcontext* nvgCreateGLES3(int flags)

gl->flags = flags;

ctx = nvgCreateInternal(&params);
ctx = nvgCreateInternal(&params, other);
if (ctx == NULL) goto error;

return ctx;


+ 725
- 1767
dgl/src/nanovg/stb_image.h
File diff suppressed because it is too large
View File


Loading…
Cancel
Save