Merge pull request #1590 from mchiasson/update_nanovg
upgraded nanovg to the latest.
This commit is contained in:
commit
4a49f14b5d
@ -518,6 +518,32 @@ void drawGraph(struct NVGcontext* vg, float x, float y, float w, float h, float
|
||||
nvgStrokeWidth(vg, 1.0f);
|
||||
}
|
||||
|
||||
void drawSpinner(struct NVGcontext* vg, float cx, float cy, float r, float t)
|
||||
{
|
||||
float a0 = 0.0f + t*6;
|
||||
float a1 = NVG_PI + t*6;
|
||||
float r0 = r;
|
||||
float r1 = r * 0.75f;
|
||||
float ax,ay, bx,by;
|
||||
struct NVGpaint paint;
|
||||
|
||||
nvgSave(vg);
|
||||
|
||||
nvgBeginPath(vg);
|
||||
nvgArc(vg, cx,cy, r0, a0, a1, NVG_CW);
|
||||
nvgArc(vg, cx,cy, r1, a1, a0, NVG_CCW);
|
||||
nvgClosePath(vg);
|
||||
ax = cx + cosf(a0) * (r0+r1)*0.5f;
|
||||
ay = cy + sinf(a0) * (r0+r1)*0.5f;
|
||||
bx = cx + cosf(a1) * (r0+r1)*0.5f;
|
||||
by = cy + sinf(a1) * (r0+r1)*0.5f;
|
||||
paint = nvgLinearGradient(vg, ax,ay, bx,by, nvgRGBA(0,0,0,0), nvgRGBA(0,0,0,128) );
|
||||
nvgFillPaint(vg, paint);
|
||||
nvgFill(vg);
|
||||
|
||||
nvgRestore(vg);
|
||||
}
|
||||
|
||||
void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, const int* images, int nimages, float t)
|
||||
{
|
||||
float cornerRadius = 3.0f;
|
||||
@ -529,7 +555,8 @@ void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, c
|
||||
float stackh = (nimages/2) * (thumb+10) + 10;
|
||||
int i;
|
||||
float u = (1+cosf(t*0.5f) )*0.5f;
|
||||
float scrollh;
|
||||
float u2 = (1-cosf(t*0.2f) )*0.5f;
|
||||
float scrollh, dv;
|
||||
|
||||
nvgSave(vg);
|
||||
// nvgClearState(vg);
|
||||
@ -556,8 +583,10 @@ void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, c
|
||||
nvgScissor(vg, x,y,w,h);
|
||||
nvgTranslate(vg, 0, -(stackh - h)*u);
|
||||
|
||||
dv = 1.0f / (float)(nimages-1);
|
||||
|
||||
for (i = 0; i < nimages; i++) {
|
||||
float tx, ty;
|
||||
float tx, ty, v, a;
|
||||
tx = x+10;
|
||||
ty = y+10;
|
||||
tx += (i%2) * (thumb+10);
|
||||
@ -574,7 +603,14 @@ void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, c
|
||||
ix = -(iw-thumb)*0.5f;
|
||||
iy = 0;
|
||||
}
|
||||
imgPaint = nvgImagePattern(vg, tx+ix, ty+iy, iw,ih, 0.0f/180.0f*NVG_PI, images[i], 1.0f);
|
||||
|
||||
v = i * dv;
|
||||
a = bx::clamp((u2-v) / dv, 0.0f, 1.0f);
|
||||
|
||||
if (a < 1.0f)
|
||||
drawSpinner(vg, tx+thumb/2,ty+thumb/2, thumb*0.25f, t);
|
||||
|
||||
imgPaint = nvgImagePattern(vg, tx+ix, ty+iy, iw,ih, 0.0f/180.0f*NVG_PI, images[i], a);
|
||||
nvgBeginPath(vg);
|
||||
nvgRoundedRect(vg, tx,ty, thumb,thumb, 5);
|
||||
nvgFillPaint(vg, imgPaint);
|
||||
@ -786,6 +822,7 @@ void drawLines(struct NVGcontext* vg, float x, float y, float w, float h, float
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nvgRestore(vg);
|
||||
}
|
||||
|
||||
@ -939,7 +976,7 @@ void drawBlendish(struct NVGcontext* _vg, float _x, float _y, float _w, float _h
|
||||
|
||||
struct DemoData
|
||||
{
|
||||
int fontNormal, fontBold, fontIcons;
|
||||
int fontNormal, fontBold, fontIcons, fontEmoji;
|
||||
int images[12];
|
||||
};
|
||||
|
||||
@ -980,12 +1017,17 @@ int createImage(struct NVGcontext* _ctx, const char* _filePath, int _imageFlags)
|
||||
|
||||
int loadDemoData(struct NVGcontext* vg, struct DemoData* data)
|
||||
{
|
||||
for (uint32_t ii = 0; ii < 12; ++ii)
|
||||
int i;
|
||||
|
||||
if (vg == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
char file[128];
|
||||
bx::snprintf(file, 128, "images/image%d.jpg", ii+1);
|
||||
data->images[ii] = createImage(vg, file, 0);
|
||||
if (data->images[ii] == 0)
|
||||
bx::snprintf(file, 128, "images/image%d.jpg", i+1);
|
||||
data->images[i] = createImage(vg, file, 0);
|
||||
if (data->images[i] == 0)
|
||||
{
|
||||
printf("Could not load %s.\n", file);
|
||||
return -1;
|
||||
@ -1013,6 +1055,15 @@ int loadDemoData(struct NVGcontext* vg, struct DemoData* data)
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->fontEmoji = nvgCreateFont(vg, "emoji", "font/NotoEmoji-Regular.ttf");
|
||||
if (data->fontEmoji == -1)
|
||||
{
|
||||
printf("Could not add font emoji.\n");
|
||||
return -1;
|
||||
}
|
||||
nvgAddFallbackFontId(vg, data->fontNormal, data->fontEmoji);
|
||||
nvgAddFallbackFontId(vg, data->fontBold, data->fontEmoji);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1031,13 +1082,14 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h
|
||||
{
|
||||
struct NVGtextRow rows[3];
|
||||
struct NVGglyphPosition glyphs[100];
|
||||
const char* text = "This is longer chunk of text.\n \n Would have used lorem ipsum but she was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party.";
|
||||
const char* text = "This is longer chunk of text.\n \n Would have used lorem ipsum but she was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party.🎉";
|
||||
const char* start;
|
||||
const char* end;
|
||||
int nrows, i, nglyphs, j, lnum = 0;
|
||||
float lineh;
|
||||
float caretx, px;
|
||||
float bounds[4];
|
||||
float a;
|
||||
float gx = 0.0f, gy = 0.0f;
|
||||
int gutter = 0;
|
||||
NVG_NOTUSED(height);
|
||||
@ -1061,7 +1113,7 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h
|
||||
int hit = mx > x && mx < (x+width) && my >= y && my < (y+lineh);
|
||||
|
||||
nvgBeginPath(vg);
|
||||
nvgFillColor(vg, nvgRGBA(255,255,255,hit?64:8) );
|
||||
nvgFillColor(vg, nvgRGBA(255,255,255,hit?64:16) );
|
||||
nvgRect(vg, x, y, row->width, lineh);
|
||||
nvgFill(vg);
|
||||
|
||||
@ -1127,6 +1179,14 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h
|
||||
nvgTextLineHeight(vg, 1.2f);
|
||||
|
||||
nvgTextBoxBounds(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL, bounds);
|
||||
|
||||
// Fade the tooltip out when close to it.
|
||||
gx = bx::abs((mx - (bounds[0]+bounds[2])*0.5f) / (bounds[0] - bounds[2]) );
|
||||
gy = bx::abs((my - (bounds[1]+bounds[3])*0.5f) / (bounds[1] - bounds[3]) );
|
||||
a = bx::max(gx, gy) - 0.5f;
|
||||
a = bx::clamp(a, 0.0f, 1.0f);
|
||||
nvgGlobalAlpha(vg, a);
|
||||
|
||||
nvgBeginPath(vg);
|
||||
nvgFillColor(vg, nvgRGBA(220,220,220,255) );
|
||||
nvgRoundedRect(vg
|
||||
@ -1150,13 +1210,15 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h
|
||||
|
||||
void drawWidths(struct NVGcontext* vg, float x, float y, float width)
|
||||
{
|
||||
int i;
|
||||
|
||||
nvgSave(vg);
|
||||
|
||||
nvgStrokeColor(vg, nvgRGBA(0,0,0,255) );
|
||||
|
||||
for (uint32_t ii = 0; ii < 20; ++ii)
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
float w = (ii+0.5f)*0.1f;
|
||||
float w = (i+0.5f)*0.1f;
|
||||
nvgStrokeWidth(vg, w);
|
||||
nvgBeginPath(vg);
|
||||
nvgMoveTo(vg, x,y);
|
||||
@ -1168,6 +1230,73 @@ void drawWidths(struct NVGcontext* vg, float x, float y, float width)
|
||||
nvgRestore(vg);
|
||||
}
|
||||
|
||||
void drawCaps(struct NVGcontext* vg, float x, float y, float width)
|
||||
{
|
||||
int i;
|
||||
int caps[3] = {NVG_BUTT, NVG_ROUND, NVG_SQUARE};
|
||||
float lineWidth = 8.0f;
|
||||
|
||||
nvgSave(vg);
|
||||
|
||||
nvgBeginPath(vg);
|
||||
nvgRect(vg, x-lineWidth/2, y, width+lineWidth, 40);
|
||||
nvgFillColor(vg, nvgRGBA(255,255,255,32) );
|
||||
nvgFill(vg);
|
||||
|
||||
nvgBeginPath(vg);
|
||||
nvgRect(vg, x, y, width, 40);
|
||||
nvgFillColor(vg, nvgRGBA(255,255,255,32) );
|
||||
nvgFill(vg);
|
||||
|
||||
nvgStrokeWidth(vg, lineWidth);
|
||||
for (i = 0; i < 3; i++) {
|
||||
nvgLineCap(vg, caps[i]);
|
||||
nvgStrokeColor(vg, nvgRGBA(0,0,0,255) );
|
||||
nvgBeginPath(vg);
|
||||
nvgMoveTo(vg, x, y + i*10 + 5);
|
||||
nvgLineTo(vg, x+width, y + i*10 + 5);
|
||||
nvgStroke(vg);
|
||||
}
|
||||
|
||||
nvgRestore(vg);
|
||||
}
|
||||
|
||||
void drawScissor(struct NVGcontext* vg, float x, float y, float t)
|
||||
{
|
||||
nvgSave(vg);
|
||||
|
||||
// Draw first rect and set scissor to it's area.
|
||||
nvgTranslate(vg, x, y);
|
||||
nvgRotate(vg, nvgDegToRad(5) );
|
||||
nvgBeginPath(vg);
|
||||
nvgRect(vg, -20,-20,60,40);
|
||||
nvgFillColor(vg, nvgRGBA(255,0,0,255) );
|
||||
nvgFill(vg);
|
||||
nvgScissor(vg, -20,-20,60,40);
|
||||
|
||||
// Draw second rectangle with offset and rotation.
|
||||
nvgTranslate(vg, 40,0);
|
||||
nvgRotate(vg, t);
|
||||
|
||||
// Draw the intended second rectangle without any scissoring.
|
||||
nvgSave(vg);
|
||||
nvgResetScissor(vg);
|
||||
nvgBeginPath(vg);
|
||||
nvgRect(vg, -20,-10,60,30);
|
||||
nvgFillColor(vg, nvgRGBA(255,128,0,64) );
|
||||
nvgFill(vg);
|
||||
nvgRestore(vg);
|
||||
|
||||
// Draw second rectangle with combined scissoring.
|
||||
nvgIntersectScissor(vg, -20,-10,60,30);
|
||||
nvgBeginPath(vg);
|
||||
nvgRect(vg, -20,-10,60,30);
|
||||
nvgFillColor(vg, nvgRGBA(255,128,0,255) );
|
||||
nvgFill(vg);
|
||||
|
||||
nvgRestore(vg);
|
||||
}
|
||||
|
||||
void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float height, float t, int blowup, struct DemoData* data)
|
||||
{
|
||||
float x,y,popx,popy;
|
||||
@ -1181,6 +1310,14 @@ void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float he
|
||||
// Line joints
|
||||
drawLines(vg, 50, height-50, 600, 35, t);
|
||||
|
||||
// Line caps
|
||||
drawWidths(vg, width-50, 35, 30);
|
||||
|
||||
// Line caps
|
||||
drawCaps(vg, width-50, 260, 30);
|
||||
|
||||
drawScissor(vg, 40, height-150, t);
|
||||
|
||||
nvgSave(vg);
|
||||
if (blowup)
|
||||
{
|
||||
@ -1188,9 +1325,6 @@ void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float he
|
||||
nvgScale(vg, 2.0f, 2.0f);
|
||||
}
|
||||
|
||||
// Line width.
|
||||
drawWidths(vg, width-50, 35, 30);
|
||||
|
||||
// Widgets.
|
||||
x = width-520; y = height-420;
|
||||
drawWindow(vg, "Widgets `n Stuff", x, y, 300, 400);
|
||||
@ -1325,7 +1459,7 @@ public:
|
||||
// if no other draw calls are submitted to view 0.
|
||||
bgfx::touch(0);
|
||||
|
||||
nvgBeginFrame(m_nvg, m_width, m_height, 1.0f);
|
||||
nvgBeginFrame(m_nvg, float(m_width), float(m_height), 1.0f);
|
||||
|
||||
renderDemo(m_nvg, float(m_mouseState.m_mx), float(m_mouseState.m_my), float(m_width), float(m_height), time, 0, &m_data);
|
||||
|
||||
|
@ -89,7 +89,7 @@ typedef struct FONStextIter FONStextIter;
|
||||
|
||||
typedef struct FONScontext FONScontext;
|
||||
|
||||
// Contructor and destructor.
|
||||
// Constructor and destructor.
|
||||
FONScontext* fonsCreateInternal(FONSparams* params);
|
||||
void fonsDeleteInternal(FONScontext* s);
|
||||
|
||||
@ -98,7 +98,7 @@ void fonsSetErrorCallback(FONScontext* s, void (*callback)(void* uptr, int error
|
||||
void fonsGetAtlasSize(FONScontext* s, int* width, int* height);
|
||||
// Expands the atlas size.
|
||||
int fonsExpandAtlas(FONScontext* s, int width, int height);
|
||||
// Reseta the whole stash.
|
||||
// Resets the whole stash.
|
||||
int fonsResetAtlas(FONScontext* stash, int width, int height);
|
||||
|
||||
// Add fonts
|
||||
@ -162,11 +162,19 @@ static FT_Library ftLibrary;
|
||||
int fons__tt_init(FONScontext *context)
|
||||
{
|
||||
FT_Error ftError;
|
||||
FONS_NOTUSED(context);
|
||||
FONS_NOTUSED(context);
|
||||
ftError = FT_Init_FreeType(&ftLibrary);
|
||||
return ftError == 0;
|
||||
}
|
||||
|
||||
int fons__tt_done(FONScontext *context)
|
||||
{
|
||||
FT_Error ftError;
|
||||
FONS_NOTUSED(context);
|
||||
ftError = FT_Done_FreeType(ftLibrary);
|
||||
return ftError == 0;
|
||||
}
|
||||
|
||||
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize)
|
||||
{
|
||||
FT_Error ftError;
|
||||
@ -204,7 +212,7 @@ int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float
|
||||
|
||||
ftError = FT_Set_Pixel_Sizes(font->font, 0, (FT_UInt)(size * (float)font->font->units_per_EM / (float)(font->font->ascender - font->font->descender)));
|
||||
if (ftError) return 0;
|
||||
ftError = FT_Load_Glyph(font->font, glyph, FT_LOAD_RENDER);
|
||||
ftError = FT_Load_Glyph(font->font, glyph, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT);
|
||||
if (ftError) return 0;
|
||||
ftError = FT_Get_Advance(font->font, glyph, FT_LOAD_NO_SCALE, &advFixed);
|
||||
if (ftError) return 0;
|
||||
@ -271,6 +279,12 @@ int fons__tt_init(FONScontext *context)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fons__tt_done(FONScontext *context)
|
||||
{
|
||||
FONS_NOTUSED(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize)
|
||||
{
|
||||
int stbError;
|
||||
@ -319,7 +333,7 @@ int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2)
|
||||
#endif
|
||||
|
||||
#ifndef FONS_SCRATCH_BUF_SIZE
|
||||
# define FONS_SCRATCH_BUF_SIZE 64000
|
||||
# define FONS_SCRATCH_BUF_SIZE 96000
|
||||
#endif
|
||||
#ifndef FONS_HASH_LUT_SIZE
|
||||
# define FONS_HASH_LUT_SIZE 256
|
||||
@ -406,7 +420,7 @@ struct FONSstate
|
||||
typedef struct FONSstate FONSstate;
|
||||
|
||||
struct FONSatlasNode {
|
||||
short x, y, width;
|
||||
short x, y, width;
|
||||
};
|
||||
typedef struct FONSatlasNode FONSatlasNode;
|
||||
|
||||
@ -497,11 +511,11 @@ static unsigned int fons__decutf8(unsigned int* state, unsigned int* codep, unsi
|
||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
||||
12,36,12,12,12,12,12,12,12,12,12,12,
|
||||
};
|
||||
};
|
||||
|
||||
unsigned int type = utf8d[byte];
|
||||
|
||||
*codep = (*state != FONS_UTF8_ACCEPT) ?
|
||||
*codep = (*state != FONS_UTF8_ACCEPT) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
|
||||
@ -886,7 +900,7 @@ error:
|
||||
int fonsAddFont(FONScontext* stash, const char* name, const char* path)
|
||||
{
|
||||
FILE* fp = 0;
|
||||
size_t dataSize = 0;
|
||||
int dataSize = 0;
|
||||
size_t readed;
|
||||
unsigned char* data = NULL;
|
||||
|
||||
@ -894,16 +908,16 @@ int fonsAddFont(FONScontext* stash, const char* name, const char* path)
|
||||
fp = fopen(path, "rb");
|
||||
if (fp == NULL) goto error;
|
||||
fseek(fp,0,SEEK_END);
|
||||
dataSize = ftell(fp);
|
||||
dataSize = (int)ftell(fp);
|
||||
fseek(fp,0,SEEK_SET);
|
||||
data = (unsigned char*)malloc(dataSize);
|
||||
if (data == NULL) goto error;
|
||||
readed = fread(data, 1, dataSize, fp);
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
if (readed != dataSize) goto error;
|
||||
if ((int)readed != dataSize) goto error;
|
||||
|
||||
return fonsAddFontMem(stash, name, data, int(dataSize), 1);
|
||||
return fonsAddFontMem(stash, name, data, dataSize, 1);
|
||||
|
||||
error:
|
||||
if (data) free(data);
|
||||
@ -1637,6 +1651,7 @@ void fonsDeleteInternal(FONScontext* stash)
|
||||
if (stash->texData) free(stash->texData);
|
||||
if (stash->scratch) free(stash->scratch);
|
||||
free(stash);
|
||||
fons__tt_done(stash);
|
||||
}
|
||||
|
||||
void fonsSetErrorCallback(FONScontext* stash, void (*callback)(void* uptr, int error, int val), void* uptr)
|
||||
|
@ -347,7 +347,7 @@ error:
|
||||
|
||||
NVGparams* nvgInternalParams(NVGcontext* ctx)
|
||||
{
|
||||
return &ctx->params;
|
||||
return &ctx->params;
|
||||
}
|
||||
|
||||
void nvgDeleteInternal(NVGcontext* ctx)
|
||||
@ -373,7 +373,7 @@ void nvgDeleteInternal(NVGcontext* ctx)
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void nvgBeginFrame(NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio)
|
||||
void nvgBeginFrame(NVGcontext* ctx, float windowWidth, float windowHeight, float devicePixelRatio)
|
||||
{
|
||||
/* printf("Tris: draws:%d fill:%d stroke:%d text:%d TOT:%d\n",
|
||||
ctx->drawCallCount, ctx->fillTriCount, ctx->strokeTriCount, ctx->textTriCount,
|
||||
@ -1421,7 +1421,8 @@ static void nvg__chooseBevel(int bevel, NVGpoint* p0, NVGpoint* p1, float w,
|
||||
}
|
||||
|
||||
static NVGvertex* nvg__roundJoin(NVGvertex* dst, NVGpoint* p0, NVGpoint* p1,
|
||||
float lw, float rw, float lu, float ru, int ncap, float fringe)
|
||||
float lw, float rw, float lu, float ru, int ncap,
|
||||
float fringe)
|
||||
{
|
||||
int i, n;
|
||||
float dlx0 = p0->dy;
|
||||
@ -1554,36 +1555,39 @@ static NVGvertex* nvg__bevelJoin(NVGvertex* dst, NVGpoint* p0, NVGpoint* p1,
|
||||
}
|
||||
|
||||
static NVGvertex* nvg__buttCapStart(NVGvertex* dst, NVGpoint* p,
|
||||
float dx, float dy, float w, float d, float aa)
|
||||
float dx, float dy, float w, float d,
|
||||
float aa, float u0, float u1)
|
||||
{
|
||||
float px = p->x - dx*d;
|
||||
float py = p->y - dy*d;
|
||||
float dlx = dy;
|
||||
float dly = -dx;
|
||||
nvg__vset(dst, px + dlx*w - dx*aa, py + dly*w - dy*aa, 0,0); dst++;
|
||||
nvg__vset(dst, px - dlx*w - dx*aa, py - dly*w - dy*aa, 1,0); dst++;
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, 0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, 1,1); dst++;
|
||||
nvg__vset(dst, px + dlx*w - dx*aa, py + dly*w - dy*aa, u0,0); dst++;
|
||||
nvg__vset(dst, px - dlx*w - dx*aa, py - dly*w - dy*aa, u1,0); dst++;
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, u0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, u1,1); dst++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static NVGvertex* nvg__buttCapEnd(NVGvertex* dst, NVGpoint* p,
|
||||
float dx, float dy, float w, float d, float aa)
|
||||
float dx, float dy, float w, float d,
|
||||
float aa, float u0, float u1)
|
||||
{
|
||||
float px = p->x + dx*d;
|
||||
float py = p->y + dy*d;
|
||||
float dlx = dy;
|
||||
float dly = -dx;
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, 0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, 1,1); dst++;
|
||||
nvg__vset(dst, px + dlx*w + dx*aa, py + dly*w + dy*aa, 0,0); dst++;
|
||||
nvg__vset(dst, px - dlx*w + dx*aa, py - dly*w + dy*aa, 1,0); dst++;
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, u0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, u1,1); dst++;
|
||||
nvg__vset(dst, px + dlx*w + dx*aa, py + dly*w + dy*aa, u0,0); dst++;
|
||||
nvg__vset(dst, px - dlx*w + dx*aa, py - dly*w + dy*aa, u1,0); dst++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
static NVGvertex* nvg__roundCapStart(NVGvertex* dst, NVGpoint* p,
|
||||
float dx, float dy, float w, int ncap, float aa)
|
||||
float dx, float dy, float w, int ncap,
|
||||
float aa, float u0, float u1)
|
||||
{
|
||||
int i;
|
||||
float px = p->x;
|
||||
@ -1594,16 +1598,17 @@ static NVGvertex* nvg__roundCapStart(NVGvertex* dst, NVGpoint* p,
|
||||
for (i = 0; i < ncap; i++) {
|
||||
float a = i/(float)(ncap-1)*NVG_PI;
|
||||
float ax = cosf(a) * w, ay = sinf(a) * w;
|
||||
nvg__vset(dst, px - dlx*ax - dx*ay, py - dly*ax - dy*ay, 0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*ax - dx*ay, py - dly*ax - dy*ay, u0,1); dst++;
|
||||
nvg__vset(dst, px, py, 0.5f,1); dst++;
|
||||
}
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, 0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, 1,1); dst++;
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, u0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, u1,1); dst++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static NVGvertex* nvg__roundCapEnd(NVGvertex* dst, NVGpoint* p,
|
||||
float dx, float dy, float w, int ncap, float aa)
|
||||
float dx, float dy, float w, int ncap,
|
||||
float aa, float u0, float u1)
|
||||
{
|
||||
int i;
|
||||
float px = p->x;
|
||||
@ -1611,13 +1616,13 @@ static NVGvertex* nvg__roundCapEnd(NVGvertex* dst, NVGpoint* p,
|
||||
float dlx = dy;
|
||||
float dly = -dx;
|
||||
NVG_NOTUSED(aa);
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, 0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, 1,1); dst++;
|
||||
nvg__vset(dst, px + dlx*w, py + dly*w, u0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*w, py - dly*w, u1,1); dst++;
|
||||
for (i = 0; i < ncap; i++) {
|
||||
float a = i/(float)(ncap-1)*NVG_PI;
|
||||
float ax = cosf(a) * w, ay = sinf(a) * w;
|
||||
nvg__vset(dst, px, py, 0.5f,1); dst++;
|
||||
nvg__vset(dst, px - dlx*ax + dx*ay, py - dly*ax + dy*ay, 0,1); dst++;
|
||||
nvg__vset(dst, px - dlx*ax + dx*ay, py - dly*ax + dy*ay, u0,1); dst++;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
@ -1693,15 +1698,24 @@ static void nvg__calculateJoins(NVGcontext* ctx, float w, int lineJoin, float mi
|
||||
}
|
||||
|
||||
|
||||
static int nvg__expandStroke(NVGcontext* ctx, float w, int lineCap, int lineJoin, float miterLimit)
|
||||
static int nvg__expandStroke(NVGcontext* ctx, float w, float fringe, int lineCap, int lineJoin, float miterLimit)
|
||||
{
|
||||
NVGpathCache* cache = ctx->cache;
|
||||
NVGvertex* verts;
|
||||
NVGvertex* dst;
|
||||
int cverts, i, j;
|
||||
float aa = ctx->fringeWidth;
|
||||
float aa = fringe;//ctx->fringeWidth;
|
||||
float u0 = 0.0f, u1 = 1.0f;
|
||||
int ncap = nvg__curveDivs(w, NVG_PI, ctx->tessTol); // Calculate divisions per half circle.
|
||||
|
||||
w += aa * 0.5f;
|
||||
|
||||
// Disable the gradient used for antialiasing when antialiasing is not used.
|
||||
if (aa == 0.0f) {
|
||||
u0 = 0.5f;
|
||||
u1 = 0.5f;
|
||||
}
|
||||
|
||||
nvg__calculateJoins(ctx, w, lineJoin, miterLimit);
|
||||
|
||||
// Calculate max vertex usage.
|
||||
@ -1762,42 +1776,42 @@ static int nvg__expandStroke(NVGcontext* ctx, float w, int lineCap, int lineJoin
|
||||
dy = p1->y - p0->y;
|
||||
nvg__normalize(&dx, &dy);
|
||||
if (lineCap == NVG_BUTT)
|
||||
dst = nvg__buttCapStart(dst, p0, dx, dy, w, -aa*0.5f, aa);
|
||||
dst = nvg__buttCapStart(dst, p0, dx, dy, w, -aa*0.5f, aa, u0, u1);
|
||||
else if (lineCap == NVG_BUTT || lineCap == NVG_SQUARE)
|
||||
dst = nvg__buttCapStart(dst, p0, dx, dy, w, w-aa, aa);
|
||||
dst = nvg__buttCapStart(dst, p0, dx, dy, w, w-aa, aa, u0, u1);
|
||||
else if (lineCap == NVG_ROUND)
|
||||
dst = nvg__roundCapStart(dst, p0, dx, dy, w, ncap, aa);
|
||||
dst = nvg__roundCapStart(dst, p0, dx, dy, w, ncap, aa, u0, u1);
|
||||
}
|
||||
|
||||
for (j = s; j < e; ++j) {
|
||||
if ((p1->flags & (NVG_PT_BEVEL | NVG_PR_INNERBEVEL)) != 0) {
|
||||
if (lineJoin == NVG_ROUND) {
|
||||
dst = nvg__roundJoin(dst, p0, p1, w, w, 0, 1, ncap, aa);
|
||||
dst = nvg__roundJoin(dst, p0, p1, w, w, u0, u1, ncap, aa);
|
||||
} else {
|
||||
dst = nvg__bevelJoin(dst, p0, p1, w, w, 0, 1, aa);
|
||||
dst = nvg__bevelJoin(dst, p0, p1, w, w, u0, u1, aa);
|
||||
}
|
||||
} else {
|
||||
nvg__vset(dst, p1->x + (p1->dmx * w), p1->y + (p1->dmy * w), 0,1); dst++;
|
||||
nvg__vset(dst, p1->x - (p1->dmx * w), p1->y - (p1->dmy * w), 1,1); dst++;
|
||||
nvg__vset(dst, p1->x + (p1->dmx * w), p1->y + (p1->dmy * w), u0,1); dst++;
|
||||
nvg__vset(dst, p1->x - (p1->dmx * w), p1->y - (p1->dmy * w), u1,1); dst++;
|
||||
}
|
||||
p0 = p1++;
|
||||
}
|
||||
|
||||
if (loop) {
|
||||
// Loop it
|
||||
nvg__vset(dst, verts[0].x, verts[0].y, 0,1); dst++;
|
||||
nvg__vset(dst, verts[1].x, verts[1].y, 1,1); dst++;
|
||||
nvg__vset(dst, verts[0].x, verts[0].y, u0,1); dst++;
|
||||
nvg__vset(dst, verts[1].x, verts[1].y, u1,1); dst++;
|
||||
} else {
|
||||
// Add cap
|
||||
dx = p1->x - p0->x;
|
||||
dy = p1->y - p0->y;
|
||||
nvg__normalize(&dx, &dy);
|
||||
if (lineCap == NVG_BUTT)
|
||||
dst = nvg__buttCapEnd(dst, p1, dx, dy, w, -aa*0.5f, aa);
|
||||
dst = nvg__buttCapEnd(dst, p1, dx, dy, w, -aa*0.5f, aa, u0, u1);
|
||||
else if (lineCap == NVG_BUTT || lineCap == NVG_SQUARE)
|
||||
dst = nvg__buttCapEnd(dst, p1, dx, dy, w, w-aa, aa);
|
||||
dst = nvg__buttCapEnd(dst, p1, dx, dy, w, w-aa, aa, u0, u1);
|
||||
else if (lineCap == NVG_ROUND)
|
||||
dst = nvg__roundCapEnd(dst, p1, dx, dy, w, ncap, aa);
|
||||
dst = nvg__roundCapEnd(dst, p1, dx, dy, w, ncap, aa, u0, u1);
|
||||
}
|
||||
|
||||
path->nstroke = (int)(dst - verts);
|
||||
@ -1956,13 +1970,13 @@ void nvgBezierTo(NVGcontext* ctx, float c1x, float c1y, float c2x, float c2y, fl
|
||||
|
||||
void nvgQuadTo(NVGcontext* ctx, float cx, float cy, float x, float y)
|
||||
{
|
||||
float x0 = ctx->commandx;
|
||||
float y0 = ctx->commandy;
|
||||
float vals[] = { NVG_BEZIERTO,
|
||||
x0 + 2.0f/3.0f*(cx - x0), y0 + 2.0f/3.0f*(cy - y0),
|
||||
x + 2.0f/3.0f*(cx - x), y + 2.0f/3.0f*(cy - y),
|
||||
x, y };
|
||||
nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals));
|
||||
float x0 = ctx->commandx;
|
||||
float y0 = ctx->commandy;
|
||||
float vals[] = { NVG_BEZIERTO,
|
||||
x0 + 2.0f/3.0f*(cx - x0), y0 + 2.0f/3.0f*(cy - y0),
|
||||
x + 2.0f/3.0f*(cx - x), y + 2.0f/3.0f*(cy - y),
|
||||
x, y };
|
||||
nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals));
|
||||
}
|
||||
|
||||
void nvgArcTo(NVGcontext* ctx, float x1, float y1, float x2, float y2, float radius)
|
||||
@ -2221,6 +2235,7 @@ void nvgStroke(NVGcontext* ctx)
|
||||
const NVGpath* path;
|
||||
int i;
|
||||
|
||||
|
||||
if (strokeWidth < ctx->fringeWidth) {
|
||||
// If the stroke width is less than pixel size, use alpha to emulate coverage.
|
||||
// Since coverage is area, scale by alpha*alpha.
|
||||
@ -2237,9 +2252,9 @@ void nvgStroke(NVGcontext* ctx)
|
||||
nvg__flattenPaths(ctx);
|
||||
|
||||
if (ctx->params.edgeAntiAlias && state->shapeAntiAlias)
|
||||
nvg__expandStroke(ctx, strokeWidth*0.5f + ctx->fringeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit);
|
||||
nvg__expandStroke(ctx, strokeWidth*0.5f, ctx->fringeWidth, state->lineCap, state->lineJoin, state->miterLimit);
|
||||
else
|
||||
nvg__expandStroke(ctx, strokeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit);
|
||||
nvg__expandStroke(ctx, strokeWidth*0.5f, 0.0f, state->lineCap, state->lineJoin, state->miterLimit);
|
||||
|
||||
ctx->params.renderStroke(ctx->params.userPtr, &strokePaint, state->compositeOperation, &state->scissor, ctx->fringeWidth,
|
||||
strokeWidth, ctx->cache->paths, ctx->cache->npaths);
|
||||
@ -2426,12 +2441,12 @@ float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char*
|
||||
while (fonsTextIterNext(ctx->fs, &iter, &q)) {
|
||||
float c[4*2];
|
||||
if (iter.prevGlyphIndex == -1) { // can not retrieve glyph?
|
||||
if (!nvg__allocTextAtlas(ctx))
|
||||
break; // no memory :(
|
||||
if (nverts != 0) {
|
||||
nvg__renderText(ctx, verts, nverts);
|
||||
nverts = 0;
|
||||
}
|
||||
if (!nvg__allocTextAtlas(ctx))
|
||||
break; // no memory :(
|
||||
iter = prevIter;
|
||||
fonsTextIterNext(ctx->fs, &iter, &q); // try again
|
||||
if (iter.prevGlyphIndex == -1) // still can not find glyph?
|
||||
|
@ -138,7 +138,7 @@ struct NVGtextRow {
|
||||
typedef struct NVGtextRow NVGtextRow;
|
||||
|
||||
enum NVGimageFlags {
|
||||
NVG_IMAGE_GENERATE_MIPMAPS = 1<<0, // Generate mipmaps during creation of the image.
|
||||
NVG_IMAGE_GENERATE_MIPMAPS = 1<<0, // Generate mipmaps during creation of the image.
|
||||
NVG_IMAGE_REPEATX = 1<<1, // Repeat image in X direction.
|
||||
NVG_IMAGE_REPEATY = 1<<2, // Repeat image in Y direction.
|
||||
NVG_IMAGE_FLIPY = 1<<3, // Flips (inverses) image in Y direction when rendered.
|
||||
@ -154,7 +154,7 @@ enum NVGimageFlags {
|
||||
// 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(NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio);
|
||||
void nvgBeginFrame(NVGcontext* ctx, float windowWidth, float windowHeight, float devicePixelRatio);
|
||||
|
||||
// Cancels drawing the current frame.
|
||||
void nvgCancelFrame(NVGcontext* ctx);
|
||||
@ -271,7 +271,7 @@ void nvgLineCap(NVGcontext* ctx, int cap);
|
||||
void nvgLineJoin(NVGcontext* ctx, int join);
|
||||
|
||||
// Sets the transparency applied to all rendered shapes.
|
||||
// Alreade transparent paths will get proportionally more transparent as well.
|
||||
// Already transparent paths will get proportionally more transparent as well.
|
||||
void nvgGlobalAlpha(NVGcontext* ctx, float alpha);
|
||||
|
||||
//
|
||||
@ -395,7 +395,7 @@ NVGpaint nvgLinearGradient(NVGcontext* ctx, float sx, float sy, float ex, float
|
||||
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,
|
||||
// drop shadows or highlights 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().
|
||||
@ -647,7 +647,7 @@ struct NVGparams {
|
||||
int (*renderDeleteTexture)(void* uptr, int image);
|
||||
int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data);
|
||||
int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h);
|
||||
void (*renderViewport)(void* uptr, int width, int height, float devicePixelRatio);
|
||||
void (*renderViewport)(void* uptr, float width, float height, float devicePixelRatio);
|
||||
void (*renderCancel)(void* uptr);
|
||||
void (*renderFlush)(void* uptr);
|
||||
void (*renderFill)(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths);
|
||||
|
@ -554,11 +554,11 @@ namespace
|
||||
gl->th = handle;
|
||||
}
|
||||
|
||||
static void nvgRenderViewport(void* _userPtr, int width, int height, float devicePixelRatio)
|
||||
static void nvgRenderViewport(void* _userPtr, float width, float height, float devicePixelRatio)
|
||||
{
|
||||
struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr;
|
||||
gl->view[0] = (float)width;
|
||||
gl->view[1] = (float)height;
|
||||
gl->view[0] = width;
|
||||
gl->view[1] = height;
|
||||
bgfx::setViewRect(gl->viewId, 0, 0, width * devicePixelRatio, height * devicePixelRatio);
|
||||
}
|
||||
|
||||
|
BIN
examples/runtime/font/NotoEmoji-Regular.ttf
Normal file
BIN
examples/runtime/font/NotoEmoji-Regular.ttf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user