From 374fe6f84541827361bdce38f4eeedf50d367385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 8 Sep 2016 21:19:47 -0700 Subject: [PATCH] Updated NanoVG. --- examples/common/nanovg/fontstash.h | 42 +++++++++++++++++++++++++----- examples/common/nanovg/nanovg.cpp | 26 +++++++++++++++--- examples/common/nanovg/nanovg.h | 10 +++++-- 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/examples/common/nanovg/fontstash.h b/examples/common/nanovg/fontstash.h index 6fdb664e9..a6c9877f3 100644 --- a/examples/common/nanovg/fontstash.h +++ b/examples/common/nanovg/fontstash.h @@ -41,7 +41,7 @@ enum FONSalign { enum FONSerrorCode { // Font atlas is full. FONS_ATLAS_FULL = 1, - // Scratch memory used to render glyphs is full, requested size reported in 'val', you may need to bump up FONS_SCRATCH_BUF_SIZE. + // Scratch memory used to render glyphs is full, requested size reported in 'val', you may need to bump up FONS_SCRATCH_BUF_SIZE. FONS_SCRATCH_FULL = 2, // Calls to fonsPushState has created too large stack, if you need deep state stack bump up FONS_MAX_STATES. FONS_STATES_OVERFLOW = 3, @@ -193,16 +193,18 @@ int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float { FT_Error ftError; FT_GlyphSlot ftGlyph; + FT_Fixed advFixed; FONS_NOTUSED(scale); 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); if (ftError) return 0; - ftError = FT_Get_Advance(font->font, glyph, FT_LOAD_NO_SCALE, (FT_Fixed*)advance); + ftError = FT_Get_Advance(font->font, glyph, FT_LOAD_NO_SCALE, &advFixed); if (ftError) return 0; ftGlyph = font->font->glyph; - *lsb = ftGlyph->metrics.horiBearingX; + *advance = (int)advFixed; + *lsb = (int)ftGlyph->metrics.horiBearingX; *x0 = ftGlyph->bitmap_left; *x1 = *x0 + ftGlyph->bitmap.width; *y0 = -ftGlyph->bitmap_top; @@ -233,7 +235,7 @@ int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2) { FT_Vector ftKerning; FT_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning); - return ftKerning.x; + return (int)((ftKerning.x + 32) >> 6); // Round up and convert to integer } #else @@ -311,7 +313,7 @@ int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2) #endif #ifndef FONS_SCRATCH_BUF_SIZE -# define FONS_SCRATCH_BUF_SIZE 16000 +# define FONS_SCRATCH_BUF_SIZE 64000 #endif #ifndef FONS_HASH_LUT_SIZE # define FONS_HASH_LUT_SIZE 256 @@ -331,6 +333,9 @@ int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2) #ifndef FONS_MAX_STATES # define FONS_MAX_STATES 20 #endif +#ifndef FONS_MAX_FALLBACKS +# define FONS_MAX_FALLBACKS 20 +#endif static unsigned int fons__hashint(unsigned int a) { @@ -378,6 +383,8 @@ struct FONSfont int cglyphs; int nglyphs; int lut[FONS_HASH_LUT_SIZE]; + int fallbacks[FONS_MAX_FALLBACKS]; + int nfallbacks; }; typedef struct FONSfont FONSfont; @@ -428,7 +435,8 @@ struct FONScontext void* errorUptr; }; -#if 0 +#if 0 // defined(STB_TRUETYPE_IMPLEMENTATION) + static void* fons__tmpalloc(size_t size, void* up) { unsigned char* ptr; @@ -454,7 +462,8 @@ static void fons__tmpfree(void* ptr, void* up) // empty } -#endif +#endif // STB_TRUETYPE_IMPLEMENTATION + // Copyright (c) 2008-2010 Bjoern Hoehrmann // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. @@ -760,6 +769,16 @@ static FONSstate* fons__getState(FONScontext* stash) return &stash->states[stash->nstates-1]; } +int fonsAddFallbackFont(FONScontext* stash, int base, int fallback) +{ + FONSfont* baseFont = stash->fonts[base]; + if (baseFont->nfallbacks < FONS_MAX_FALLBACKS) { + baseFont->fallbacks[baseFont->nfallbacks++] = fallback; + return 1; + } + return 0; +} + void fonsSetSize(FONScontext* stash, float size) { fons__getState(stash)->size = size; @@ -1046,6 +1065,15 @@ static FONSglyph* fons__getGlyph(FONScontext* stash, FONSfont* font, unsigned in // Could not find glyph, create it. scale = fons__tt_getPixelHeightScale(&font->font, size); g = fons__tt_getGlyphIndex(&font->font, codepoint); + // Try to find the glyph in fallback fonts. + if (g == 0) { + for (i = 0; i < font->nfallbacks; ++i) { + FONSglyph* fallbackGlyph = fons__getGlyph(stash, stash->fonts[font->fallbacks[i]], codepoint, isize, iblur); + if (fallbackGlyph != NULL && fallbackGlyph->index != 0) { + return fallbackGlyph; + } + } + } fons__tt_buildGlyphBitmap(&font->font, g, size, scale, &advance, &lsb, &x0, &y0, &x1, &y1); gw = x1-x0 + pad*2; gh = y1-y0 + pad*2; diff --git a/examples/common/nanovg/nanovg.cpp b/examples/common/nanovg/nanovg.cpp index 9904141c1..257af11d5 100644 --- a/examples/common/nanovg/nanovg.cpp +++ b/examples/common/nanovg/nanovg.cpp @@ -16,8 +16,11 @@ // 3. This notice may not be removed or altered from any source distribution. // +#include #include #include +#include + #include "nanovg.h" #include @@ -250,11 +253,14 @@ static void nvg__setDevicePixelRatio(NVGcontext* ctx, float ratio) static NVGcompositeOperationState nvg__compositeOperationState(int op) { - // NVG_SOURCE_OVER - int sfactor = NVG_ONE; - int dfactor = NVG_ONE_MINUS_SRC_ALPHA; + int sfactor, dfactor; - if (op == NVG_SOURCE_IN) + if (op == NVG_SOURCE_OVER) + { + sfactor = NVG_ONE; + dfactor = NVG_ONE_MINUS_SRC_ALPHA; + } + else if (op == NVG_SOURCE_IN) { sfactor = NVG_DST_ALPHA; dfactor = NVG_ZERO; @@ -2308,6 +2314,18 @@ int nvgFindFont(NVGcontext* ctx, const char* name) return fonsGetFontByName(ctx->fs, name); } + +int nvgAddFallbackFontId(NVGcontext* ctx, int baseFont, int fallbackFont) +{ + if(baseFont == -1 || fallbackFont == -1) return 0; + return fonsAddFallbackFont(ctx->fs, baseFont, fallbackFont); +} + +int nvgAddFallbackFont(NVGcontext* ctx, const char* baseFont, const char* fallbackFont) +{ + return nvgAddFallbackFontId(ctx, nvgFindFont(ctx, baseFont), nvgFindFont(ctx, fallbackFont)); +} + // State setting void nvgFontSize(NVGcontext* ctx, float size) { diff --git a/examples/common/nanovg/nanovg.h b/examples/common/nanovg/nanovg.h index 99797e21f..31109efad 100644 --- a/examples/common/nanovg/nanovg.h +++ b/examples/common/nanovg/nanovg.h @@ -267,7 +267,7 @@ void nvgLineCap(NVGcontext* ctx, int cap); void nvgLineJoin(NVGcontext* ctx, int join); // Sets the transparency applied to all rendered shapes. -// Already transparent paths will get proportionally more transparent as well. +// Alreade transparent paths will get proportionally more transparent as well. void nvgGlobalAlpha(NVGcontext* ctx, float alpha); // @@ -399,7 +399,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 highlights for boxes. Parameters (x,y) define the top-left corner of the rectangle, +// drop shadows or hilights for boxes. Parameters (x,y) define the top-left corner of the rectangle, // (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry // 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(). @@ -548,6 +548,12 @@ int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int // Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found. int nvgFindFont(NVGcontext* ctx, const char* name); +// Adds a fallback font by handle. +int nvgAddFallbackFontId(NVGcontext* ctx, int baseFont, int fallbackFont); + +// Adds a fallback font by name. +int nvgAddFallbackFont(NVGcontext* ctx, const char* baseFont, const char* fallbackFont); + // Sets the font size of current text style. void nvgFontSize(NVGcontext* ctx, float size);