Make text wrap work nicely

This commit is contained in:
Reed Nightingale 2020-01-19 12:56:47 -08:00
parent e65f4d57a4
commit 00f5d2691d
2 changed files with 62 additions and 17 deletions

View File

@ -145,6 +145,7 @@ public:
static void drawChar(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size); static void drawChar(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size);
static void drawCharGFX(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size); static void drawCharGFX(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size);
static inline void setCursor(coord_t x, coord_t y); static inline void setCursor(coord_t x, coord_t y);
static inline void setBound(coord_t x, coord_t y);
static inline void setTextColor(color_t c); static inline void setTextColor(color_t c);
static inline void setTextColor(color_t c, color_t bg); static inline void setTextColor(color_t c, color_t bg);
static inline void setTextSize(uint8_t s); static inline void setTextSize(uint8_t s);
@ -157,8 +158,8 @@ public:
static inline uint8_t getRotation() __attribute__ ((always_inline)) { return rotation; } static inline uint8_t getRotation() __attribute__ ((always_inline)) { return rotation; }
static inline coord_t getCursorX() __attribute__ ((always_inline)) { return cursor_x; } static inline coord_t getCursorX() __attribute__ ((always_inline)) { return cursor_x; }
static inline coord_t getCursorY() __attribute__ ((always_inline)) { return cursor_y; } static inline coord_t getCursorY() __attribute__ ((always_inline)) { return cursor_y; }
static inline void getTextBounds(char *string, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); static inline void getTextBounds(char *string, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi = _width);
static inline void getTextBounds(const __FlashStringHelper *s, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); static inline void getTextBounds(const __FlashStringHelper *s, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi = _width);
virtual size_t write(uint8_t); // used by Arduino "Print.h" (and the one required virtual function) virtual size_t write(uint8_t); // used by Arduino "Print.h" (and the one required virtual function)
@ -167,6 +168,7 @@ protected:
static coord_t WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes static coord_t WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes
static coord_t _width, _height; // Display w/h as modified by current rotation static coord_t _width, _height; // Display w/h as modified by current rotation
static coord_t cursor_x, cursor_y; static coord_t cursor_x, cursor_y;
static coord_t bound_x1, bound_x2;
static color_t textcolor, textbgcolor; static color_t textcolor, textbgcolor;
static uint8_t textsize; static uint8_t textsize;
static uint8_t rotation; static uint8_t rotation;
@ -216,6 +218,10 @@ int16_t PDQ_GFX<HW>::cursor_x;
template<class HW> template<class HW>
int16_t PDQ_GFX<HW>::cursor_y; int16_t PDQ_GFX<HW>::cursor_y;
template<class HW> template<class HW>
int16_t PDQ_GFX<HW>::bound_x1;
template<class HW>
int16_t PDQ_GFX<HW>::bound_x2;
template<class HW>
color_t PDQ_GFX<HW>::textcolor; color_t PDQ_GFX<HW>::textcolor;
template<class HW> template<class HW>
color_t PDQ_GFX<HW>::textbgcolor; color_t PDQ_GFX<HW>::textbgcolor;
@ -239,6 +245,8 @@ PDQ_GFX<HW>::PDQ_GFX(coord_t w, coord_t h)
_height = (int16_t)h; _height = (int16_t)h;
cursor_x = 0; cursor_x = 0;
cursor_y = 0; cursor_y = 0;
bound_x1 = 0;
bound_x2 = WIDTH;
rotation = 0; rotation = 0;
textsize = 1; textsize = 1;
textcolor = 0xffff; textcolor = 0xffff;
@ -756,10 +764,10 @@ size_t PDQ_GFX<HW>::write(uint8_t c)
if ((w > 0) && (h > 0)) if ((w > 0) && (h > 0))
{ {
coord_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic coord_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
if(wrap && ((cursor_x + textsize * (xo + w)) >= _width)) if(wrap && ((cursor_x + textsize * (xo + w)) >= bound_x2))
{ {
// Drawing character would go off right edge; wrap to new line // Drawing character would go off right edge; wrap to new line
cursor_x = 0; cursor_x = bound_x1;
cursor_y += (coord_t)textsize * cursor_y += (coord_t)textsize *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance); (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
} }
@ -970,6 +978,13 @@ void PDQ_GFX<HW>::setCursor(coord_t x, coord_t y)
cursor_y = (int16_t)y; cursor_y = (int16_t)y;
} }
template<class HW>
void PDQ_GFX<HW>::setBound(coord_t x1, coord_t x2)
{
bound_x1 = (int16_t)x1;
bound_x2 = (int16_t)x2;
}
template<class HW> template<class HW>
void PDQ_GFX<HW>::setTextSize(uint8_t s) void PDQ_GFX<HW>::setTextSize(uint8_t s)
{ {
@ -1046,10 +1061,13 @@ void PDQ_GFX<HW>::setFont(const GFXfont *f)
// Pass string and a cursor position, returns UL corner and W,H. // Pass string and a cursor position, returns UL corner and W,H.
template<class HW> template<class HW>
void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi)
{ {
uint8_t c; // Current character uint8_t c; // Current character
coord_t xs = x;
coord_t xe = xs+wi;
*x1 = x; *x1 = x;
*y1 = y; *y1 = y;
*w = *h = 0; *w = *h = 0;
@ -1080,9 +1098,9 @@ void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, in
xa = pgm_read_byte(&glyph->xAdvance); xa = pgm_read_byte(&glyph->xAdvance);
xo = pgm_read_byte(&glyph->xOffset); xo = pgm_read_byte(&glyph->xOffset);
yo = pgm_read_byte(&glyph->yOffset); yo = pgm_read_byte(&glyph->yOffset);
if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= _width)) // Line wrap if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= xe)) // Line wrap
{ {
x = 0; // Reset x to 0 x = xs; // Reset x to 0
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
gx1 = x + xo * ts; gx1 = x + xo * ts;
@ -1103,7 +1121,7 @@ void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, in
} }
else // Newline else // Newline
{ {
x = 0; // Reset x x = xs; // Reset x
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
} }
@ -1158,10 +1176,12 @@ void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, in
// Same as above, but for PROGMEM strings // Same as above, but for PROGMEM strings
template<class HW> template<class HW>
void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi)
{ {
uint8_t *s = (uint8_t *)str; uint8_t *s = (uint8_t *)str;
uint8_t c; uint8_t c;
coord_t xs = x;
coord_t xe = xs+wi;
*x1 = x; *x1 = x;
*y1 = y; *y1 = y;
@ -1194,9 +1214,9 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
xa = pgm_read_byte(&glyph->xAdvance); xa = pgm_read_byte(&glyph->xAdvance);
xo = pgm_read_byte(&glyph->xOffset); xo = pgm_read_byte(&glyph->xOffset);
yo = pgm_read_byte(&glyph->yOffset); yo = pgm_read_byte(&glyph->yOffset);
if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= _width)) // Line wrap if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= xe)) // Line wrap
{ {
x = 0; // Reset x to 0 x = xs; // Reset x to 0
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
gx1 = x + xo * ts; gx1 = x + xo * ts;
@ -1217,7 +1237,7 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
} }
else // Newline else // Newline
{ {
x = 0; // Reset x x = xs; // Reset x
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
} }

View File

@ -178,7 +178,7 @@ void displayInit(void){
tft.begin(); tft.begin();
tft.setFont(ubitx_font); tft.setFont(ubitx_font);
tft.setTextWrap(false); tft.setTextWrap(true);
tft.setTextColor(DISPLAY_GREEN,DISPLAY_BLACK); tft.setTextColor(DISPLAY_GREEN,DISPLAY_BLACK);
tft.setTextSize(1); tft.setTextSize(1);
tft.setRotation(1); tft.setRotation(1);
@ -217,6 +217,14 @@ void displayChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t
void displayRawText(char *text, int x1, int y1, int color, int background){ void displayRawText(char *text, int x1, int y1, int color, int background){
tft.setTextColor(color,background); tft.setTextColor(color,background);
tft.setCursor(x1,y1); tft.setCursor(x1,y1);
tft.setBound(0,320);
tft.print(text);
}
void displayRawText(char *text, int x1, int y1, int w, int color, int background){
tft.setTextColor(color,background);
tft.setCursor(x1,y1);
tft.setBound(x1,x1+w);
tft.print(text); tft.print(text);
} }
@ -228,10 +236,27 @@ void displayText(char *text, int x1, int y1, int w, int h, int color, int backgr
int16_t y1_out; int16_t y1_out;
uint16_t width_out; uint16_t width_out;
uint16_t height_out; uint16_t height_out;
tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out); tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out,w);
x1 += (w - ( width_out + (x1_out-x1)))/2; Serial.println(text);
y1 += h - (h - height_out)/2; Serial.print(F("Calc w/h:"));
displayRawText(text,x1,y1,color,background); Serial.print(width_out);
Serial.print(F(","));
Serial.println(height_out);
Serial.print(F("w/h:"));
Serial.print(w);
Serial.print(F(","));
Serial.println(h);
Serial.print(F("Old x1/y1:"));
Serial.print(x1);
Serial.print(F(","));
Serial.println(y1);
x1 += (w - ( (int32_t)width_out + (x1_out-x1)))/2;
y1 += (ubitx_font->yAdvance + h - ( (int32_t)height_out + (y1_out-y1)))/2;
Serial.print(F("New x1/y1:"));
Serial.print(x1);
Serial.print(F(","));
Serial.println(y1);
displayRawText(text,x1,y1,w,color,background);
} }
void setupTouch(){ void setupTouch(){