Files
McBitFont/STM32_HAL_Lib/mctext.c
2025-07-19 09:02:49 +03:00

142 lines
5.7 KiB
C

/*
* mctext.c
*
* Created on: May 16, 2025
* Author: Anton Mukhin
*/
#include "mctext.h"
#include "ST7565.h"
//=========================== SET A FUNCTION NAME HERE! ===========================//
// A function from display driver to set a pixel (x, y, color)
void (*mct_SetPixel)(uint8_t, uint8_t, uint8_t) = ST7565_SetPixel;
//=================================================================================//
// Draw a single character. Returns width of drawn character
uint8_t mct_CharTS(uint8_t x, uint8_t y, unsigned char c, uint8_t color, const uint8_t *font, uint8_t transp, uint8_t scale) {
uint8_t pk = font[0]; // Is it a packed font?
uint8_t w = font[1]; // Font char width
uint8_t h = font[2]; // Font char height
uint8_t fc = font[4]; // First char code in the font
uint8_t lc = font[5]; // Last char code in the font
uint8_t i, j, p, s, b, seg; // i-cur.column, j-cur.row of 8, p-rows of 8, s-height in cur.row of 8, b-cur.bit in cur.row, seg-byte.segment
uint8_t bps; // Bytes per symbol for packed fonts
uint16_t o; // Current offset
uint8_t sx, sy; // To paint scaled pixel
if (c < fc || c > lc) return 0;
if (x > LCDWIDTH) return 0;
if (y + h * scale > LCDHEIGHT) return 0;
// Calc the offset for desired symbol
if (pk) { // The font is packed
if (w) { // The font is monospaced
bps = w*h/8; // Bytes per symbol
if ((w*h)%8 > 0) bps++; // Correction for the last byte
o = FONT_HEADER+(c-fc)*bps; // Offset for desired symbol
} else { // The font is not monospaced
o = FONT_HEADER; // Starting offset
for (i=0; i<c-fc; i++) { // Going through every symbol
bps = font[o]*h/8; // Bytes per current symbol
if ((font[o]*h)%8 > 0) bps++; // Correction for the last byte
o += bps + 1; // Adding symbol's width to the offset (+ width byte)
}
w = font[o]; // Desired symbol's width
o++; // Offset for desired symbol's data
}
// Draw the packed symbol!
bps = w*h/8; // Bytes per current symbol
if ((w*h)%8 > 0) bps++; // Correction for the last byte
b = 0; // bit indexer in "current" byte
for (i=0; i<w*scale; i+=scale) { // Going through columns
if (x+i > LCDWIDTH) return i-1; // Check if we're out of display size
for (j=0; j<h*scale; j+=scale) { // Going through rows in column [i]
if (b == 0) seg = font[o];
if ((seg>>b) & 1) {
for (sx = 0; sx < scale; sx++)
for (sy = 0; sy < scale; sy++)
mct_SetPixel(x+i+sx, y+j+sy, color); // Paint the pixel
} else if (!transp) {
for (sx = 0; sx < scale; sx++)
for (sy = 0; sy < scale; sy++)
mct_SetPixel(x+i+sx, y+j+sy, !color); // Paint the background pixel
}
if (b < 7) b++; else {b = 0; o++;} // Track bits and bytes
}
}
} else { // The font is not packed
p = (h%8 > 0) ? h/8 + 1 : h/8; // Bytes in one column
if (w) { // The font is monospaced
o = FONT_HEADER+(c-fc)*w*p; // Offset for desired symbol
} else { // The font is not monospaced
o = FONT_HEADER; // Starting offset
for (i=0; i<c-fc; i++) { // Going through every symbol
o += font[o]*p + 1; // Adding symbol's width to the offset
}
w = font[o]; // Desired symbol's width
o++; // Offset for desired symbol's data
}
// Draw the symbol
for (i=0; i<w*scale; i+=scale) { // Going through columns
if (x+i > LCDWIDTH) return i-1; // Check if we're out of display size
for (j=0; j<p; j++) { // Going through bytes in single column
s = (h - j*8 >= 8) ? 8 : (h - j*8) % 8; // Clac the amount of pixels in current byte
seg = font[o];
for (b=0; b<s; b++) { // Going through the byte and paint the pixel if the bit is 1
if ((seg>>b) & 1) {
for (sx = 0; sx < scale; sx++)
for (sy = 0; sy < scale; sy++)
mct_SetPixel(x+i+sx, y+j*8*scale+b*scale+sy, color);
} else if (!transp) {
for (sx = 0; sx < scale; sx++)
for (sy = 0; sy < scale; sy++)
mct_SetPixel(x+i+sx, y+j*8*scale+b*scale+sy, !color);
}
}
o++;
}
//mct_SetPixel(x+i, y, color); // For testing purposes
}
}
return w*scale;
}
// Draw a single character. Not scaled
uint8_t mct_CharT(uint8_t x, uint8_t y, unsigned char c, uint8_t color, const uint8_t *font, uint8_t transp) {
return mct_CharTS(x, y, c, color, font, transp, 1);
}
// Draw a single character. Transparent background. Returns width of drawn character
uint8_t mct_Char(uint8_t x, uint8_t y, unsigned char c, uint8_t color, const uint8_t *font) {
return mct_CharT(x, y, c, color, font, 1);
}
// Draw a string of characters. Transparency, Scale
void mct_StringTS(uint8_t x, uint8_t y, const char *c, uint8_t color, const uint8_t *font, uint8_t transp, uint8_t scale) {
uint8_t w = font[1]; // Font char width
uint8_t h = font[2]; // Font char height
uint8_t s = font[3]; // Font space between characters
if (y+h*scale > LCDHEIGHT) return;
while (c[0] != 0) {
//if (x+w > LCDWIDTH) return;
w = mct_CharTS(x, y, (unsigned char)*c, color, font, transp, scale);
c++;
x += w + s*scale;
}
}
// Draw a string of characters
void mct_String(uint8_t x, uint8_t y, const char *c, uint8_t color, const uint8_t *font) {
mct_StringTS(x, y, c, color, font, 1, 1);
}