2025-09-14 22:53:11 +02:00

115 lines
3.2 KiB
C

#include "font.h"
#include "LCD_driver.h"
void GFX_DrawChar(
uint16_t x,
uint16_t y,
char c,
const GFXfont *font,
uint16_t fg_color,
uint16_t bg_color) {
if (c < font->firstChar || c > font->lastChar) {
return;
}
uint16_t glyphIndex = c - font->firstChar;
const GFXglyph *glyph = &font->glyphs[glyphIndex];
int16_t startX = x + glyph->xOffset;
int16_t startY = y + glyph->yOffset;
if (startX + glyph->width <= 0 || startX >= LCD_WIDTH) return;
if (startY + glyph->height <= 0 || startY >= LCD_HEIGHT) return;
LCD_Set_Address(startX, startY, startX + glyph->width - 1, startY + glyph->height - 1);
uint16_t pendingPixelCount = 0;
uint8_t pendingPixelBit = 0;
uint16_t bitPos = 0;
for (uint8_t row = 0; row < glyph->height; row++) {
for (uint8_t col = 0; col < glyph->width; col++) {
uint16_t byteIndex = glyph->bitmapOffset + (bitPos / 8);
uint8_t bitIndex = bitPos % 8;
uint8_t pixelBit = font->bitmaps[byteIndex] & (0x80 >> bitIndex);
if(pixelBit == pendingPixelBit) {
pendingPixelCount++;
}else {
if(pendingPixelCount != 0) {
LCD_Draw_Colour_Burst(pendingPixelBit ? fg_color : bg_color, pendingPixelCount);
pendingPixelCount = 1;
}
pendingPixelBit = pixelBit;
}
// Per pixel way: slower
// uint16_t pixelColor = pixelBit ? fg_color : bg_color;
//
// int16_t absX = startX + col;
// int16_t absY = startY + row;
//
// if (absX >= 0 && absX < LCD_WIDTH && absY >= 0 && absY < LCD_HEIGHT) {
// LCD_Draw_Pixel(absX, absY, pixelColor);
// }
bitPos++;
}
}
if(pendingPixelCount != 0) {
LCD_Draw_Colour_Burst(pendingPixelBit ? fg_color : bg_color, pendingPixelCount);
}
}
uint16_t GFX_GetTextWidth(const char *text, const GFXfont *font) {
uint16_t width = 0;
while (*text != '\0') {
if (*text >= font->firstChar && *text <= font->lastChar) {
uint16_t glyphIndex = *text - font->firstChar;
width += font->glyphs[glyphIndex].advance;
} else {
// Default advance for unsupported characters
width += 10;
}
text++;
}
return width;
}
void GFX_DrawText(uint16_t x, uint16_t y, const char *text, const GFXfont *font,
uint16_t fg_color, uint16_t bg_color, uint8_t alignment) {
// Adjust x position based on alignment
switch (alignment) {
case 1: // Center
x -= GFX_GetTextWidth(text, font) / 2;
break;
case 2: // Right
x -= GFX_GetTextWidth(text, font);
break;
// Default: Left alignment (no adjustment)
}
// Draw each character
uint16_t cursorX = x;
uint16_t cursorY = y;
while (*text != '\0') {
GFX_DrawChar(cursorX, cursorY, *text, font, fg_color, bg_color);
// Move cursor by the glyph's advance width
if (*text >= font->firstChar && *text <= font->lastChar) {
uint16_t glyphIndex = *text - font->firstChar;
cursorX += font->glyphs[glyphIndex].advance;
} else {
// Default advance for unsupported characters
cursorX += 10;
}
text++;
}
}