diff options
| author | spl3g <spleefer6@yandex.ru> | 2025-11-09 20:43:50 +0300 |
|---|---|---|
| committer | spl3g <spleefer6@yandex.ru> | 2025-11-09 20:43:50 +0300 |
| commit | fc326115fa154bc19f3f10d7c2c4e57710ef1e0d (patch) | |
| tree | 53ea067805d79d578a258fb0c347aa1525ab2dc2 /third-party/fontstash/glfontstash.h | |
| parent | 11e5f50717af85f775491a5d2a2867a7e0f9c45f (diff) | |
Move to sokol (broke the wave screen)
Diffstat (limited to 'third-party/fontstash/glfontstash.h')
| -rw-r--r-- | third-party/fontstash/glfontstash.h | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/third-party/fontstash/glfontstash.h b/third-party/fontstash/glfontstash.h new file mode 100644 index 0000000..072bbb8 --- /dev/null +++ b/third-party/fontstash/glfontstash.h @@ -0,0 +1,146 @@ +// +// Copyright (c) 2009-2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +#ifndef GLFONTSTASH_H +#define GLFONTSTASH_H + +FONScontext* glfonsCreate(int width, int height, int flags); +void glfonsDelete(FONScontext* ctx); + +unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +#endif + +#ifdef GLFONTSTASH_IMPLEMENTATION + +struct GLFONScontext { + GLuint tex; + int width, height; +}; +typedef struct GLFONScontext GLFONScontext; + +static int glfons__renderCreate(void* userPtr, int width, int height) +{ + GLFONScontext* gl = (GLFONScontext*)userPtr; + // Create may be called multiple times, delete existing texture. + if (gl->tex != 0) { + glDeleteTextures(1, &gl->tex); + gl->tex = 0; + } + glGenTextures(1, &gl->tex); + if (!gl->tex) return 0; + 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); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + return 1; +} + +static int glfons__renderResize(void* userPtr, int width, int height) +{ + // Reuse create to resize too. + return glfons__renderCreate(userPtr, width, height); +} + +static void glfons__renderUpdate(void* userPtr, int* rect, const unsigned char* data) +{ + GLFONScontext* gl = (GLFONScontext*)userPtr; + int w = rect[2] - rect[0]; + int h = rect[3] - rect[1]; + + 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_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); + glPopClientAttrib(); +} + +static void glfons__renderDraw(void* userPtr, const float* verts, const float* tcoords, const unsigned int* colors, int nverts) +{ + GLFONScontext* gl = (GLFONScontext*)userPtr; + if (gl->tex == 0) return; + glBindTexture(GL_TEXTURE_2D, gl->tex); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(float)*2, verts); + glTexCoordPointer(2, GL_FLOAT, sizeof(float)*2, tcoords); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(unsigned int), colors); + + glDrawArrays(GL_TRIANGLES, 0, nverts); + + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); +} + +static void glfons__renderDelete(void* userPtr) +{ + GLFONScontext* gl = (GLFONScontext*)userPtr; + if (gl->tex != 0) + glDeleteTextures(1, &gl->tex); + gl->tex = 0; + free(gl); +} + + +FONScontext* glfonsCreate(int width, int height, int flags) +{ + FONSparams params; + GLFONScontext* gl; + + gl = (GLFONScontext*)malloc(sizeof(GLFONScontext)); + if (gl == NULL) goto error; + memset(gl, 0, sizeof(GLFONScontext)); + + memset(¶ms, 0, sizeof(params)); + params.width = width; + params.height = height; + params.flags = (unsigned char)flags; + params.renderCreate = glfons__renderCreate; + params.renderResize = glfons__renderResize; + params.renderUpdate = glfons__renderUpdate; + params.renderDraw = glfons__renderDraw; + params.renderDelete = glfons__renderDelete; + params.userPtr = gl; + + return fonsCreateInternal(¶ms); + +error: + if (gl != NULL) free(gl); + return NULL; +} + +void glfonsDelete(FONScontext* ctx) +{ + fonsDeleteInternal(ctx); +} + +unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + return (r) | (g << 8) | (b << 16) | (a << 24); +} + +#endif |
