Anti aliasing + per-character speed text refreshing
This commit is contained in:
+70
-54
@@ -1,14 +1,15 @@
|
||||
#include "dashboard.h"
|
||||
#include "font.h"
|
||||
#include "icons.h"
|
||||
//#include "monomaniacone12pt.h"
|
||||
#include "monomaniacone14pt.h"
|
||||
#include "monomaniacone20pt.h"
|
||||
#include "monomaniacone72pt.h"
|
||||
#include "usart.h"
|
||||
#include "crc.h"
|
||||
#include "float16.h"
|
||||
#include "math.h"
|
||||
//#include "monomaniacone14pt.h"
|
||||
#include "monomaniacone27pt.h" // 2x antialiased version of 14pt
|
||||
//#include "monomaniacone20pt.h"
|
||||
#include "monomaniacone39pt.h" // 2x antialiased version of 20pt
|
||||
#include "monomaniacone72pt.h"
|
||||
#include <stdio.h>
|
||||
|
||||
const char *fault_code_strings[] = { "none", "over voltage", "under voltage",
|
||||
@@ -29,8 +30,8 @@ void run_dashboard_loop_test() {
|
||||
uint32_t i = 0;
|
||||
while (1) {
|
||||
|
||||
draw_battery(654, i * 100 / 4, 1321, 343);
|
||||
draw_speed(i * 1000 / 4, i % 30);
|
||||
draw_battery(654, i * 10 / 4, 13210000, 343000);
|
||||
draw_speed((((i/2) % 34)) * 1000, 0);
|
||||
int16_t duty = 1000 - (int16_t) i * 1000 / 200;
|
||||
draw_power_bars(duty);
|
||||
draw_power(100 * i / 20 * (duty < 0 ? -1 : 1), duty, 60 * 10);
|
||||
@@ -52,7 +53,7 @@ void run_dashboard_loop_test() {
|
||||
|
||||
uint8_t initialized = 0;
|
||||
void run_dashboard_loop() {
|
||||
|
||||
//run_dashboard_loop_test();
|
||||
LCD_Init();
|
||||
LCD_Fill_Screen(COLOR_OFF, 1);
|
||||
LCD_Fill_Screen(COLOR_BG, 0);
|
||||
@@ -130,9 +131,9 @@ void update_values(uint8_t refresh_slow, uint8_t refresh_mid) {
|
||||
refresh_mid = 1;
|
||||
}
|
||||
|
||||
//speed = (int32_t) (((float) speed) / 1.609344);
|
||||
//float wheel_diameter = 0.246; // in meter
|
||||
//speed = ((float) rpm) * 3.14159265359 * wheel_diameter * 60 / 1000;
|
||||
//speed = (int32_t) (((float) speed) / 1.609344);
|
||||
//float wheel_diameter = 0.246; // in meter
|
||||
//speed = ((float) rpm) * 3.14159265359 * wheel_diameter * 60 / 1000;
|
||||
|
||||
draw_power_bars(duty_cycle);
|
||||
if (refresh_mid) {
|
||||
@@ -141,7 +142,7 @@ void update_values(uint8_t refresh_slow, uint8_t refresh_mid) {
|
||||
}
|
||||
if (refresh_slow) {
|
||||
draw_battery(input_voltage_filtered, battery_level, distance_abs,
|
||||
distance_life);
|
||||
distance_life);
|
||||
draw_temps(temp_fet, temp_motor);
|
||||
}
|
||||
}
|
||||
@@ -333,35 +334,35 @@ void draw_battery(
|
||||
if (percent > 20 * 10) {
|
||||
// Drawing the voltage to the left
|
||||
left_x = 10
|
||||
+ GFX_DrawText(left_x, text_y_14, voltage_text, &monomaniacone14pt,
|
||||
COLOR_BG, COLOR_SUCCESS, 0, -2);
|
||||
+ GFX_DrawTextScaled(left_x, text_y_14, voltage_text,
|
||||
&monomaniacone27pt,
|
||||
COLOR_BG, COLOR_SUCCESS, 0, -2, 2);
|
||||
} else {
|
||||
// Drawing the voltage to the right
|
||||
right_x = -10
|
||||
+ GFX_DrawText(right_x, text_y_14, voltage_text, &monomaniacone14pt,
|
||||
COLOR_FG, COLOR_BG, 2, -2);
|
||||
+ GFX_DrawTextScaled(right_x, text_y_14, voltage_text,
|
||||
&monomaniacone27pt,
|
||||
COLOR_FG, COLOR_BG, 2, -2, 2);
|
||||
}
|
||||
|
||||
if (percent > 50 * 10) {
|
||||
// Drawing the distances on the left
|
||||
GFX_DrawText(left_x, text_y_14, distances_text, &monomaniacone14pt,
|
||||
COLOR_BG, COLOR_SUCCESS, 0, -3);
|
||||
GFX_DrawTextScaled(left_x, text_y_14, distances_text, &monomaniacone27pt,
|
||||
COLOR_BG, COLOR_SUCCESS, 0, -2, 2);
|
||||
} else {
|
||||
// Drawing the distances on the right
|
||||
GFX_DrawText(right_x, text_y_14, distances_text, &monomaniacone14pt,
|
||||
COLOR_FG, COLOR_BG, 2, -3);
|
||||
GFX_DrawTextScaled(right_x, text_y_14, distances_text, &monomaniacone27pt,
|
||||
COLOR_FG, COLOR_BG, 2, -2, 2);
|
||||
}
|
||||
|
||||
if (percent > 80 * 10) {
|
||||
// Drawing the distances on the left
|
||||
GFX_DrawText(filled_bar_end_x - 4, text_y_14, percent_text,
|
||||
&monomaniacone14pt,
|
||||
COLOR_BG, COLOR_SUCCESS, 2, 0);
|
||||
GFX_DrawTextScaled(filled_bar_end_x - 4, text_y_14, percent_text,
|
||||
&monomaniacone27pt, COLOR_BG, COLOR_SUCCESS, 2, 0, 2);
|
||||
} else {
|
||||
// Drawing the distances on the right
|
||||
GFX_DrawText(filled_bar_end_x + 4, text_y_14, percent_text,
|
||||
&monomaniacone14pt,
|
||||
COLOR_FG, COLOR_BG, 0, 0);
|
||||
GFX_DrawTextScaled(filled_bar_end_x + 4, text_y_14, percent_text,
|
||||
&monomaniacone27pt, COLOR_FG, COLOR_BG, 0, 0, 2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -416,6 +417,8 @@ uint32_t last_avg_speed = 30;
|
||||
uint32_t avg_speed_tot = 0;// You need to ride super fast for a super long time for it to overflow ;)
|
||||
uint32_t avg_speed_count = 0;
|
||||
uint8_t last_fault_code = 0;
|
||||
uint16_t last_speed_cursor_x = 0;
|
||||
char speed_text[4];
|
||||
void draw_speed(int32_t speedd, uint8_t fault_code) {
|
||||
|
||||
uint32_t speed = speedd < 0 ? -speedd / 1000 : speedd / 1000;
|
||||
@@ -440,14 +443,26 @@ void draw_speed(int32_t speedd, uint8_t fault_code) {
|
||||
|
||||
// Draw
|
||||
if (last_speed != speed) {
|
||||
//uint16_t erase_width = 85;// width to erase from center
|
||||
|
||||
if (last_speed >= 10 && speed >= 10 && last_speed / 10 == speed / 10) {
|
||||
uint16_t old_glyphIndex = speed_text[0] - monomaniacone72pt.firstChar;
|
||||
const GFXglyph *old_glyph = &monomaniacone72pt.glyphs[old_glyphIndex];
|
||||
GFX_ClearChar(last_speed_cursor_x - old_glyph->advance, 32 + 95, speed_text[1], &monomaniacone72pt, COLOR_BG);
|
||||
sprintf(speed_text, "%lu", speed);
|
||||
last_speed_cursor_x = GFX_DrawChar(last_speed_cursor_x - old_glyph->advance, 32 + 95, speed_text[1],
|
||||
&monomaniacone72pt, COLOR_FG, COLOR_BG);
|
||||
} else {
|
||||
GFX_ClearText(LCD_WIDTH / 2, 32 + 95, speed_text,
|
||||
&monomaniacone72pt, COLOR_BG, 1, -5);
|
||||
sprintf(speed_text, "%lu", speed);
|
||||
// LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 22, 2 * erase_width, 110,
|
||||
// COLOR_BG);
|
||||
last_speed_cursor_x = 5 + GFX_DrawText(LCD_WIDTH / 2, 32 + 95, speed_text,
|
||||
&monomaniacone72pt,
|
||||
COLOR_FG, COLOR_BG, 1, -5);
|
||||
}
|
||||
last_speed = speed;
|
||||
uint16_t erase_width = 85;// width to erase from center
|
||||
char speed_text[4];
|
||||
sprintf(speed_text, "%lu", speed);
|
||||
LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 22, 2 * erase_width, 110,
|
||||
COLOR_BG);
|
||||
GFX_DrawText(LCD_WIDTH / 2, 32 + 95, speed_text, &monomaniacone72pt,
|
||||
COLOR_FG, COLOR_BG, 1, -5);
|
||||
}
|
||||
|
||||
uint16_t erase_width = 90;// width to erase from center
|
||||
@@ -469,8 +484,8 @@ void draw_speed(int32_t speedd, uint8_t fault_code) {
|
||||
|
||||
LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 140, 2 * erase_width, 25,
|
||||
COLOR_BG);
|
||||
GFX_DrawText(LCD_WIDTH / 2, 159, fault_text, &monomaniacone14pt,
|
||||
COLOR_ERROR, COLOR_BG, 1, -3);
|
||||
GFX_DrawTextScaled(LCD_WIDTH / 2, 159, fault_text, &monomaniacone27pt,
|
||||
COLOR_ERROR, COLOR_BG, 1, -3, 2);
|
||||
}
|
||||
}
|
||||
if (update_stats) {
|
||||
@@ -478,8 +493,8 @@ void draw_speed(int32_t speedd, uint8_t fault_code) {
|
||||
sprintf(stats_text, "avg: %lu max: %lu", avg_speed, max_speed);
|
||||
LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 140, 2 * erase_width, 25,
|
||||
COLOR_BG);
|
||||
GFX_DrawText(LCD_WIDTH / 2, 159, stats_text, &monomaniacone14pt,
|
||||
COLOR_SECONDARY, COLOR_BG, 1, -3);
|
||||
GFX_DrawTextScaled(LCD_WIDTH / 2, 159, stats_text, &monomaniacone27pt,
|
||||
COLOR_SECONDARY, COLOR_BG, 1, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,7 +507,7 @@ int32_t last_power = 1000;
|
||||
// Input voltage from COMM_GET_VALUES, scale 10
|
||||
void draw_power(int32_t current_i, int16_t duty_i, int16_t voltage_i) {
|
||||
if (duty_i < 0 && current_i > 0) {
|
||||
current_i = -current_i;
|
||||
current_i = -current_i;
|
||||
}
|
||||
int16_t current = current_i / 100;
|
||||
uint16_t duty = duty_i < 0 ? -duty_i / 10 : duty_i / 10;
|
||||
@@ -513,10 +528,10 @@ void draw_power(int32_t current_i, int16_t duty_i, int16_t voltage_i) {
|
||||
}
|
||||
|
||||
char text[8];
|
||||
sprintf(text, "%dA", current);
|
||||
sprintf(text, "%d.", current);
|
||||
LCD_Draw_Rectangle(LEFT_CENTER_COL1 - 38, 30, 2 * 39, 35, COLOR_BG);
|
||||
GFX_DrawText(LEFT_CENTER_COL1, 60, text, &monomaniacone20pt,
|
||||
COLOR_PRIMARY, COLOR_BG, 1, -2);
|
||||
GFX_DrawTextScaled(LEFT_CENTER_COL1, 60, text, &monomaniacone39pt,
|
||||
COLOR_PRIMARY, COLOR_BG, 1, -2, 2);
|
||||
}
|
||||
if (duty != last_duty) {
|
||||
last_duty = duty;
|
||||
@@ -525,10 +540,10 @@ void draw_power(int32_t current_i, int16_t duty_i, int16_t voltage_i) {
|
||||
}
|
||||
|
||||
char text[8];
|
||||
sprintf(text, "%u%%", duty);
|
||||
sprintf(text, "%u,", duty);
|
||||
LCD_Draw_Rectangle(LEFT_CENTER_COL2 - 39, 30, 2 * 39, 35, COLOR_BG);
|
||||
GFX_DrawText(LEFT_CENTER_COL2, 60, text, &monomaniacone20pt,
|
||||
COLOR_PRIMARY, COLOR_BG, 1, -2);
|
||||
GFX_DrawTextScaled(LEFT_CENTER_COL2, 60, text, &monomaniacone39pt,
|
||||
COLOR_PRIMARY, COLOR_BG, 1, -2, 2);
|
||||
}
|
||||
if (power != last_power) {
|
||||
last_power = power;
|
||||
@@ -539,10 +554,10 @@ void draw_power(int32_t current_i, int16_t duty_i, int16_t voltage_i) {
|
||||
}
|
||||
|
||||
char text[10];
|
||||
sprintf(text, "%ldW", power);
|
||||
sprintf(text, "%ld/", power);
|
||||
LCD_Draw_Rectangle(RIGHT_CENTER - 70, 30, 2 * 70, 35, COLOR_BG);
|
||||
GFX_DrawText(RIGHT_CENTER, 60, text, &monomaniacone20pt,
|
||||
COLOR_PRIMARY, COLOR_BG, 1, -2);
|
||||
GFX_DrawTextScaled(RIGHT_CENTER, 60, text, &monomaniacone39pt,
|
||||
COLOR_PRIMARY, COLOR_BG, 1, -2, 2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -584,8 +599,8 @@ void draw_adc(
|
||||
// Draw the text
|
||||
char text[8];
|
||||
sprintf(text, "%.1fV", ((float) adc1) / 10);
|
||||
GFX_DrawText(RIGHT_CENTER - 3 - 27, 76 + free_height - 2, text,
|
||||
&monomaniacone14pt, color, COLOR_BG, 1, -2);
|
||||
GFX_DrawTextScaled(RIGHT_CENTER - 3 - 27, 76 + free_height - 2, text,
|
||||
&monomaniacone27pt, color, COLOR_BG, 1, -1, 2);
|
||||
|
||||
last_adc1 = adc1;
|
||||
last_adc1_en = adc1_en;
|
||||
@@ -608,8 +623,8 @@ void draw_adc(
|
||||
// Draw the text
|
||||
char text[8];
|
||||
sprintf(text, "%.1fV", ((float) adc2) / 10);
|
||||
GFX_DrawText(RIGHT_CENTER + 3 + 27, 76 + free_height - 2, text,
|
||||
&monomaniacone14pt, color, COLOR_BG, 1, -2);
|
||||
GFX_DrawTextScaled(RIGHT_CENTER + 3 + 27, 76 + free_height - 2, text,
|
||||
&monomaniacone27pt, color, COLOR_BG, 1, -1, 2);
|
||||
|
||||
last_adc2 = adc2;
|
||||
last_adc2_en = adc2_en;
|
||||
@@ -637,8 +652,8 @@ void draw_temps(int16_t temp_fet_scaled, int16_t temp_motor_scaled) {
|
||||
char text[8];
|
||||
sprintf(text, "%u>C", temp_mot);
|
||||
LCD_Draw_Rectangle(LEFT_CENTER_COL1 - 38, 138, 2 * 39, 25, COLOR_BG);
|
||||
GFX_DrawText(LEFT_CENTER_COL1, 159, text, &monomaniacone14pt,
|
||||
COLOR_SECONDARY, COLOR_BG, 1, -1);
|
||||
GFX_DrawTextScaled(LEFT_CENTER_COL1, 159, text, &monomaniacone27pt,
|
||||
COLOR_SECONDARY, COLOR_BG, 1, -1, 2);
|
||||
}
|
||||
if (temp_fet != last_temp_fet) {
|
||||
last_temp_fet = temp_fet;
|
||||
@@ -646,7 +661,8 @@ void draw_temps(int16_t temp_fet_scaled, int16_t temp_motor_scaled) {
|
||||
char text[8];
|
||||
sprintf(text, "%u>C", temp_fet);
|
||||
LCD_Draw_Rectangle(LEFT_CENTER_COL2 - 39, 138, 2 * 39, 25, COLOR_BG);
|
||||
GFX_DrawText(LEFT_CENTER_COL2, 159, text, &monomaniacone14pt, COLOR_PRIMARY,
|
||||
COLOR_BG, 1, -1);
|
||||
GFX_DrawTextScaled(LEFT_CENTER_COL2, 159, text, &monomaniacone27pt,
|
||||
COLOR_PRIMARY,
|
||||
COLOR_BG, 1, -1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
+230
-19
@@ -1,7 +1,7 @@
|
||||
#include "font.h"
|
||||
#include "LCD_driver.h"
|
||||
|
||||
void GFX_DrawChar(
|
||||
uint16_t GFX_DrawChar(
|
||||
uint16_t x,
|
||||
uint16_t y,
|
||||
char c,
|
||||
@@ -10,7 +10,7 @@ void GFX_DrawChar(
|
||||
uint16_t bg_color) {
|
||||
|
||||
if (c < font->firstChar || c > font->lastChar) {
|
||||
return;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16_t glyphIndex = c - font->firstChar;
|
||||
@@ -19,8 +19,8 @@ void GFX_DrawChar(
|
||||
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;
|
||||
if (startX + glyph->width <= 0 || startX >= LCD_WIDTH) return x;
|
||||
if (startY + glyph->height <= 0 || startY >= LCD_HEIGHT) return x;
|
||||
|
||||
LCD_Set_Address(startX, startY, startX + glyph->width - 1,
|
||||
startY + glyph->height - 1);
|
||||
@@ -32,7 +32,8 @@ void GFX_DrawChar(
|
||||
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)) ? 1 : 0;
|
||||
uint8_t pixelBit =
|
||||
(font->bitmaps[byteIndex] & (0x80 >> bitIndex)) ? 1 : 0;
|
||||
|
||||
if (pixelBit == pendingPixelBit) {
|
||||
pendingPixelCount++;
|
||||
@@ -62,9 +63,153 @@ void GFX_DrawChar(
|
||||
LCD_Draw_Colour_Burst(pendingPixelBit ? fg_color : bg_color,
|
||||
pendingPixelCount);
|
||||
}
|
||||
|
||||
return x + glyph->advance;
|
||||
}
|
||||
|
||||
uint16_t GFX_GetTextWidth(const char *text, const GFXfont *font, int8_t letter_spacing) {
|
||||
uint16_t GFX_ClearChar(
|
||||
uint16_t x,
|
||||
uint16_t y,
|
||||
char c,
|
||||
const GFXfont *font,
|
||||
uint16_t bg_color) {
|
||||
|
||||
if (c < font->firstChar || c > font->lastChar) {
|
||||
return x;
|
||||
}
|
||||
|
||||
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 x;
|
||||
if (startY + glyph->height <= 0 || startY >= LCD_HEIGHT) return x;
|
||||
|
||||
LCD_Set_Address(startX, startY, startX + glyph->width - 1,
|
||||
startY + glyph->height - 1);
|
||||
LCD_Draw_Colour_Burst(bg_color, glyph->height * glyph->width);
|
||||
|
||||
return x + glyph->advance;
|
||||
}
|
||||
|
||||
uint16_t GFX_DrawCharScaled(
|
||||
uint16_t x,
|
||||
uint16_t y,
|
||||
char c,
|
||||
const GFXfont *font,
|
||||
uint16_t fg_color,
|
||||
uint16_t bg_color,
|
||||
uint8_t scale) {
|
||||
|
||||
if (c < font->firstChar || c > font->lastChar || scale == 0) {
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16_t glyphIndex = c - font->firstChar;
|
||||
const GFXglyph *glyph = &font->glyphs[glyphIndex];
|
||||
|
||||
// Calcul des dimensions cibles après mise à l'échelle
|
||||
uint16_t target_width = (glyph->width + scale - 1) / scale;
|
||||
uint16_t target_height = (glyph->height + scale - 1) / scale;
|
||||
|
||||
int16_t startX = x + (glyph->xOffset / scale);
|
||||
int16_t startY = y + (glyph->yOffset / scale);
|
||||
|
||||
// Vérification des limites avec les dimensions cibles
|
||||
if (startX + target_width <= 0 || startX >= LCD_WIDTH) return x;
|
||||
if (startY + target_height <= 0 || startY >= LCD_HEIGHT) return x;
|
||||
|
||||
// Mode standard (sans anti-crénelage)
|
||||
if (scale == 1) {
|
||||
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)) ? 1 : 0;
|
||||
|
||||
if (pixelBit == pendingPixelBit) {
|
||||
pendingPixelCount++;
|
||||
} else {
|
||||
if (pendingPixelCount != 0) {
|
||||
LCD_Draw_Colour_Burst(pendingPixelBit ? fg_color : bg_color,
|
||||
pendingPixelCount);
|
||||
pendingPixelCount = 1;
|
||||
}
|
||||
pendingPixelBit = pixelBit;
|
||||
}
|
||||
bitPos++;
|
||||
}
|
||||
}
|
||||
if (pendingPixelCount != 0) {
|
||||
LCD_Draw_Colour_Burst(pendingPixelBit ? fg_color : bg_color,
|
||||
pendingPixelCount);
|
||||
}
|
||||
return x + glyph->advance;
|
||||
}
|
||||
|
||||
// Mode anti-crénelage (scale > 1)
|
||||
const uint16_t scale_sq = scale * scale;
|
||||
const uint8_t bg_R = (bg_color >> 11) & 0x1F;
|
||||
const uint8_t bg_G = (bg_color >> 5) & 0x3F;
|
||||
const uint8_t bg_B = bg_color & 0x1F;
|
||||
const uint8_t fg_R = (fg_color >> 11) & 0x1F;
|
||||
const uint8_t fg_G = (fg_color >> 5) & 0x3F;
|
||||
const uint8_t fg_B = fg_color & 0x1F;
|
||||
|
||||
for (uint16_t tr = 0; tr < target_height; tr++) {
|
||||
for (uint16_t tc = 0; tc < target_width; tc++) {
|
||||
uint16_t count = 0;
|
||||
const uint16_t src_row_start = tr * scale;
|
||||
const uint16_t src_col_start = tc * scale;
|
||||
|
||||
// Comptage des pixels actifs dans le bloc source
|
||||
for (uint8_t sr = 0; sr < scale; sr++) {
|
||||
for (uint8_t sc = 0; sc < scale; sc++) {
|
||||
const uint16_t src_row = src_row_start + sr;
|
||||
const uint16_t src_col = src_col_start + sc;
|
||||
|
||||
if (src_row >= glyph->height || src_col >= glyph->width) continue;
|
||||
|
||||
const uint32_t bitPos = (src_row * glyph->width) + src_col;
|
||||
const uint16_t byteIndex = glyph->bitmapOffset + (bitPos / 8);
|
||||
const uint8_t bitIndex = bitPos % 8;
|
||||
if (font->bitmaps[byteIndex] & (0x80 >> bitIndex)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calcul de la couleur interpolée (RGB565)
|
||||
const uint8_t coverage = (count * 100) / scale_sq;// Pour éviter la division flottante
|
||||
const uint8_t R = (bg_R * (100 - coverage) + fg_R * coverage) / 100;
|
||||
const uint8_t G = (bg_G * (100 - coverage) + fg_G * coverage) / 100;
|
||||
const uint8_t B = (bg_B * (100 - coverage) + fg_B * coverage) / 100;
|
||||
const uint16_t blended_color = (R << 11) | (G << 5) | B;
|
||||
|
||||
// Dessin du pixel cible si dans les limites
|
||||
const int16_t absX = startX + tc;
|
||||
const int16_t absY = startY + tr;
|
||||
if (absX >= 0 && absX < LCD_WIDTH && absY >= 0 && absY < LCD_HEIGHT) {
|
||||
LCD_Draw_Pixel(absX, absY, blended_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
return x + (glyph->advance / scale);
|
||||
}
|
||||
|
||||
uint16_t GFX_GetTextWidth(
|
||||
const char *text,
|
||||
const GFXfont *font,
|
||||
int8_t letter_spacing) {
|
||||
uint16_t width = 0;
|
||||
|
||||
while (*text != '\0') {
|
||||
@@ -108,21 +253,87 @@ uint16_t GFX_DrawText(
|
||||
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;
|
||||
cursorX += letter_spacing;
|
||||
} else {
|
||||
// Default advance for unsupported characters
|
||||
cursorX += 10 + letter_spacing;
|
||||
}
|
||||
|
||||
cursorX = GFX_DrawChar(cursorX, cursorY, *text, font, fg_color, bg_color);
|
||||
cursorX += letter_spacing;
|
||||
text++;
|
||||
}
|
||||
if(alignment == 2) {
|
||||
if (alignment == 2) {
|
||||
return x;
|
||||
}
|
||||
return cursorX;
|
||||
}
|
||||
uint16_t GFX_ClearText(
|
||||
uint16_t x,
|
||||
uint16_t y,
|
||||
const char *text,
|
||||
const GFXfont *font,
|
||||
uint16_t bg_color,
|
||||
uint8_t alignment,
|
||||
int8_t letter_spacing) {
|
||||
|
||||
// Adjust x position based on alignment
|
||||
switch (alignment) {
|
||||
case 1:// Center
|
||||
x -= GFX_GetTextWidth(text, font, letter_spacing) / 2;
|
||||
break;
|
||||
case 2:// Right
|
||||
x -= GFX_GetTextWidth(text, font, letter_spacing);
|
||||
break;
|
||||
// Default: Left alignment (no adjustment)
|
||||
}
|
||||
|
||||
// Draw each character
|
||||
uint16_t cursorX = x;
|
||||
uint16_t cursorY = y;
|
||||
|
||||
while (*text != '\0') {
|
||||
cursorX = GFX_ClearChar(cursorX, cursorY, *text, font, bg_color);
|
||||
cursorX += letter_spacing;
|
||||
text++;
|
||||
}
|
||||
if (alignment == 2) {
|
||||
return x;
|
||||
}
|
||||
return cursorX;
|
||||
}
|
||||
uint16_t GFX_DrawTextScaled(
|
||||
uint16_t x,
|
||||
uint16_t y,
|
||||
const char *text,
|
||||
const GFXfont *font,
|
||||
uint16_t fg_color,
|
||||
uint16_t bg_color,
|
||||
uint8_t alignment,
|
||||
int8_t letter_spacing,
|
||||
uint8_t scale) {
|
||||
|
||||
uint16_t text_width = GFX_GetTextWidth(text, font, letter_spacing * scale);
|
||||
|
||||
if (scale != 1) {
|
||||
text_width /= scale;
|
||||
}
|
||||
// Adjust x position based on alignment
|
||||
switch (alignment) {
|
||||
case 1:// Center
|
||||
x -= text_width / 2;
|
||||
break;
|
||||
case 2:// Right
|
||||
x -= text_width;
|
||||
break;
|
||||
// Default: Left alignment (no adjustment)
|
||||
}
|
||||
|
||||
// Draw each character
|
||||
uint16_t cursorX = x;
|
||||
uint16_t cursorY = y;
|
||||
|
||||
while (*text != '\0') {
|
||||
cursorX = GFX_DrawCharScaled(cursorX, cursorY, *text, font, fg_color, bg_color,
|
||||
scale);
|
||||
cursorX += letter_spacing;
|
||||
text++;
|
||||
}
|
||||
if (alignment == 2) {
|
||||
return x;
|
||||
}
|
||||
return cursorX;
|
||||
|
||||
Reference in New Issue
Block a user