aboutsummaryrefslogtreecommitdiff
path: root/third-party/fontstash/glfontstash.h
diff options
context:
space:
mode:
authorspl3g <spleefer6@yandex.ru>2025-11-09 20:43:50 +0300
committerspl3g <spleefer6@yandex.ru>2025-11-09 20:43:50 +0300
commitfc326115fa154bc19f3f10d7c2c4e57710ef1e0d (patch)
tree53ea067805d79d578a258fb0c347aa1525ab2dc2 /third-party/fontstash/glfontstash.h
parent11e5f50717af85f775491a5d2a2867a7e0f9c45f (diff)
Move to sokol (broke the wave screen)
Diffstat (limited to 'third-party/fontstash/glfontstash.h')
-rw-r--r--third-party/fontstash/glfontstash.h146
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(&params, 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(&params);
+
+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