add knob and fix text
This commit is contained in:
+198
-36
@@ -758,53 +758,215 @@ void gc9a01_text(gc9a01_GC9A01_obj_t *self, GFXfont *font, char *str, uint16_t x
|
||||
}
|
||||
}
|
||||
|
||||
void gc9a01_text_gfx(gc9a01_GC9A01_obj_t *self, GFXfont *font, char *str, uint16_t x0, uint16_t y0, uint16_t color) {
|
||||
int16_t cursor_x = x0;
|
||||
int16_t cursor_y = y0;
|
||||
void gc9a01_text_gfx_transparent(gc9a01_GC9A01_obj_t *self, GFXfont *font, const char *str, uint16_t x0, uint16_t y0, uint16_t color) {
|
||||
if (!str || !*str) return;
|
||||
|
||||
// Process each character in the string
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
char c = str[i];
|
||||
// First pass: calculate string dimensions
|
||||
int16_t min_x = 32767, max_x = -32768;
|
||||
int16_t min_y = 32767, max_y = -32768;
|
||||
int16_t cursor_x = 0;
|
||||
bool has_visible_chars = false;
|
||||
|
||||
// Check if character is in font range
|
||||
if (c < font->first || c > font->last) {
|
||||
continue; // Skip unsupported characters
|
||||
}
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
char c = str[i];
|
||||
if (c < font->first || c > font->last) continue;
|
||||
|
||||
// Get glyph data for this character
|
||||
uint8_t glyph_index = c - font->first;
|
||||
GFXglyph *glyph = &font->glyph[glyph_index];
|
||||
uint8_t *bitmap = font->bitmap;
|
||||
uint8_t glyph_index = c - font->first;
|
||||
GFXglyph *glyph = &font->glyph[glyph_index];
|
||||
|
||||
// Calculate starting position for this glyph
|
||||
int16_t glyph_x = cursor_x + glyph->xOffset;
|
||||
int16_t glyph_y = cursor_y + glyph->yOffset;
|
||||
int16_t glyph_x = cursor_x + glyph->xOffset;
|
||||
int16_t glyph_y = glyph->yOffset;
|
||||
int16_t glyph_x2 = glyph_x + glyph->width - 1;
|
||||
int16_t glyph_y2 = glyph_y + glyph->height - 1;
|
||||
|
||||
// Render the glyph bitmap
|
||||
uint32_t bitmap_offset = glyph->bitmapOffset;
|
||||
uint8_t bit_index = 0;
|
||||
// Track bounding box
|
||||
if (glyph_x < min_x) min_x = glyph_x;
|
||||
if (glyph_x2 > max_x) max_x = glyph_x2;
|
||||
if (glyph_y < min_y) min_y = glyph_y;
|
||||
if (glyph_y2 > max_y) max_y = glyph_y2;
|
||||
|
||||
for (int16_t row = 0; row < glyph->height; row++) {
|
||||
for (int16_t col = 0; col < glyph->width; col++) {
|
||||
// Get current bit from bitmap
|
||||
uint8_t byte_index = bitmap_offset + (bit_index / 8);
|
||||
uint8_t bit_position = 7 - (bit_index % 8);
|
||||
uint8_t pixel = (bitmap[byte_index] >> bit_position) & 0x01;
|
||||
cursor_x += glyph->xAdvance;
|
||||
has_visible_chars = true;
|
||||
}
|
||||
|
||||
// Draw pixel if bit is set
|
||||
if (pixel) {
|
||||
gc9a01_draw_pixel(self, glyph_x + col, glyph_y + row, color);
|
||||
}
|
||||
if (!has_visible_chars) return;
|
||||
|
||||
bit_index++;
|
||||
}
|
||||
}
|
||||
// Calculate buffer dimensions
|
||||
uint16_t buffer_width = max_x - min_x + 1;
|
||||
uint16_t buffer_height = max_y - min_y + 1;
|
||||
uint32_t buffer_pixels = buffer_width * buffer_height;
|
||||
|
||||
// Advance cursor to next character position
|
||||
cursor_x += glyph->xAdvance;
|
||||
}
|
||||
// Allocate mask and color buffers
|
||||
uint8_t *mask = malloc(buffer_pixels);
|
||||
uint16_t *buffer = malloc(buffer_pixels * 2); // 2 bytes per pixel
|
||||
|
||||
if (!mask || !buffer) {
|
||||
if (mask) free(mask);
|
||||
if (buffer) free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize mask to 0 (transparent)
|
||||
memset(mask, 0, buffer_pixels);
|
||||
|
||||
// Second pass: render characters into buffer and set mask
|
||||
cursor_x = 0;
|
||||
uint16_t color_swapped = _swap_bytes(color);
|
||||
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
char c = str[i];
|
||||
if (c < font->first || c > font->last) continue;
|
||||
|
||||
uint8_t glyph_index = c - font->first;
|
||||
GFXglyph *glyph = &font->glyph[glyph_index];
|
||||
uint8_t *bitmap = font->bitmap;
|
||||
|
||||
int16_t glyph_x = cursor_x + glyph->xOffset - min_x; // Offset relative to buffer
|
||||
int16_t glyph_y = glyph->yOffset - min_y;
|
||||
|
||||
// Render glyph bitmap
|
||||
uint32_t bitmap_offset = glyph->bitmapOffset;
|
||||
uint16_t bit_index = 0;
|
||||
|
||||
for (int16_t row = 0; row < glyph->height; row++) {
|
||||
for (int16_t col = 0; col < glyph->width; col++) {
|
||||
// Get pixel from font bitmap
|
||||
uint8_t byte_index = bitmap_offset + (bit_index / 8);
|
||||
uint8_t bit_position = 7 - (bit_index % 8);
|
||||
uint8_t pixel = (bitmap[byte_index] >> bit_position) & 0x01;
|
||||
|
||||
// Set pixel in buffer and mask if foreground
|
||||
if (pixel) {
|
||||
uint32_t buffer_idx = (glyph_y + row) * buffer_width + (glyph_x + col);
|
||||
if (buffer_idx < buffer_pixels) {
|
||||
buffer[buffer_idx] = color_swapped;
|
||||
mask[buffer_idx] = 1;
|
||||
}
|
||||
}
|
||||
bit_index++;
|
||||
}
|
||||
}
|
||||
|
||||
cursor_x += glyph->xAdvance;
|
||||
}
|
||||
|
||||
// Draw only masked pixels using individual pixel writes
|
||||
for (uint16_t row = 0; row < buffer_height; row++) {
|
||||
for (uint16_t col = 0; col < buffer_width; col++) {
|
||||
uint32_t idx = row * buffer_width + col;
|
||||
if (mask[idx]) {
|
||||
// Convert back from swapped format for pixel drawing
|
||||
uint16_t pixel_color = _swap_bytes(buffer[idx]);
|
||||
gc9a01_draw_pixel(self, x0 + min_x + col, y0 + min_y + row, pixel_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(mask);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
void gc9a01_text_gfx_buffered(gc9a01_GC9A01_obj_t *self, GFXfont *font, const char *str, uint16_t x0, uint16_t y0, uint16_t fg_color, uint16_t bg_color) {
|
||||
if (!str || !*str) return;
|
||||
|
||||
// First pass: calculate string dimensions
|
||||
int16_t min_x = 32767, max_x = -32768;
|
||||
int16_t min_y = 32767, max_y = -32768;
|
||||
int16_t cursor_x = 0;
|
||||
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
char c = str[i];
|
||||
if (c < font->first || c > font->last) continue;
|
||||
|
||||
uint8_t glyph_index = c - font->first;
|
||||
GFXglyph *glyph = &font->glyph[glyph_index];
|
||||
|
||||
int16_t glyph_x = cursor_x + glyph->xOffset;
|
||||
int16_t glyph_y = glyph->yOffset;
|
||||
int16_t glyph_x2 = glyph_x + glyph->width - 1;
|
||||
int16_t glyph_y2 = glyph_y + glyph->height - 1;
|
||||
|
||||
// Track bounding box
|
||||
if (glyph_x < min_x) min_x = glyph_x;
|
||||
if (glyph_x2 > max_x) max_x = glyph_x2;
|
||||
if (glyph_y < min_y) min_y = glyph_y;
|
||||
if (glyph_y2 > max_y) max_y = glyph_y2;
|
||||
|
||||
cursor_x += glyph->xAdvance;
|
||||
}
|
||||
|
||||
// Calculate buffer dimensions
|
||||
uint16_t buffer_width = max_x - min_x + 1;
|
||||
uint16_t buffer_height = max_y - min_y + 1;
|
||||
uint32_t buffer_size = buffer_width * buffer_height * 2; // 2 bytes per pixel
|
||||
|
||||
// Allocate buffer
|
||||
uint16_t *buffer = malloc(buffer_size);
|
||||
if (!buffer) return;
|
||||
|
||||
// Initialize buffer with background color
|
||||
uint16_t bg_swapped = _swap_bytes(bg_color);
|
||||
for (uint32_t i = 0; i < buffer_width * buffer_height; i++) {
|
||||
buffer[i] = bg_swapped;
|
||||
}
|
||||
|
||||
// Second pass: render characters into buffer
|
||||
cursor_x = 0;
|
||||
uint16_t fg_swapped = _swap_bytes(fg_color);
|
||||
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
char c = str[i];
|
||||
if (c < font->first || c > font->last) continue;
|
||||
|
||||
uint8_t glyph_index = c - font->first;
|
||||
GFXglyph *glyph = &font->glyph[glyph_index];
|
||||
uint8_t *bitmap = font->bitmap;
|
||||
|
||||
int16_t glyph_x = cursor_x + glyph->xOffset - min_x; // Offset relative to buffer
|
||||
int16_t glyph_y = glyph->yOffset - min_y;
|
||||
|
||||
// Render glyph bitmap
|
||||
uint32_t bitmap_offset = glyph->bitmapOffset;
|
||||
uint16_t bit_index = 0;
|
||||
|
||||
for (int16_t row = 0; row < glyph->height; row++) {
|
||||
for (int16_t col = 0; col < glyph->width; col++) {
|
||||
// Get pixel from font bitmap
|
||||
uint8_t byte_index = bitmap_offset + (bit_index / 8);
|
||||
uint8_t bit_position = 7 - (bit_index % 8);
|
||||
uint8_t pixel = (bitmap[byte_index] >> bit_position) & 0x01;
|
||||
|
||||
// Only draw foreground pixels (preserve background)
|
||||
if (pixel) {
|
||||
uint32_t buffer_idx = (glyph_y + row) * buffer_width + (glyph_x + col);
|
||||
if (buffer_idx < buffer_width * buffer_height) {
|
||||
buffer[buffer_idx] = fg_swapped;
|
||||
}
|
||||
}
|
||||
bit_index++;
|
||||
}
|
||||
}
|
||||
|
||||
cursor_x += glyph->xAdvance;
|
||||
}
|
||||
|
||||
// Write entire buffer to display in one transaction
|
||||
int16_t final_x = x0 + min_x;
|
||||
int16_t final_y = y0 + min_y;
|
||||
|
||||
gc9a01_set_window(self, final_x, final_y,
|
||||
final_x + buffer_width - 1,
|
||||
final_y + buffer_height - 1);
|
||||
DC_HIGH();
|
||||
CS_LOW();
|
||||
gc9a01_write_spi(self->spi_obj, (uint8_t*)buffer, buffer_size, self->cs);
|
||||
CS_HIGH();
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
void gc9a01_set_rotation(gc9a01_GC9A01_obj_t *self) {
|
||||
uint8_t madctl_value = GC9A01_MADCTL_BGR;
|
||||
|
||||
|
||||
+2
-1
@@ -101,7 +101,8 @@ void gc9a01_set_rotation(gc9a01_GC9A01_obj_t *self);
|
||||
void gc9a01_hline(gc9a01_GC9A01_obj_t *self, uint16_t x, uint16_t y, uint16_t w, uint16_t color);
|
||||
void gc9a01_vline(gc9a01_GC9A01_obj_t *self, uint16_t x, uint16_t y, uint16_t w, uint16_t color);
|
||||
void gc9a01_text(gc9a01_GC9A01_obj_t *self, GFXfont *font, char *str, uint16_t x0, uint16_t y0, uint16_t fg_color, uint16_t bg_color);
|
||||
void gc9a01_text_gfx(gc9a01_GC9A01_obj_t *self, GFXfont *font, char *str, uint16_t x0, uint16_t y0, uint16_t color);
|
||||
void gc9a01_text_gfx_transparent(gc9a01_GC9A01_obj_t *self, GFXfont *font, const char *str, uint16_t x0, uint16_t y0, uint16_t color);
|
||||
void gc9a01_text_gfx_buffered(gc9a01_GC9A01_obj_t *self, GFXfont *font, const char *str, uint16_t x0, uint16_t y0, uint16_t fg_color, uint16_t bg_color);
|
||||
uint8_t gc9a01_get_color(uint8_t bpp);
|
||||
uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user