From 79fd926ce26f49f8ba6b370287d2d3f5c5c37913 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Sun, 10 Jun 2018 16:55:36 +0200 Subject: [PATCH 1/4] support different color structures --- .gitignore | 4 ++ premake4.lua | 4 +- src/fontstash.h | 131 +++++++++++++++++++++++++++-------------- src/gl3corefontstash.h | 22 ++++--- src/glfontstash.h | 16 +++-- 5 files changed, 120 insertions(+), 57 deletions(-) diff --git a/.gitignore b/.gitignore index 70f534e..1373142 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,7 @@ build/* ## xcode specific *xcuserdata* +src/lib-vc2015/glfw3dll.lib +src/GLFW/glfw3native.h +src/GLFW/glfw3.h +src/lib-vc2015/glfw3.lib diff --git a/premake4.lua b/premake4.lua index b52cfcc..b418f68 100644 --- a/premake4.lua +++ b/premake4.lua @@ -18,7 +18,7 @@ solution "fontstash" configuration { "windows" } defines { "_CRT_SECURE_NO_WARNINGS" } - links { "glu32","opengl32", "gdi32", "winmm", "user32" } + links { "glu32","opengl32", "gdi32", "winmm", "user32", "glfw3" } configuration { "macosx" } links { "glfw3" } @@ -44,7 +44,7 @@ solution "fontstash" configuration { "windows" } defines { "_CRT_SECURE_NO_WARNINGS" } - links { "glu32","opengl32", "gdi32", "winmm", "user32" } + links { "glu32","opengl32", "gdi32", "winmm", "user32", "glfw3" } configuration { "macosx" } links { "glfw3" } diff --git a/src/fontstash.h b/src/fontstash.h index f276af1..e8b7988 100644 --- a/src/fontstash.h +++ b/src/fontstash.h @@ -23,6 +23,14 @@ extern "C" { #endif +// options +#ifndef FONS_OPTIONS_RGBA_COLORS + #define FONS_OPTIONS_RGBA_COLORS 1 +#endif +#ifndef FONS_OPTIONS_FILE_IO + #define FONS_OPTIONS_FILE_IO 1 +#endif + // To make the implementation private to the file that generates the implementation #ifdef FONS_STATIC #define FONS_DEF static @@ -60,13 +68,24 @@ enum FONSerrorCode { FONS_STATES_UNDERFLOW = 4, }; +#pragma pack(push, 1) +struct FONScolor +{ + #if FONS_OPTIONS_RGBA_COLORS + unsigned char r, g, b; + #endif + unsigned char a; +}; +#pragma pack(pop) +typedef struct FONScolor FONScolor; + struct FONSparams { int width, height; unsigned char flags; void* userPtr; int (*renderCreate)(void* uptr, int width, int height); int (*renderResize)(void* uptr, int width, int height); - void (*renderUpdate)(void* uptr, int* rect, const unsigned char* data); + void (*renderUpdate)(void* uptr, int* rect, const FONScolor* data); void (*renderDraw)(void* uptr, const float* verts, const float* tcoords, const unsigned int* colors, int nverts); void (*renderDelete)(void* uptr); }; @@ -107,7 +126,9 @@ FONS_DEF int fonsExpandAtlas(FONScontext* s, int width, int height); FONS_DEF int fonsResetAtlas(FONScontext* stash, int width, int height); // Add fonts +#if FONS_OPTIONS_FILE_IO FONS_DEF int fonsAddFont(FONScontext* s, const char* name, const char* path); +#endif FONS_DEF int fonsAddFontMem(FONScontext* s, const char* name, unsigned char* data, int ndata, int freeData); FONS_DEF int fonsGetFontByName(FONScontext* s, const char* name); FONS_DEF int fonsAddFallbackFont(FONScontext* stash, int base, int fallback); @@ -138,7 +159,7 @@ FONS_DEF int fonsTextIterInit(FONScontext* stash, FONStextIter* iter, float x, f FONS_DEF int fonsTextIterNext(FONScontext* stash, FONStextIter* iter, struct FONSquad* quad); // Pull texture changes -FONS_DEF const unsigned char* fonsGetTextureData(FONScontext* stash, int* width, int* height); +FONS_DEF const FONScolor* fonsGetTextureData(FONScontext* stash, int* width, int* height); FONS_DEF int fonsValidateTexture(FONScontext* s, int* dirty); // Draws the stash texture for debugging @@ -153,8 +174,21 @@ FONS_DEF void fonsDrawDebug(FONScontext* s, float x, float y); #ifdef FONTSTASH_IMPLEMENTATION +#if FONS_OPTIONS_FILE_IO && defined(_WIN32) +#include +#endif + #define FONS_NOTUSED(v) (void)sizeof(v) +#if FONS_OPTIONS_RGBA_COLORS +static FONScolor fons__color_clear() {FONScolor r = {0, 0, 0, 0}; return r;} +static FONScolor fons__color_white() {FONScolor r = {0xff, 0xff, 0xff, 0xff}; return r;} +#else +static FONScolor fons__color_clear() {FONScolor r = {0}; return r;} +static FONScolor fons__color_white() {FONScolor r = {0xff}; return r;} +#endif +static FONScolor fons__color_alpha(unsigned char alpha) {FONScolor r = fons__color_white(); r.a = alpha; return r;} + #ifdef FONS_USE_FREETYPE #include @@ -228,7 +262,7 @@ static int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size return 1; } -static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride, +static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, FONScolor *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) { FT_GlyphSlot ftGlyph = font->font->glyph; @@ -242,7 +276,7 @@ static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *outp for ( y = 0; y < ftGlyph->bitmap.rows; y++ ) { for ( x = 0; x < ftGlyph->bitmap.width; x++ ) { - output[(y * outStride) + x] = ftGlyph->bitmap.buffer[ftGlyphOffset++]; + output[(y * outStride) + x] = fons__color_alpha(ftGlyph->bitmap.buffer[ftGlyphOffset++]); } } } @@ -309,10 +343,14 @@ static int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size return 1; } -static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride, +static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, FONScolor *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) { - stbtt_MakeGlyphBitmap(&font->font, output, outWidth, outHeight, outStride, scaleX, scaleY, glyph); + stbtt_MakeGlyphBitmap(&font->font, (unsigned char*)output, outWidth, outHeight, outStride * sizeof(FONScolor), scaleX, scaleY, glyph); + + for(int y = outHeight - 1; y >= 0; y--) + for(int x = outWidth - 1; x >= 0; x--) + output[outStride * y + x] = fons__color_alpha(((unsigned char*)output)[outStride * sizeof(FONScolor) * y + x]); } static int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2) @@ -427,7 +465,7 @@ struct FONScontext { FONSparams params; float itw,ith; - unsigned char* texData; + FONScolor* texData; int dirtyRect[4]; FONSfont** fonts; FONSatlas* atlas; @@ -698,7 +736,7 @@ static int fons__atlasAddRect(FONSatlas* atlas, int rw, int rh, int* rx, int* ry static void fons__addWhiteRect(FONScontext* stash, int w, int h) { int x, y, gx, gy; - unsigned char* dst; + FONScolor* dst; if (fons__atlasAddRect(stash->atlas, w, h, &gx, &gy) == 0) return; @@ -706,7 +744,7 @@ static void fons__addWhiteRect(FONScontext* stash, int w, int h) dst = &stash->texData[gx + gy * stash->params.width]; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) - dst[x] = 0xff; + dst[x] = fons__color_white(); dst += stash->params.width; } @@ -716,6 +754,7 @@ static void fons__addWhiteRect(FONScontext* stash, int w, int h) stash->dirtyRect[3] = fons__maxi(stash->dirtyRect[3], gy+h); } + FONScontext* fonsCreateInternal(FONSparams* params) { FONScontext* stash = NULL; @@ -752,9 +791,9 @@ FONScontext* fonsCreateInternal(FONSparams* params) // Create texture for the cache. stash->itw = 1.0f/stash->params.width; stash->ith = 1.0f/stash->params.height; - stash->texData = (unsigned char*)malloc(stash->params.width * stash->params.height); + stash->texData = (FONScolor*)malloc(stash->params.width * stash->params.height * sizeof(FONScolor)); if (stash->texData == NULL) goto error; - memset(stash->texData, 0, stash->params.width * stash->params.height); + memset(stash->texData, 0, stash->params.width * stash->params.height * sizeof(FONScolor)); stash->dirtyRect[0] = stash->params.width; stash->dirtyRect[1] = stash->params.height; @@ -887,6 +926,8 @@ static int fons__allocFont(FONScontext* stash) return FONS_INVALID; } +#if FONS_OPTIONS_FILE_IO + static FILE* fons__fopen(const char* filename, const char* mode) { #ifdef _WIN32 @@ -943,6 +984,8 @@ int fonsAddFont(FONScontext* stash, const char* name, const char* path) return FONS_INVALID; } +#endif + int fonsAddFontMem(FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData) { int i, ascent, descent, fh, lineGap; @@ -1014,48 +1057,48 @@ static FONSglyph* fons__allocGlyph(FONSfont* font) #define APREC 16 #define ZPREC 7 -static void fons__blurCols(unsigned char* dst, int w, int h, int dstStride, int alpha) +static void fons__blurCols(FONScolor* dst, int w, int h, int dstStride, int alpha) { int x, y; for (y = 0; y < h; y++) { int z = 0; // force zero border for (x = 1; x < w; x++) { - z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC; - dst[x] = (unsigned char)(z >> ZPREC); + z += (alpha * (((int)(dst[x].a) << ZPREC) - z)) >> APREC; + dst[x] = fons__color_alpha((unsigned char)(z >> ZPREC)); } - dst[w-1] = 0; // force zero border + dst[w-1] = fons__color_clear(); // force zero border z = 0; for (x = w-2; x >= 0; x--) { - z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC; - dst[x] = (unsigned char)(z >> ZPREC); + z += (alpha * (((int)(dst[x].a) << ZPREC) - z)) >> APREC; + dst[x] = fons__color_alpha((unsigned char)(z >> ZPREC)); } - dst[0] = 0; // force zero border + dst[0] = fons__color_clear(); // force zero border dst += dstStride; } } -static void fons__blurRows(unsigned char* dst, int w, int h, int dstStride, int alpha) +static void fons__blurRows(FONScolor* dst, int w, int h, int dstStride, int alpha) { int x, y; for (x = 0; x < w; x++) { int z = 0; // force zero border for (y = dstStride; y < h*dstStride; y += dstStride) { - z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC; - dst[y] = (unsigned char)(z >> ZPREC); + z += (alpha * (((int)(dst[y].a) << ZPREC) - z)) >> APREC; + dst[y] = fons__color_alpha((unsigned char)(z >> ZPREC)); } - dst[(h-1)*dstStride] = 0; // force zero border + dst[(h-1)*dstStride] = fons__color_clear(); // force zero border z = 0; for (y = (h-2)*dstStride; y >= 0; y -= dstStride) { - z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC; - dst[y] = (unsigned char)(z >> ZPREC); + z += (alpha * (((int)(dst[y].a) << ZPREC) - z)) >> APREC; + dst[y] = fons__color_alpha((unsigned char)(z >> ZPREC)); } - dst[0] = 0; // force zero border + dst[0] = fons__color_clear(); // force zero border dst++; } } -static void fons__blur(FONScontext* stash, unsigned char* dst, int w, int h, int dstStride, int blur) +static void fons__blur(FONScontext* stash, FONScolor* dst, int w, int h, int dstStride, int blur) { int alpha; float sigma; @@ -1083,8 +1126,8 @@ static FONSglyph* fons__getGlyph(FONScontext* stash, FONSfont* font, unsigned in unsigned int h; float size = isize/10.0f; int pad, added; - unsigned char* bdst; - unsigned char* dst; + FONScolor* bdst; + FONScolor* dst; FONSfont* renderFont = font; if (isize < 2) return NULL; @@ -1159,21 +1202,21 @@ static FONSglyph* fons__getGlyph(FONScontext* stash, FONSfont* font, unsigned in // Make sure there is one pixel empty border. dst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width]; for (y = 0; y < gh; y++) { - dst[y*stash->params.width] = 0; - dst[gw-1 + y*stash->params.width] = 0; + dst[y*stash->params.width] = fons__color_clear(); + dst[gw-1 + y*stash->params.width] = fons__color_clear(); } for (x = 0; x < gw; x++) { - dst[x] = 0; - dst[x + (gh-1)*stash->params.width] = 0; + dst[x] = fons__color_clear(); + dst[x + (gh-1)*stash->params.width] = fons__color_clear(); } // Debug code to color the glyph background -/* unsigned char* fdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width]; +/* FONScolor* fdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width]; for (y = 0; y < gh; y++) { for (x = 0; x < gw; x++) { int a = (int)fdst[x+y*stash->params.width] + 20; if (a > 255) a = 255; - fdst[x+y*stash->params.width] = a; + fdst[x+y*stash->params.width] = fons__color_alpha(a); } }*/ @@ -1606,7 +1649,7 @@ FONS_DEF void fonsLineBounds(FONScontext* stash, float y, float* miny, float* ma } } -FONS_DEF const unsigned char* fonsGetTextureData(FONScontext* stash, int* width, int* height) +FONS_DEF const FONScolor* fonsGetTextureData(FONScontext* stash, int* width, int* height) { if (width != NULL) *width = stash->params.width; @@ -1667,7 +1710,7 @@ FONS_DEF void fonsGetAtlasSize(FONScontext* stash, int* width, int* height) FONS_DEF int fonsExpandAtlas(FONScontext* stash, int width, int height) { int i, maxy = 0; - unsigned char* data = NULL; + FONScolor* data = NULL; if (stash == NULL) return 0; width = fons__maxi(width, stash->params.width); @@ -1685,18 +1728,18 @@ FONS_DEF int fonsExpandAtlas(FONScontext* stash, int width, int height) return 0; } // Copy old texture data over. - data = (unsigned char*)malloc(width * height); + data = (FONScolor*)malloc(width * height * sizeof(FONScolor)); if (data == NULL) return 0; for (i = 0; i < stash->params.height; i++) { - unsigned char* dst = &data[i*width]; - unsigned char* src = &stash->texData[i*stash->params.width]; - memcpy(dst, src, stash->params.width); + FONScolor* dst = &data[i*width]; + FONScolor* src = &stash->texData[i*stash->params.width]; + memcpy(dst, src, stash->params.width * sizeof(FONScolor)); if (width > stash->params.width) - memset(dst+stash->params.width, 0, width - stash->params.width); + memset(dst+stash->params.width, 0, (width - stash->params.width) * sizeof(FONScolor)); } if (height > stash->params.height) - memset(&data[stash->params.height * width], 0, (height - stash->params.height) * width); + memset(&data[stash->params.height * width], 0, (height - stash->params.height) * width * sizeof(FONScolor)); free(stash->texData); stash->texData = data; @@ -1738,9 +1781,9 @@ FONS_DEF int fonsResetAtlas(FONScontext* stash, int width, int height) fons__atlasReset(stash->atlas, width, height); // Clear texture data. - stash->texData = (unsigned char*)realloc(stash->texData, width * height); + stash->texData = (FONScolor*)realloc(stash->texData, width * height * sizeof(FONScolor)); if (stash->texData == NULL) return 0; - memset(stash->texData, 0, width * height); + memset(stash->texData, 0, width * height * sizeof(FONScolor)); // Reset dirty rect stash->dirtyRect[0] = width; diff --git a/src/gl3corefontstash.h b/src/gl3corefontstash.h index 2cd08c7..4da1219 100644 --- a/src/gl3corefontstash.h +++ b/src/gl3corefontstash.h @@ -87,11 +87,15 @@ static int glfons__renderCreate(void* userPtr, int width, int height) gl->width = width; gl->height = height; glBindTexture(GL_TEXTURE_2D, gl->tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, gl->width, gl->height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - static GLint swizzleRgbaParams[4] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams); + #if FONS_OPTIONS_RGBA_COLORS + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gl->width, gl->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + #else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, gl->width, gl->height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + static GLint swizzleRgbaParams[4] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams); + #endif + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); return 1; } @@ -102,7 +106,7 @@ static int glfons__renderResize(void* userPtr, int width, int height) return glfons__renderCreate(userPtr, width, height); } -static void glfons__renderUpdate(void* userPtr, int* rect, const unsigned char* data) +static void glfons__renderUpdate(void* userPtr, int* rect, const FONScolor* data) { GLFONScontext* gl = (GLFONScontext*)userPtr; int w = rect[2] - rect[0]; @@ -124,7 +128,11 @@ static void glfons__renderUpdate(void* userPtr, int* rect, const unsigned char* glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect[0]); glPixelStorei(GL_UNPACK_SKIP_ROWS, rect[1]); - glTexSubImage2D(GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, GL_RED, GL_UNSIGNED_BYTE, data); + #if FONS_OPTIONS_RGBA_COLORS + glTexSubImage2D(GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, GL_RGBA, GL_UNSIGNED_BYTE, data); + #else + glTexSubImage2D(GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, GL_RED, GL_UNSIGNED_BYTE, data); + #endif // Pop old values glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); diff --git a/src/glfontstash.h b/src/glfontstash.h index 072bbb8..e4404e4 100644 --- a/src/glfontstash.h +++ b/src/glfontstash.h @@ -46,7 +46,11 @@ static int glfons__renderCreate(void* userPtr, int width, int height) gl->width = width; gl->height = height; glBindTexture(GL_TEXTURE_2D, gl->tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gl->width, gl->height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); + #if FONS_OPTIONS_RGBA_COLORS + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gl->width, gl->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + #else + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gl->width, gl->height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); + #endif glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); return 1; } @@ -57,7 +61,7 @@ static int glfons__renderResize(void* userPtr, int width, int height) return glfons__renderCreate(userPtr, width, height); } -static void glfons__renderUpdate(void* userPtr, int* rect, const unsigned char* data) +static void glfons__renderUpdate(void* userPtr, int* rect, const FONScolor* data) { GLFONScontext* gl = (GLFONScontext*)userPtr; int w = rect[2] - rect[0]; @@ -66,11 +70,15 @@ static void glfons__renderUpdate(void* userPtr, int* rect, const unsigned char* if (gl->tex == 0) return; glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glBindTexture(GL_TEXTURE_2D, gl->tex); - glPixelStorei(GL_UNPACK_ALIGNMENT,1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->width); glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect[0]); glPixelStorei(GL_UNPACK_SKIP_ROWS, rect[1]); - glTexSubImage2D(GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, GL_ALPHA,GL_UNSIGNED_BYTE, data); + #if FONS_OPTIONS_RGBA_COLORS + glTexSubImage2D(GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, GL_RGBA, GL_UNSIGNED_BYTE, data); + #else + glTexSubImage2D(GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, GL_ALPHA, GL_UNSIGNED_BYTE, data); + #endif glPopClientAttrib(); } From ef190b2430eb6f78f7a0b314946069020729b846 Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Sun, 10 Jun 2018 18:44:50 +0200 Subject: [PATCH 2/4] add coin sprites --- example/coin/coin.bmp | Bin 0 -> 18486 bytes example/coin/readme.txt | 1 + 2 files changed, 1 insertion(+) create mode 100644 example/coin/coin.bmp create mode 100644 example/coin/readme.txt diff --git a/example/coin/coin.bmp b/example/coin/coin.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4d3d97332820dc3f2e675520ed43e14b1a0ad4e5 GIT binary patch literal 18486 zcmeH}L2eU45Jkh99Y}~JOHPmjuwuiKvv4pjfW(#ya1IU-2EHsk`TN&Y_jpWhAZee^s1(`1JVk;qTYu@_fI%zb)@~%lpN{+vT}@E$gpe>aE1X!&CWn+Eslo0V|6Y z_q4WxXe^&d=ieJgTU*Y#r=MGg8=FqN^Y4wLD_hQqmwsMBl*^ZR=eZKFvUtwA^z#a$ zv3!a8C)YUI+H$}AR5|l43$Tf2KYf2%eQ`f9E1^!+@K>L|E-&p|!G&d45pz44f>OB+ zS&qH=@^g7@cSbeWT^Lo-em!flR=J<9)^Ufwz00n0n=VVYcA&E=4r_kS^W$#+`1Q2< z;*52Cqe=}IdCL^J7JJdDcCO3&kw@M3`c<2J5UtaN&W*H(71m^}a{s7G%@_HYAI|)! z+qan?pB&a%$Nec9RUvuwFMiSzQ?ya0_d*$I?afpdsG^M2Q*F$%&bp^uWfzi`@;ud# z$=9iCsgOL{>vW@Ie&pm_e>Ag`}lC35xk-7hIRUo>L*;E7xiwAM@i5ct-BAcZ}J6=IhROCWi#7aJszX>~*a| zJ}Y;oR!Mf3lu3%x5~oi~D%9GWDL3Xmf8>TL6o+y0S$SWj|Hp&N8KO?aIb zflN8P$LEiCnYxPkTg=;~`Qd(5o}N_asal0QYch9Ai{#XW`d;*>LrW^ki?BD7^Fz-& z^|L~8M4-3*E>KZ1nTk8)`c$pb;rktxAvtxnzLz+CT2eXYr}jC`B=hQmPaV7LDz~2> zDe8I5j~tlmLfu)P1Wt>`$Nb38y=PL+>;E5m&Tgj9NmeM%ZRUr+vpzXKz0B}lioNp0 zCx@{JB-f55Mc$=DODg>PwKr3I&CjS7{nuH}&uACu7|EP!GQESU!Sl@2Dm9-R#?mD@ zb=L1i#Zmv0$}vCgGrdi7!b#(P_L^O;Rd~wDT$L8dsk2FOj+RvZ)%?(~#ZaZf~JuaiIQLh_0ZkjdFdeC|;^s*=d8ye6}o?v-woR8qChOc}a2 zT4$dr^7Ee`)#+2DeCL@uLZ9dOiR@i)t^a9$=-!+sb6rkabbF4>x$3CU0iLbnL_X%n z9q`QdF4z7izIvUW?0C)Bji{2CK3yGh?bx-LwTj%BtF}WHUw4^Pq5q_%Ui5D?N}lTo zRZ`7!95++s^R}y%L!n*Q%eYGtTUEp|7Q#uEP2mbAMeqS4a6g+mCA%t@deY zr>pEocIQ)7b>3?xnepgdw11R8r@}f@JW8f-^)0rLYnA=TbZLu9?aXymq?Mj@ax_j% z=0};npESn4b1p+B<2jn2B9pQ29L# F`3>nE><<6{ literal 0 HcmV?d00001 diff --git a/example/coin/readme.txt b/example/coin/readme.txt new file mode 100644 index 0000000..94b58e4 --- /dev/null +++ b/example/coin/readme.txt @@ -0,0 +1 @@ +from https://www.tutpad.com/tutorials/how-to-create-an-animated-pixel-art-coin \ No newline at end of file From 5f9e1d186d31aa3ba0d2d3f170d6b2801a51cd2a Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Sun, 10 Jun 2018 19:20:57 +0200 Subject: [PATCH 3/4] add ability to provide custom font engines --- example/example.c | 143 ++++++++++++++++++++++++++++++++++-- src/fontstash.h | 180 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 266 insertions(+), 57 deletions(-) diff --git a/example/example.c b/example/example.c index b902ab2..c0595d2 100644 --- a/example/example.c +++ b/example/example.c @@ -57,28 +57,139 @@ static void key(GLFWwindow* window, int key, int scancode, int action, int mods) debug = !debug; } +int code_to_utf8(unsigned char* buffer, unsigned int code) // https://stackoverflow.com/questions/42012563/convert-unicode-code-points-to-utf-8-and-utf-32 +{ + if (code <= 0x7F) { + buffer[0] = code; + return 1; + } else if (code <= 0x7FF) { + buffer[0] = 0xC0 | (code >> 6); /* 110xxxxx */ + buffer[1] = 0x80 | (code & 0x3F); /* 10xxxxxx */ + return 2; + } else if (code <= 0xFFFF) { + buffer[0] = 0xE0 | (code >> 12); /* 1110xxxx */ + buffer[1] = 0x80 | ((code >> 6) & 0x3F); /* 10xxxxxx */ + buffer[2] = 0x80 | (code & 0x3F); /* 10xxxxxx */ + return 3; + } else if (code <= 0x10FFFF) { + buffer[0] = 0xF0 | (code >> 18); /* 11110xxx */ + buffer[1] = 0x80 | ((code >> 12) & 0x3F); /* 10xxxxxx */ + buffer[2] = 0x80 | ((code >> 6) & 0x3F); /* 10xxxxxx */ + buffer[3] = 0x80 | (code & 0x3F); /* 10xxxxxx */ + return 4; + } + return 0; +} + +#pragma pack(push, 2) +typedef struct +{ + unsigned char magic[2]; + unsigned int size; + unsigned short _r1, _r2; + unsigned int offset; +} bmp_header_t; +#pragma pack(pop) + +#define BITMAP_FRAME_W 32 +#define BITMAP_FRAME_H 32 +#define BITMAP_FRAMES 6 + +void* bitmap_loadFont(FONScontext *context, unsigned char *data, int dataSize) +{ + // this is super crude bmp "parsing" + // will only work with "raw" 24 bit bmps + void *pixel_data_rgb = malloc(BITMAP_FRAME_W * BITMAP_FRAME_H * BITMAP_FRAMES * 3); + memcpy(pixel_data_rgb, data + ((bmp_header_t*)data)->offset, BITMAP_FRAME_W * BITMAP_FRAME_H * BITMAP_FRAMES * 3); + return pixel_data_rgb; +} +void bitmap_freeFont(void *usrdata) +{ + if (usrdata) + free(usrdata); +} +void bitmap_getFontVMetrics(void *usrdata, int *ascent, int *descent, int *lineGap) +{ + *ascent = BITMAP_FRAME_H - 5; + *descent = -5; + *lineGap = 1; +} +float bitmap_getPixelHeightScale(void *usrdata, float size) +{ + return BITMAP_FRAME_H; +} +int bitmap_getGlyphIndex(void *usrdata, int codepoint) +{ + if(codepoint >= 0xf0000 + 0 && codepoint < 0xf0000 + BITMAP_FRAMES) + return codepoint - 0xf0000 + 1; + else + return 0; +} +int bitmap_buildGlyphBitmap(void *usrdata, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1) +{ + *advance = 1; + *lsb = 0; + *x0 = 0; + *y0 = -BITMAP_FRAME_H + 5; + *x1 = BITMAP_FRAME_W; + *y1 = 5; + return 1; +} +void bitmap_renderGlyphBitmap(void *usrdata, FONScolor *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) +{ + for(int y = 0; y < outHeight; ++y) + { + for(int x = 0; x < outWidth; ++x) + { + int pos = (BITMAP_FRAME_W * BITMAP_FRAMES * y + x + (glyph - 1) * BITMAP_FRAME_W) * 3; + unsigned char b = ((unsigned char*)usrdata)[pos + 0]; + unsigned char g = ((unsigned char*)usrdata)[pos + 1]; + unsigned char r = ((unsigned char*)usrdata)[pos + 2]; + #if FONS_OPTIONS_RGBA_COLORS + output[y * outStride + x].r = r; + output[y * outStride + x].g = g; + output[y * outStride + x].b = b; + #endif + output[y * outStride + x].a = (r == 0xff && g == 0xff && b == 0xff) ? 0x00 : 0xff; + } + } +} +int bitmap_getGlyphKernAdvance(void *usrdata, int glyph1, int glyph2) {return 0;} + +FONSfontEngine simple_bitmap_engine = { + bitmap_loadFont, + bitmap_freeFont, + bitmap_getFontVMetrics, + bitmap_getPixelHeightScale, + bitmap_getGlyphIndex, + bitmap_buildGlyphBitmap, + bitmap_renderGlyphBitmap, + bitmap_getGlyphKernAdvance +}; + int main() { int fontNormal = FONS_INVALID; int fontItalic = FONS_INVALID; int fontBold = FONS_INVALID; int fontJapanese = FONS_INVALID; + int fontBitmap = FONS_INVALID; GLFWwindow* window; const GLFWvidmode* mode; - + FONScontext* fs = NULL; if (!glfwInit()) return -1; mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Font Stash", NULL, NULL); + window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Font Stash", NULL, NULL); if (!window) { glfwTerminate(); return -1; } - glfwSetKeyCallback(window, key); + glfwSetKeyCallback(window, key); glfwMakeContextCurrent(window); fs = glfonsCreate(512, 512, FONS_ZERO_TOPLEFT); @@ -107,7 +218,14 @@ int main() printf("Could not add font japanese.\n"); return -1; } + fontBitmap = fonsAddFontWithEngine(fs, "bitmap", "../example/coin/coin.bmp", &simple_bitmap_engine); + if (fontBitmap == FONS_INVALID) { + printf("Could not add bitmap font.\n"); + return -1; + } + fonsAddFallbackFont(fs, fontNormal, fontBitmap); + int sprite_frame = 0; while (!glfwWindowShouldClose(window)) { float sx, sy, dx, dy, lh = 0; @@ -139,7 +257,7 @@ int main() black = glfonsRGBA(0,0,0,255); sx = 50; sy = 50; - + dx = sx; dy = sy; dash(dx,dy); @@ -152,7 +270,7 @@ int main() dx = sx; dy += lh; dash(dx,dy); - + fonsSetSize(fs, 124.0f); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); @@ -257,6 +375,21 @@ int main() fonsSetBlur(fs, 0); fonsDrawText(fs, dx,dy,"DROP THAT SHADOW",NULL); + // bitmap + dx = 50; dy = 550; + char temp[32], temp2[5] = {0}; + code_to_utf8((unsigned char*)temp2, 0xf0000 + (sprite_frame / 10) % 6); + snprintf(temp, sizeof(temp), "hello sprite <%s> world!", temp2); + sprite_frame++; + + fonsSetSize(fs, 32.0f); + fonsSetFont(fs, fontNormal); + fonsSetColor(fs, black); + fonsDrawText(fs, dx+4,dy+4,temp, NULL); + + fonsSetColor(fs, white); + dx = fonsDrawText(fs, dx,dy,temp, NULL); + if (debug) fonsDrawDebug(fs, 800.0, 50.0); diff --git a/src/fontstash.h b/src/fontstash.h index e8b7988..2e4b6e6 100644 --- a/src/fontstash.h +++ b/src/fontstash.h @@ -113,6 +113,18 @@ typedef struct FONStextIter FONStextIter; typedef struct FONScontext FONScontext; +struct FONSfontEngine { + void* (*loadFont)(FONScontext *context, unsigned char *data, int dataSize); // returns userdata or NULL + void (*freeFont)(void *usrdata); + void (*getFontVMetrics)(void *usrdata, int *ascent, int *descent, int *lineGap); + float (*getPixelHeightScale)(void *usrdata, float size); + int (*getGlyphIndex)(void *usrdata, int codepoint); + int (*buildGlyphBitmap)(void *usrdata, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1); + void (*renderGlyphBitmap)(void *usrdata, FONScolor *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph); + int (*getGlyphKernAdvance)(void *usrdata, int glyph1, int glyph2); +}; +typedef struct FONSfontEngine FONSfontEngine; + // Contructor and destructor. FONS_DEF FONScontext* fonsCreateInternal(FONSparams* params); FONS_DEF void fonsDeleteInternal(FONScontext* s); @@ -128,8 +140,10 @@ FONS_DEF int fonsResetAtlas(FONScontext* stash, int width, int height); // Add fonts #if FONS_OPTIONS_FILE_IO FONS_DEF int fonsAddFont(FONScontext* s, const char* name, const char* path); +FONS_DEF int fonsAddFontWithEngine(FONScontext* s, const char* name, const char* path, FONSfontEngine* engine); #endif FONS_DEF int fonsAddFontMem(FONScontext* s, const char* name, unsigned char* data, int ndata, int freeData); +FONS_DEF int fonsAddFontMemWithEngine(FONScontext* s, const char* name, unsigned char* data, int ndata, int freeData, FONSfontEngine* engine); FONS_DEF int fonsGetFontByName(FONScontext* s, const char* name); FONS_DEF int fonsAddFallbackFont(FONScontext* stash, int base, int fallback); @@ -202,48 +216,65 @@ struct FONSttFontImpl { typedef struct FONSttFontImpl FONSttFontImpl; static FT_Library ftLibrary; +static bool ftLibrary_init = false; -static int fons__tt_init() +static void *fons__tt_loadFont(FONScontext *context, unsigned char *data, int dataSize) { FT_Error ftError; FONS_NOTUSED(context); - ftError = FT_Init_FreeType(&ftLibrary); - return ftError == 0; -} -static int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize) -{ - FT_Error ftError; - FONS_NOTUSED(context); + if(!ftLibrary_init) { + ftError = FT_Init_FreeType(&ftLibrary); + if (ftError == 0) { + ftLibrary_init = true; + } else { + return NULL; + } + } - //font->font.userdata = stash; + FONSttFontImpl *font = (FONSttFontImpl*)malloc(sizeof(FONSttFontImpl)); ftError = FT_New_Memory_Face(ftLibrary, (const FT_Byte*)data, dataSize, 0, &font->font); - return ftError == 0; + if (ftError == 0) { + return font; + } else { + free(font); + return NULL; + } +} + +static void fons__tt_freeFont(void *usrdata) +{ + if (usrdata) + free(usrdata); } -static void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap) +static void fons__tt_getFontVMetrics(void *usrdata, int *ascent, int *descent, int *lineGap) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; *ascent = font->font->ascender; *descent = font->font->descender; *lineGap = font->font->height - (*ascent - *descent); } -static float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size) +static float fons__tt_getPixelHeightScale(void *usrdata, float size) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; return size / (font->font->ascender - font->font->descender); } -static int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint) +static int fons__tt_getGlyphIndex(void *usrdata, int codepoint) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; return FT_Get_Char_Index(font->font, codepoint); } -static int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale, +static int fons__tt_buildGlyphBitmap(void *usrdata, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1) { FT_Error ftError; FT_GlyphSlot ftGlyph; FT_Fixed advFixed; + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; 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))); @@ -262,12 +293,13 @@ static int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size return 1; } -static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, FONScolor *output, int outWidth, int outHeight, int outStride, +static void fons__tt_renderGlyphBitmap(void *usrdata, FONScolor *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) { FT_GlyphSlot ftGlyph = font->font->glyph; int ftGlyphOffset = 0; int x, y; + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; FONS_NOTUSED(outWidth); FONS_NOTUSED(outHeight); FONS_NOTUSED(scaleX); @@ -281,9 +313,10 @@ static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, FONScolor *output, } } -static int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2) +static int fons__tt_getGlyphKernAdvance(void *usrdata, int glyph1, int glyph2) { FT_Vector ftKerning; + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; FT_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning); return (int)((ftKerning.x + 32) >> 6); // Round up and convert to integer } @@ -303,63 +336,90 @@ struct FONSttFontImpl { }; typedef struct FONSttFontImpl FONSttFontImpl; -static int fons__tt_init(FONScontext *context) +static void *fons__tt_loadFont(FONScontext *context, unsigned char *data, int dataSize) { - FONS_NOTUSED(context); - return 1; -} - -static int fons__tt_loadFont(FONScontext *context, FONSttFontImpl *font, unsigned char *data, int dataSize) -{ - int stbError; FONS_NOTUSED(dataSize); + FONSttFontImpl *font = (FONSttFontImpl*)malloc(sizeof(FONSttFontImpl)); font->font.userdata = context; - stbError = stbtt_InitFont(&font->font, data, 0); - return stbError; + if (stbtt_InitFont(&font->font, data, 0)) { + return font; + } else { + free(font); + return NULL; + } +} + +static void fons__tt_freeFont(void *usrdata) +{ + if (usrdata) + free(usrdata); } -static void fons__tt_getFontVMetrics(FONSttFontImpl *font, int *ascent, int *descent, int *lineGap) +static void fons__tt_getFontVMetrics(void *usrdata, int *ascent, int *descent, int *lineGap) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; stbtt_GetFontVMetrics(&font->font, ascent, descent, lineGap); } -static float fons__tt_getPixelHeightScale(FONSttFontImpl *font, float size) +static float fons__tt_getPixelHeightScale(void *usrdata, float size) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; return stbtt_ScaleForPixelHeight(&font->font, size); } -static int fons__tt_getGlyphIndex(FONSttFontImpl *font, int codepoint) +static int fons__tt_getGlyphIndex(void *usrdata, int codepoint) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; return stbtt_FindGlyphIndex(&font->font, codepoint); } -static int fons__tt_buildGlyphBitmap(FONSttFontImpl *font, int glyph, float size, float scale, +static int fons__tt_buildGlyphBitmap(void *usrdata, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; FONS_NOTUSED(size); stbtt_GetGlyphHMetrics(&font->font, glyph, advance, lsb); stbtt_GetGlyphBitmapBox(&font->font, glyph, scale, scale, x0, y0, x1, y1); return 1; } -static void fons__tt_renderGlyphBitmap(FONSttFontImpl *font, FONScolor *output, int outWidth, int outHeight, int outStride, +static void fons__tt_renderGlyphBitmap(void *usrdata, FONScolor *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; stbtt_MakeGlyphBitmap(&font->font, (unsigned char*)output, outWidth, outHeight, outStride * sizeof(FONScolor), scaleX, scaleY, glyph); - for(int y = outHeight - 1; y >= 0; y--) - for(int x = outWidth - 1; x >= 0; x--) - output[outStride * y + x] = fons__color_alpha(((unsigned char*)output)[outStride * sizeof(FONScolor) * y + x]); + // for rgba, do Alpha -> RGBA conversion in-place + #if FONS_OPTIONS_RGBA_COLORS + for(int y = outHeight - 1; y >= 0; y--) + for(int x = outWidth - 1; x >= 0; x--) + output[outStride * y + x] = fons__color_alpha(((unsigned char*)output)[outStride * sizeof(FONScolor) * y + x]); + #endif } -static int fons__tt_getGlyphKernAdvance(FONSttFontImpl *font, int glyph1, int glyph2) +static int fons__tt_getGlyphKernAdvance(void *usrdata, int glyph1, int glyph2) { + FONSttFontImpl *font = (FONSttFontImpl*)usrdata; return stbtt_GetGlyphKernAdvance(&font->font, glyph1, glyph2); } #endif +static FONSfontEngine *fons__tt_getEngine() { + static FONSfontEngine e = { + fons__tt_loadFont, + fons__tt_freeFont, + fons__tt_getFontVMetrics, + fons__tt_getPixelHeightScale, + fons__tt_getGlyphIndex, + fons__tt_buildGlyphBitmap, + fons__tt_renderGlyphBitmap, + fons__tt_getGlyphKernAdvance, + }; + return &e; +} + #ifndef FONS_SCRATCH_BUF_SIZE # define FONS_SCRATCH_BUF_SIZE 64000 #endif @@ -419,7 +479,8 @@ typedef struct FONSglyph FONSglyph; struct FONSfont { - FONSttFontImpl font; + FONSfontEngine* e; + void* edata; char name[64]; unsigned char* data; int dataSize; @@ -770,9 +831,6 @@ FONScontext* fonsCreateInternal(FONSparams* params) stash->scratch = (unsigned char*)malloc(FONS_SCRATCH_BUF_SIZE); if (stash->scratch == NULL) goto error; - // Initialize implementation library - if (!fons__tt_init(stash)) goto error; - if (stash->params.renderCreate != NULL) { if (stash->params.renderCreate(stash->params.userPtr, stash->params.width, stash->params.height) == 0) goto error; @@ -894,6 +952,7 @@ void fonsClearState(FONScontext* stash) static void fons__freeFont(FONSfont* font) { if (font == NULL) return; + if (font->e && font->edata) font->e->freeFont(font->edata); if (font->glyphs) free(font->glyphs); if (font->freeData && font->data) free(font->data); free(font); @@ -958,6 +1017,11 @@ static FILE* fons__fopen(const char* filename, const char* mode) } int fonsAddFont(FONScontext* stash, const char* name, const char* path) +{ + return fonsAddFontWithEngine(stash, name, path, fons__tt_getEngine()); +} + +int fonsAddFontWithEngine(FONScontext* stash, const char* name, const char* path, FONSfontEngine* engine) { FILE* fp = 0; int dataSize = 0, readed; @@ -976,7 +1040,7 @@ int fonsAddFont(FONScontext* stash, const char* name, const char* path) fp = 0; if (readed != dataSize) goto error; - return fonsAddFontMem(stash, name, data, dataSize, 1); + return fonsAddFontMemWithEngine(stash, name, data, dataSize, 1, engine); error: if (data) free(data); @@ -986,16 +1050,26 @@ int fonsAddFont(FONScontext* stash, const char* name, const char* path) #endif + int fonsAddFontMem(FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData) +{ + return fonsAddFontMemWithEngine(stash, name, data, dataSize, freeData, fons__tt_getEngine()); +} + + +int fonsAddFontMemWithEngine(FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData, FONSfontEngine* engine) { int i, ascent, descent, fh, lineGap; - FONSfont* font; + FONSfont* font = NULL; + + if (!engine) goto error; int idx = fons__allocFont(stash); if (idx == FONS_INVALID) return FONS_INVALID; font = stash->fonts[idx]; + font->e = engine; strncpy(font->name, name, sizeof(font->name)); font->name[sizeof(font->name)-1] = '\0'; @@ -1011,11 +1085,12 @@ int fonsAddFontMem(FONScontext* stash, const char* name, unsigned char* data, in // Init font stash->nscratch = 0; - if (!fons__tt_loadFont(stash, &font->font, data, dataSize)) goto error; + font->edata = font->e->loadFont(stash, data, dataSize); + if (!font->edata) goto error; // Store normalized line height. The real line height is got // by multiplying the lineh by font size. - fons__tt_getFontVMetrics( &font->font, &ascent, &descent, &lineGap); + font->e->getFontVMetrics(font->edata, &ascent, &descent, &lineGap); fh = ascent - descent; font->ascender = (float)ascent / (float)fh; font->descender = (float)descent / (float)fh; @@ -1029,6 +1104,7 @@ int fonsAddFontMem(FONScontext* stash, const char* name, unsigned char* data, in return FONS_INVALID; } + int fonsGetFontByName(FONScontext* s, const char* name) { int i; @@ -1147,12 +1223,12 @@ static FONSglyph* fons__getGlyph(FONScontext* stash, FONSfont* font, unsigned in } // Could not find glyph, create it. - g = fons__tt_getGlyphIndex(&font->font, codepoint); + g = font->e->getGlyphIndex(font->edata, codepoint); // Try to find the glyph in fallback fonts. if (g == 0) { for (i = 0; i < font->nfallbacks; ++i) { FONSfont* fallbackFont = stash->fonts[font->fallbacks[i]]; - int fallbackIndex = fons__tt_getGlyphIndex(&fallbackFont->font, codepoint); + int fallbackIndex = fallbackFont->e->getGlyphIndex(fallbackFont->edata, codepoint); if (fallbackIndex != 0) { g = fallbackIndex; renderFont = fallbackFont; @@ -1162,8 +1238,8 @@ static FONSglyph* fons__getGlyph(FONScontext* stash, FONSfont* font, unsigned in // It is possible that we did not find a fallback glyph. // In that case the glyph index 'g' is 0, and we'll proceed below and cache empty glyph. } - scale = fons__tt_getPixelHeightScale(&renderFont->font, size); - fons__tt_buildGlyphBitmap(&renderFont->font, g, size, scale, &advance, &lsb, &x0, &y0, &x1, &y1); + scale = renderFont->e->getPixelHeightScale(renderFont->edata, size); + renderFont->e->buildGlyphBitmap(renderFont->edata, g, size, scale, &advance, &lsb, &x0, &y0, &x1, &y1); gw = x1-x0 + pad*2; gh = y1-y0 + pad*2; @@ -1197,7 +1273,7 @@ static FONSglyph* fons__getGlyph(FONScontext* stash, FONSfont* font, unsigned in // Rasterize dst = &stash->texData[(glyph->x0+pad) + (glyph->y0+pad) * stash->params.width]; - fons__tt_renderGlyphBitmap(&renderFont->font, dst, gw-pad*2,gh-pad*2, stash->params.width, scale,scale, g); + renderFont->e->renderGlyphBitmap(renderFont->edata, dst, gw-pad*2,gh-pad*2, stash->params.width, scale,scale, g); // Make sure there is one pixel empty border. dst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width]; @@ -1242,7 +1318,7 @@ static void fons__getQuad(FONScontext* stash, FONSfont* font, float rx,ry,xoff,yoff,x0,y0,x1,y1; if (prevGlyphIndex != -1) { - float adv = fons__tt_getGlyphKernAdvance(&font->font, prevGlyphIndex, glyph->index) * scale; + float adv = font->e->getGlyphKernAdvance(font->edata, prevGlyphIndex, glyph->index) * scale; *x += (int)(adv + spacing + 0.5f); } @@ -1365,7 +1441,7 @@ FONS_DEF float fonsDrawText(FONScontext* stash, font = stash->fonts[state->font]; if (font->data == NULL) return x; - scale = fons__tt_getPixelHeightScale(&font->font, (float)isize/10.0f); + scale = font->e->getPixelHeightScale(font->edata, (float)isize/10.0f); if (end == NULL) end = str + strlen(str); @@ -1423,7 +1499,7 @@ FONS_DEF int fonsTextIterInit(FONScontext* stash, FONStextIter* iter, iter->isize = (short)(state->size*10.0f); iter->iblur = (short)state->blur; - iter->scale = fons__tt_getPixelHeightScale(&iter->font->font, (float)iter->isize/10.0f); + iter->scale = iter->font->e->getPixelHeightScale(iter->font->edata, (float)iter->isize/10.0f); // Align horizontally if (state->align & FONS_ALIGN_LEFT) { @@ -1551,7 +1627,7 @@ FONS_DEF float fonsTextBounds(FONScontext* stash, font = stash->fonts[state->font]; if (font->data == NULL) return 0; - scale = fons__tt_getPixelHeightScale(&font->font, (float)isize/10.0f); + scale = font->e->getPixelHeightScale(font->edata, (float)isize/10.0f); // Align vertically. y += fons__getVertAlign(stash, font, state->align, isize); From 6682a9c0fd1a89c48dc6b7ba4b180cc046ff310e Mon Sep 17 00:00:00 2001 From: Dmytro Ivanov Date: Sun, 10 Jun 2018 21:14:02 +0200 Subject: [PATCH 4/4] remote gitignore stuff --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index 1373142..70f534e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,3 @@ build/* ## xcode specific *xcuserdata* -src/lib-vc2015/glfw3dll.lib -src/GLFW/glfw3native.h -src/GLFW/glfw3.h -src/lib-vc2015/glfw3.lib