/* =========================================================================== IceTech GPL Source Code Copyright (C) 2026 Justin Marshall This file is part of the IceTech GPL Source Code. =========================================================================== */ #ifndef __RADIANTGLTEXT_H__ #define __RADIANTGLTEXT_H__ static ID_INLINE const unsigned char* RadiantGLText_GlyphRows(char c) { static const unsigned char glyphBlank[7] = { 0, 0, 0, 0, 0, 0, 0 }; static const unsigned char glyph0[7] = { 14, 17, 19, 21, 25, 17, 14 }; static const unsigned char glyph1[7] = { 4, 12, 4, 4, 4, 4, 14 }; static const unsigned char glyph2[7] = { 14, 17, 1, 2, 4, 8, 31 }; static const unsigned char glyph3[7] = { 30, 1, 1, 14, 1, 1, 30 }; static const unsigned char glyph4[7] = { 2, 6, 10, 18, 31, 2, 2 }; static const unsigned char glyph5[7] = { 31, 16, 16, 30, 1, 1, 30 }; static const unsigned char glyph6[7] = { 14, 16, 16, 30, 17, 17, 14 }; static const unsigned char glyph7[7] = { 31, 1, 2, 4, 8, 8, 8 }; static const unsigned char glyph8[7] = { 14, 17, 17, 14, 17, 17, 14 }; static const unsigned char glyph9[7] = { 14, 17, 17, 15, 1, 1, 14 }; static const unsigned char glyphA[7] = { 14, 17, 17, 31, 17, 17, 17 }; static const unsigned char glyphB[7] = { 30, 17, 17, 30, 17, 17, 30 }; static const unsigned char glyphC[7] = { 14, 17, 16, 16, 16, 17, 14 }; static const unsigned char glyphD[7] = { 30, 17, 17, 17, 17, 17, 30 }; static const unsigned char glyphE[7] = { 31, 16, 16, 30, 16, 16, 31 }; static const unsigned char glyphF[7] = { 31, 16, 16, 30, 16, 16, 16 }; static const unsigned char glyphG[7] = { 14, 17, 16, 23, 17, 17, 14 }; static const unsigned char glyphH[7] = { 17, 17, 17, 31, 17, 17, 17 }; static const unsigned char glyphI[7] = { 14, 4, 4, 4, 4, 4, 14 }; static const unsigned char glyphJ[7] = { 7, 2, 2, 2, 18, 18, 12 }; static const unsigned char glyphK[7] = { 17, 18, 20, 24, 20, 18, 17 }; static const unsigned char glyphL[7] = { 16, 16, 16, 16, 16, 16, 31 }; static const unsigned char glyphM[7] = { 17, 27, 21, 21, 17, 17, 17 }; static const unsigned char glyphN[7] = { 17, 25, 21, 19, 17, 17, 17 }; static const unsigned char glyphO[7] = { 14, 17, 17, 17, 17, 17, 14 }; static const unsigned char glyphP[7] = { 30, 17, 17, 30, 16, 16, 16 }; static const unsigned char glyphQ[7] = { 14, 17, 17, 17, 21, 18, 13 }; static const unsigned char glyphR[7] = { 30, 17, 17, 30, 20, 18, 17 }; static const unsigned char glyphS[7] = { 15, 16, 16, 14, 1, 1, 30 }; static const unsigned char glyphT[7] = { 31, 4, 4, 4, 4, 4, 4 }; static const unsigned char glyphU[7] = { 17, 17, 17, 17, 17, 17, 14 }; static const unsigned char glyphV[7] = { 17, 17, 17, 17, 17, 10, 4 }; static const unsigned char glyphW[7] = { 17, 17, 17, 21, 21, 21, 10 }; static const unsigned char glyphX[7] = { 17, 17, 10, 4, 10, 17, 17 }; static const unsigned char glyphY[7] = { 17, 17, 10, 4, 4, 4, 4 }; static const unsigned char glyphZ[7] = { 31, 1, 2, 4, 8, 16, 31 }; static const unsigned char glyphColon[7] = { 0, 4, 4, 0, 4, 4, 0 }; static const unsigned char glyphXChar[7] = { 0, 0, 17, 10, 4, 10, 17 }; static const unsigned char glyphSlash[7] = { 1, 1, 2, 4, 8, 16, 16 }; static const unsigned char glyphBackslash[7] = { 16, 16, 8, 4, 2, 1, 1 }; static const unsigned char glyphDot[7] = { 0, 0, 0, 0, 0, 12, 12 }; static const unsigned char glyphDash[7] = { 0, 0, 0, 31, 0, 0, 0 }; static const unsigned char glyphUnderscore[7] = { 0, 0, 0, 0, 0, 0, 31 }; if (c >= 'a' && c <= 'z' && c != 'x') { c = c - 'a' + 'A'; } switch (c) { case '0': return glyph0; case '1': return glyph1; case '2': return glyph2; case '3': return glyph3; case '4': return glyph4; case '5': return glyph5; case '6': return glyph6; case '7': return glyph7; case '8': return glyph8; case '9': return glyph9; case 'A': return glyphA; case 'B': return glyphB; case 'C': return glyphC; case 'D': return glyphD; case 'E': return glyphE; case 'F': return glyphF; case 'G': return glyphG; case 'H': return glyphH; case 'I': return glyphI; case 'J': return glyphJ; case 'K': return glyphK; case 'L': return glyphL; case 'M': return glyphM; case 'N': return glyphN; case 'O': return glyphO; case 'P': return glyphP; case 'Q': return glyphQ; case 'R': return glyphR; case 'S': return glyphS; case 'T': return glyphT; case 'U': return glyphU; case 'V': return glyphV; case 'W': return glyphW; case 'X': return glyphX; case 'x': return glyphXChar; case 'Y': return glyphY; case 'Z': return glyphZ; case ':': return glyphColon; case '/': return glyphSlash; case '\\': return glyphBackslash; case '.': return glyphDot; case '-': return glyphDash; case '_': return glyphUnderscore; default: return glyphBlank; } } static ID_INLINE float RadiantGLText_Abs(float value) { return (value < 0.0f) ? -value : value; } static ID_INLINE float RadiantGLText_Width(const char* text, float scale) { if (!text || !text[0]) { return 0.0f; } return (float)strlen(text) * 6.0f * RadiantGLText_Abs(scale); } static ID_INLINE float RadiantGLText_Height(float scale) { return 7.0f * RadiantGLText_Abs(scale); } static ID_INLINE void RadiantGLText_DrawScaled(const char* text, float x, float y, float xScale, float yScale) { if (!text || !text[0]) { return; } const float glyphAdvance = 6.0f * RadiantGLText_Abs(xScale); float penX = x; glBegin(GL_QUADS); for (const char* p = text; *p; p++) { const char c = *p; if (c == ' ') { penX += glyphAdvance; continue; } const unsigned char* rows = RadiantGLText_GlyphRows(c); for (int row = 0; row < 7; row++) { for (int col = 0; col < 5; col++) { if (!(rows[row] & (1 << (4 - col)))) { continue; } const float x0 = penX + col * xScale; const float y0 = y + row * yScale; const float x1 = x0 + xScale; const float y1 = y0 + yScale; glVertex2f(x0, y0); glVertex2f(x1, y0); glVertex2f(x1, y1); glVertex2f(x0, y1); } } penX += glyphAdvance; } glEnd(); } static ID_INLINE void RadiantGLText_Draw(const char* text, float x, float y, float scale) { RadiantGLText_DrawScaled(text, x, y, scale, scale); } static ID_INLINE void RadiantGLText_DrawCentered(const char* text, float centerX, float centerY, float scale) { const float x = centerX - RadiantGLText_Width(text, scale) * 0.5f; const float y = centerY - RadiantGLText_Height(scale) * 0.5f; RadiantGLText_Draw(text, x, y, scale); } static ID_INLINE void RadiantGLText_DrawCenteredYUp(const char* text, float centerX, float centerY, float scale) { const float x = centerX - RadiantGLText_Width(text, scale) * 0.5f; const float y = centerY + RadiantGLText_Height(scale) * 0.5f; RadiantGLText_DrawScaled(text, x, y, scale, -scale); } #endif // __RADIANTGLTEXT_H__