|
|
@@ -112,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; |
|
|
@@ -125,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; |
|
|
@@ -286,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)); |
|
|
@@ -295,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; |
|
|
@@ -311,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; |
|
|
|
|
|
|
@@ -350,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) |
|
|
@@ -394,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; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -2309,35 +2329,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) |
|
|
@@ -2347,7 +2367,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) |
|
|
@@ -2395,7 +2415,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) |
|
|
@@ -2412,12 +2432,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]; |
|
|
@@ -2431,23 +2451,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; |
|
|
|
} |
|
|
|
|
|
|
@@ -2458,7 +2478,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++) { |
|
|
@@ -2495,19 +2515,19 @@ float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char* |
|
|
|
|
|
|
|
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) { |
|
|
@@ -2517,7 +2537,7 @@ 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; |
|
|
|
} |
|
|
@@ -2602,18 +2622,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; |
|
|
@@ -2666,20 +2686,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) { |
|
|
@@ -2850,16 +2870,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; |
|
|
@@ -2894,12 +2914,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; |
|
|
|
|
|
|
@@ -2945,13 +2965,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) |
|
|
|