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 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 setBound(coord_t x, coord_t y);
static inline void setTextColor(color_t c);
static inline void setTextColor(color_t c, color_t bg);
static inline void setTextSize(uint8_t s);
@ -157,8 +158,8 @@ public:
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 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(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(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, coord_t wi = _width);
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; // Display w/h as modified by current rotation
static coord_t cursor_x, cursor_y;
static coord_t bound_x1, bound_x2;
static color_t textcolor, textbgcolor;
static uint8_t textsize;
static uint8_t rotation;
@ -216,6 +218,10 @@ int16_t PDQ_GFX<HW>::cursor_x;
template<class HW>
int16_t PDQ_GFX<HW>::cursor_y;
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;
template<class HW>
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;
cursor_x = 0;
cursor_y = 0;
bound_x1 = 0;
bound_x2 = WIDTH;
rotation = 0;
textsize = 1;
textcolor = 0xffff;
@ -756,10 +764,10 @@ size_t PDQ_GFX<HW>::write(uint8_t c)
if ((w > 0) && (h > 0))
{
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
cursor_x = 0;
cursor_x = bound_x1;
cursor_y += (coord_t)textsize *
(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;
}
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>
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.
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
coord_t xs = x;
coord_t xe = xs+wi;
*x1 = x;
*y1 = y;
*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);
xo = pgm_read_byte(&glyph->xOffset);
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
}
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
{
x = 0; // Reset x
x = xs; // Reset x
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
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 c;
coord_t xs = x;
coord_t xe = xs+wi;
*x1 = x;
*y1 = y;
@ -1194,9 +1214,9 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
xa = pgm_read_byte(&glyph->xAdvance);
xo = pgm_read_byte(&glyph->xOffset);
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
}
gx1 = x + xo * ts;
@ -1217,7 +1237,7 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
}
else // Newline
{
x = 0; // Reset x
x = xs; // Reset x
y += ya; // Advance y by 1 line
}
}

View File

@ -178,7 +178,7 @@ void displayInit(void){
tft.begin();
tft.setFont(ubitx_font);
tft.setTextWrap(false);
tft.setTextWrap(true);
tft.setTextColor(DISPLAY_GREEN,DISPLAY_BLACK);
tft.setTextSize(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){
tft.setTextColor(color,background);
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);
}
@ -228,10 +236,27 @@ void displayText(char *text, int x1, int y1, int w, int h, int color, int backgr
int16_t y1_out;
uint16_t width_out;
uint16_t height_out;
tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out);
x1 += (w - ( width_out + (x1_out-x1)))/2;
y1 += h - (h - height_out)/2;
displayRawText(text,x1,y1,color,background);
tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out,w);
Serial.println(text);
Serial.print(F("Calc w/h:"));
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(){