Adjust displayGetTextBounds(); fix rendering issues at printBoatValueImpl()

This commit is contained in:
Ulrich Meine
2026-08-26 00:36:23 +02:00
parent 99f88cca3f
commit 18c1da5991
2 changed files with 95 additions and 52 deletions
+80 -43
View File
@@ -541,12 +541,12 @@ std::vector<String> wordwrap(String &line, uint16_t maxwidth) {
} }
// Draw centered text // Draw centered text
// bool dsegAdjust = false - optional, for adjustment of DSEG italic font
// returns left <x> edge of printed string // returns left <x> edge of printed string
int16_t drawTextCenter(int16_t cx, int16_t cy, String text) { int16_t drawTextCenter(int16_t cx, int16_t cy, String text, bool dsegAdjust) {
int16_t x1, y1; int16_t x1, y1;
uint16_t w, h; uint16_t w, h;
displayGetTextBounds(text, 0, 0, &x1, &y1, &w, &h, dsegAdjust);
displayGetTextBounds(text, 0, 0, &x1, &y1, &w, &h);
int16_t cursorX = cx - (x1 + static_cast<int16_t>(w / 2)); int16_t cursorX = cx - (x1 + static_cast<int16_t>(w / 2));
int16_t cursorY = cy - (y1 + static_cast<int16_t>(h / 2)); int16_t cursorY = cy - (y1 + static_cast<int16_t>(h / 2));
getdisplay().setCursor(cursorX, cursorY); getdisplay().setCursor(cursorX, cursorY);
@@ -586,15 +586,8 @@ void drawButtonCenter(int16_t cx, int16_t cy, int8_t sx, int8_t sy, String text,
int16_t drawTextRalign(int16_t x, int16_t y, const String& text, bool dsegAdjust) { int16_t drawTextRalign(int16_t x, int16_t y, const String& text, bool dsegAdjust) {
int16_t x1 = 0, y1 = 0; int16_t x1 = 0, y1 = 0;
uint16_t w = 0, h = 0; uint16_t w = 0, h = 0;
String str = text;
// make sure that we always have a char with max size at last position for boundary test displayGetTextBounds(text, 0, y, &x1, &y1, &w, &h, dsegAdjust);
// for monotype italic DSEG7 font to avoid text wobbling
if (dsegAdjust && str.length() > 0 && isDigit(str[str.length() - 1])) {
str.setCharAt(str.length() - 1, '8');
}
displayGetTextBounds(str, 0, y, &x1, &y1, &w, &h);
int16_t cursorX = x - x1 - w; int16_t cursorX = x - x1 - w;
getdisplay().setCursor(cursorX, y); getdisplay().setCursor(cursorX, y);
getdisplay().print(text); getdisplay().print(text);
@@ -605,28 +598,32 @@ int16_t drawTextRalign(int16_t x, int16_t y, const String& text, bool dsegAdjus
// Implementation of <printBoatValue()>; does the actual printing // Implementation of <printBoatValue()>; does the actual printing
static void printBoatValueImpl(const String &sBoatValue, const int16_t x, const int16_t y, static void printBoatValueImpl(const String &sBoatValue, const int16_t x, const int16_t y,
const int8_t align, const int8_t fontSize, bool smallDecs) { const int8_t align, const int8_t fontSize, bool smallDecs) {
const GFXfont *mainFont = NULL; const GFXfont *mainFont = nullptr;
const GFXfont *decimalFont = NULL; const GFXfont *decimalFont = nullptr;
constexpr bool dsegAdjust = true; constexpr bool dsegAdjust = true;
String integerPart = sBoatValue; String integerPart = "";
String decimalPart = ""; String decimalPart = "";
int16_t dot = 0; int16_t dot = 0;
int16_t decimalLeftX = x; // <x> printing position of decimals part of boat data value
int16_t x1 = 0, y1 = 0;
uint16_t w = 0, h = 0;
if (sBoatValue.indexOf('"') != -1) { uint16_t intW = 0, decW = 0;
// boat value string includes a <"> which indicates LAT/LON value -> requires another font than DSEG7 int16_t decimalLeftX = 0;
if (fontSize <= 12) {
// -----------------------------------------------------------------
// Font selection
// -----------------------------------------------------------------
if (sBoatValue.indexOf('"') != -1)
{
// LAT/LON values
if (fontSize <= 12)
mainFont = &Ubuntu_Bold12pt8b; mainFont = &Ubuntu_Bold12pt8b;
} else if (fontSize <= 16) { else if (fontSize <= 16)
mainFont = &Ubuntu_Bold16pt8b; mainFont = &Ubuntu_Bold16pt8b;
} else if (fontSize <= 20) { else if (fontSize <= 20)
mainFont = &Ubuntu_Bold20pt8b; mainFont = &Ubuntu_Bold20pt8b;
} else { else
mainFont = &Ubuntu_Bold32pt8b; mainFont = &Ubuntu_Bold32pt8b;
}
smallDecs = false; // disable small decimals for LAT/LON in any case smallDecs = false; // disable small decimals for LAT/LON in any case
} }
else if (fontSize <= 12) { else if (fontSize <= 12) {
@@ -652,35 +649,75 @@ static void printBoatValueImpl(const String &sBoatValue, const int16_t x, const
decimalFont = &DSEG7Classic_BoldItalic42pt7b; decimalFont = &DSEG7Classic_BoldItalic42pt7b;
} }
if (smallDecs) { // separate integer and decimal part of the value
dot = sBoatValue.indexOf('.'); dot = sBoatValue.indexOf('.');
if (dot != -1) { if (dot == -1) { // no decimal point found
integerPart = sBoatValue.substring(0, dot + 1); // includes '.' integerPart = sBoatValue;
decimalPart = "";
smallDecs = false; // print only integer part
} else {
integerPart = sBoatValue.substring(0, dot + 1); // keep decimal point
decimalPart = sBoatValue.substring(dot + 1); decimalPart = sBoatValue.substring(dot + 1);
} }
// Draw decimal part of boat data value
// -----------------------------------------------------------------
// Small decimals mode
// -----------------------------------------------------------------
if (smallDecs) {
// Measure integer part
int16_t ix1, iy1;
uint16_t iw, ih;
display.setFont(mainFont);
displayGetTextBounds(integerPart, 0, 0, &ix1, &iy1, &iw, &ih, dsegAdjust);
intW = ix1 + iw;
// Measure decimal part
int16_t dx1, dy1;
uint16_t dw, dh;
display.setFont(decimalFont); display.setFont(decimalFont);
if (align == 2) { displayGetTextBounds(decimalPart, 0, 0, &dx1, &dy1, &dw, &dh, dsegAdjust);
decimalLeftX = drawTextRalign(x, y, decimalPart, dsegAdjust); decW = dx1 + dw;
} else if (align == 1) {
decimalLeftX = drawTextCenter(x, y, decimalPart); const int16_t totalWidth = intW + decW;
displayGetTextBounds(decimalPart, 0, 0, &x1, &y1, &w, &h); int16_t startX;
decimalLeftX -= w / 2 - 1; switch (align) {
} else { case 0: // LEFT
displayGetTextBounds(decimalPart, 0, 0, &x1, &y1, &w, &h); startX = x;
getdisplay().setCursor(x + w + 1, y); break;
getdisplay().print(decimalPart); case 1: // CENTER
decimalLeftX = x; startX = x - totalWidth / 2;
break;
case 2: // RIGHT
default:
startX = x - totalWidth;
break;
} }
decimalLeftX = startX + intW;
// Draw integer part
display.setFont(mainFont);
getdisplay().setCursor(startX, y);
getdisplay().print(integerPart);
// Draw decimal part immediately after integer part
display.setFont(decimalFont);
getdisplay().setCursor(decimalLeftX, y);
getdisplay().print(decimalPart);
return;
} }
// Draw integer or full part of boat data value // -----------------------------------------------------------------
// Normal rendering (no small decimals)
// -----------------------------------------------------------------
display.setFont(mainFont); display.setFont(mainFont);
if (align == 2) { if (align == 2) {
drawTextRalign(decimalLeftX, y, integerPart, dsegAdjust); drawTextRalign(x, y, sBoatValue, dsegAdjust);
} else if (align == 1) {
drawTextCenter(x, y, sBoatValue, dsegAdjust);
} else { } else {
getdisplay().setCursor(decimalLeftX, y); getdisplay().setCursor(x, y);
getdisplay().print(integerPart); getdisplay().print(sBoatValue);
} }
} }
+10 -4
View File
@@ -697,11 +697,17 @@ inline void displaySetFullWindow() {
// replacement for getTextBounds that works with both EPD and TFT // replacement for getTextBounds that works with both EPD and TFT
inline void displayGetTextBounds(const String &txt, int16_t x, int16_t y, inline void displayGetTextBounds(const String &txt, int16_t x, int16_t y,
int16_t *x0, int16_t *y0, int16_t *x0, int16_t *y0,
uint16_t *w, uint16_t *h) { uint16_t *w, uint16_t *h, const bool dsegAdjust = false) {
String str = txt;
// make sure that we always have a char with max size at last position for boundary test
// for monotype italic DSEG7 font to avoid text wobbling
if (dsegAdjust && str.length() > 0 && isDigit(str[str.length() - 1])) {
str.setCharAt(str.length() - 1, '8');
}
#ifdef TFT_DISPLAY #ifdef TFT_DISPLAY
getdisplay().getTextBounds(txt, x, y, x0, y0, w, h); getdisplay().getTextBounds(str, x, y, x0, y0, w, h);
#else #else
getdisplay().getTextBounds(txt, x, y, x0, y0, w, h); getdisplay().getTextBounds(str, x, y, x0, y0, w, h);
#endif #endif
} }
@@ -734,7 +740,7 @@ void setBuzzerPower(uint power); // Set buzzer power
String xdrDelete(String input); // Delete xdr prefix from string String xdrDelete(String input); // Delete xdr prefix from string
int16_t drawTextCenter(int16_t cx, int16_t cy, String text); int16_t drawTextCenter(int16_t cx, int16_t cy, String text, bool dsegAdjust = false);
void drawButtonCenter(int16_t cx, int16_t cy, int8_t sx, int8_t sy, String text, uint16_t fg, uint16_t bg, bool inverted); void drawButtonCenter(int16_t cx, int16_t cy, int8_t sx, int8_t sy, String text, uint16_t fg, uint16_t bg, bool inverted);
int16_t drawTextRalign(int16_t x, int16_t y, const String& text, bool dsegAdjust = false); int16_t drawTextRalign(int16_t x, int16_t y, const String& text, bool dsegAdjust = false);
void drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border); void drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border);