Skip to content

Instantly share code, notes, and snippets.

@Quackward
Last active August 29, 2021 09:48
Show Gist options
  • Save Quackward/3c14bef7d4a0e7262cea99993c030c9e to your computer and use it in GitHub Desktop.
Save Quackward/3c14bef7d4a0e7262cea99993c030c9e to your computer and use it in GitHub Desktop.
// starts at bl going right and upward (6 px upward)
// texture must be 8-bit 1-channel
// if drawing the bg outline, there MUST be 1px wiggle room on all sides in the surface
// does not do any formatting, draws newlines and tabs AS CHARACTERS cause yea!
//
// params:
// px the image's pixels, for now this only works with 8-bit (1-color channel) paletted images
// fgColor main color the font uses
// bgColor the outline color of the text (1 pixel wide in the 8 adjacent pixels)
// drawBG turns the outline on or off
// x left most position where text starts
// y bottom most position where text starts (px is assumed to be in the bottom-left, since we're drawing on openGL textures usually)
// texWidth just need the width of the texture
// pxLimit Nothing is drawn past this, defines an absolute WIDTH (yeah it should be called width huh)
// constWidth if not 0, there is no kerning and it just uses this width for every glyph
// string ascii string, it draws newlines, linefeeds, and tabs AS CHARACTERS (it does not format or make new lines when encountering these)
void rasterText(uint8 * px, uint8 fgColor, uint8 bgColor, bool drawBG, uint32 x, uint32 y, uint32 texWidth, uint32 pxLimit, uint32 constWidth, const char * string) {
// 31 wwww _mpp pppp pppp pppp pppp pppp pppp 0
// where w = len, m = 1 pixel down, p = pixels 0 - 25 :: left->right top->bottom
// starts at [space], through all ascii to [del], then TAB, NEWLINE, LINEFEED, //fullcircle, emptycircle, right, left
const uint32 GLYPH_BIT_COUNT = 103 - 4;
const uint32 GLYPH_BITS[GLYPH_BIT_COUNT] = {
0x40000000,0x10100421,0x300000a5,0x50afabea,0x5447d1c5,0x519d1173,0x40a2a8a2,0x10000021,
0x20208422,0x20110841,0x30001445,0x30011c40,0x24110000,0x30001c00,0x10100000,0x50111110,
0x4064a526,0x30710862,0x40f11126,0x40741907,0x40843d2a,0x40741c2f,0x40649c26,0x4021110f,
0x40649926,0x40643926,0x10008020,0x20110040,0x30410444,0x300380e0,0x30111041,0x30200883,
0x300394c0,0x4095a526,0x40749527,0x40e0842e,0x4074a527,0x40e09c2e,0x40109c2e,0x40e4b42e,
0x4094bd29,0x30710847,0x4022908f,0x40928ca9,0x40e08421,0x515ad6af,0x4094b569,0x4064a526,
0x4012a527,0x40a2a526,0x4092a527,0x4074182e,0x5042109f,0x4064a529,0x4022a529,0x50aad631,
0x40920929,0x40643929,0x40f1110f,0x20308423,0x51041041,0x20310843,0x300000a2,0x44f00000, // <-- _
0x20000041,0x40e4a5c0,0x4074a4a1,0x306084c0,0x40e4a5c8,0x4060a4c0,0x30109c26,0x4464292e,
0x4094a4e1,0x10108401,0x24110840,0x40959521,0x10108421,0x515ad5e0,0x4094a4e0,0x4064a4c0,
0x4412a527,0x5505252e,0x4010ada0,0x407405c0,0x302108e2,0x40e4a520,0x4022a520,0x50aad620,
0x40920920,0x44643929,0x40f0a1e0,0x20208822,0x10108421,0x20110441,0x40001540,0x40551545,
0x50467d84,0x51f87310,0x5005e539,//0x50efffee,0x50e8c62e,0x30119c61,0x30431cc4,
};
if(string == NULL)
return;
const char * str = string;
uint32 limit = glm::min(texWidth - x, pxLimit ? pxLimit : 0xFFFFFFFF);
for (uint32 yOff = 0; yOff < 7; ++yOff) {
uint32 n = 0;
uint8 c;
while (n < limit && (c = *str) != 0) {
if (c == '\n') c = '~'+3;
else if(c == '\t') c = '~'+2;
else if(c == '\f') c = '~'+4;
else if(c < ' ' || c > '~') c = '~'+1;
c -= ' ';
uint32 bits = GLYPH_BITS[c];
uint32 width = bits >> 28;
uint32 shift = uint32(!((bits >> 26)&0x1));
if(n + width > limit)
break;
if(constWidth)
n += ((constWidth)>>1) - ((width)>>1);
uint8 * ptr = px + n + x + (y + yOff-1 + shift) * texWidth - 1;
if (drawBG && yOff == 0) {
uint32 nibble = bits >> (20u - (yOff)*5u);
if(width > 0u && (nibble)&0x01u){ ptr[0] = bgColor; ptr[1] = bgColor; ptr[2] = bgColor;}
if(width > 1u && (nibble)&0x02u){ ptr[1] = bgColor; ptr[2] = bgColor; ptr[3] = bgColor;}
if(width > 2u && (nibble)&0x04u){ ptr[2] = bgColor; ptr[3] = bgColor; ptr[4] = bgColor;}
if(width > 3u && (nibble)&0x08u){ ptr[3] = bgColor; ptr[4] = bgColor; ptr[5] = bgColor;}
if(width > 4u && (nibble)&0x10u){ ptr[4] = bgColor; ptr[5] = bgColor; ptr[6] = bgColor;}
}else if ((yOff != 6)) {
uint32 nibble = bits >> (20u - (yOff-1)*5u);
if (drawBG) {
if (yOff != 1) {
uint32 lowerNibble = bits >> (20u - (yOff-2)*5u);
if(width > 0u && (lowerNibble)&0x01u){ ptr[0] = bgColor; ptr[1] = bgColor; ptr[2] = bgColor;}
if(width > 1u && (lowerNibble)&0x02u){ ptr[1] = bgColor; ptr[2] = bgColor; ptr[3] = bgColor;}
if(width > 2u && (lowerNibble)&0x04u){ ptr[2] = bgColor; ptr[3] = bgColor; ptr[4] = bgColor;}
if(width > 3u && (lowerNibble)&0x08u){ ptr[3] = bgColor; ptr[4] = bgColor; ptr[5] = bgColor;}
if(width > 4u && (lowerNibble)&0x10u){ ptr[4] = bgColor; ptr[5] = bgColor; ptr[6] = bgColor;}
}
if (yOff != 5) {
uint32 higherNibble = bits >> (20u - (yOff)*5u);
if(width > 0u && (higherNibble)&0x01u){ ptr[0] = bgColor; ptr[1] = bgColor; ptr[2] = bgColor;}
if(width > 1u && (higherNibble)&0x02u){ ptr[1] = bgColor; ptr[2] = bgColor; ptr[3] = bgColor;}
if(width > 2u && (higherNibble)&0x04u){ ptr[2] = bgColor; ptr[2] = bgColor; ptr[4] = bgColor;}
if(width > 3u && (higherNibble)&0x08u){ ptr[3] = bgColor; ptr[4] = bgColor; ptr[5] = bgColor;}
if(width > 4u && (higherNibble)&0x10u){ ptr[4] = bgColor; ptr[5] = bgColor; ptr[6] = bgColor;}
}
if(width > 0u && (nibble)&0x01u){ ptr[0] = bgColor; ptr[2] = bgColor;}
if(width > 1u && (nibble)&0x02u){ ptr[1] = bgColor; ptr[3] = bgColor;}
if(width > 2u && (nibble)&0x04u){ ptr[2] = bgColor; ptr[4] = bgColor;}
if(width > 3u && (nibble)&0x08u){ ptr[3] = bgColor; ptr[5] = bgColor;}
if(width > 4u && (nibble)&0x10u){ ptr[4] = bgColor; ptr[6] = bgColor;}
}
if(width > 0u && (nibble)&0x01u) ptr[1] = fgColor;
if(width > 1u && (nibble)&0x02u) ptr[2] = fgColor;
if(width > 2u && (nibble)&0x04u) ptr[3] = fgColor;
if(width > 3u && (nibble)&0x08u) ptr[4] = fgColor;
if(width > 4u && (nibble)&0x10u) ptr[5] = fgColor;
} else if(drawBG) {
uint32 nibble = bits >> (20u - (yOff-2)*5u);
if(width > 0u && (nibble)&0x01u){ ptr[0] = bgColor; ptr[1] = bgColor; ptr[2] = bgColor;}
if(width > 1u && (nibble)&0x02u){ ptr[1] = bgColor; ptr[2] = bgColor; ptr[3] = bgColor;}
if(width > 2u && (nibble)&0x04u){ ptr[2] = bgColor; ptr[3] = bgColor; ptr[4] = bgColor;}
if(width > 3u && (nibble)&0x08u){ ptr[3] = bgColor; ptr[4] = bgColor; ptr[5] = bgColor;}
if(width > 4u && (nibble)&0x10u){ ptr[4] = bgColor; ptr[5] = bgColor; ptr[6] = bgColor;}
}
n += constWidth ? constWidth - ((constWidth)>>1 - (width)>>1) : width + 1;
++str;
}
str = string;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment