Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getTextBounds missing #6

Closed
stanzlavos opened this issue Apr 9, 2017 · 5 comments
Closed

getTextBounds missing #6

stanzlavos opened this issue Apr 9, 2017 · 5 comments

Comments

@stanzlavos
Copy link

Hi

First of all, thanks for this fast lib. :)

Any plans to add "getTextBounds" API ? If not, I could try to add something and raise a pull request ?

@Bodmer
Copy link
Owner

Bodmer commented Apr 12, 2017

The "Free Fonts" can be rendered with background (unlike the stock Adafruit_GFX library) so I did not see a need for a getTextBounds function. See the "TFT_Custom_Fonts" or "Free_Font_Demo" examples.

When a "Free Font" is selected the library scans all characters in the set to determine the maximum y coordinate limits, so the background box always has the same height irrespective of what characters are drawn. This makes life easier as you don't need to do the messy box and erase coding yourself.

You can also add width padding to the background, so old text gets erased when over-writing. This is particularly useful for numbers that change as the erased box width can be fixed to be larger that the maximum digit count.

A getTextBounds function is clearly possible but would need to take into account the feature of the library to set the text coordinate datum (see "Free_Font_Demo" example).

@Bodmer Bodmer closed this as completed Apr 12, 2017
@stanzlavos
Copy link
Author

stanzlavos commented Apr 13, 2017 via email

@Bodmer
Copy link
Owner

Bodmer commented Apr 14, 2017

The sketch decides if the font is drawn with background or not, e.g.:

tft.setTextColor(TFT_WHITE, TFT_BLACK); // White characters with black background

tft.setTextColor(TFT_WHITE); // White characters no (transparent) background

The text can then be drawn using the drawString() function

If the print() method is used then background is not rendered for the FreeFonts for technical reasons (due to streaming of characters)

P.S. For centering text within a button frame use the setTextDatum(MC_DATUM) function and plot text at center coord of button (makes life easy!)

@stanzlavos
Copy link
Author

stanzlavos commented Apr 14, 2017 via email

@wilhelmzeuschner
Copy link

@stanzlavos I don't knwo whether this is still in any way relevant to you now but here's my quick and improvised solution (I essentially copied the code from the Adafruit GFX library and changed a few things so that now errors occurred during compilation).

Paste this code into your sketch:

void getTextBounds(const char *str, int16_t x, int16_t y,
	int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) {
	uint8_t c; // Current character

	*x1 = x;
	*y1 = y;
	*w = *h = 0;

	int16_t minx = tft.width(), miny = tft.width(), maxx = -1, maxy = -1;

	while ((c = *str++))
		charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy);

	if (maxx >= minx) {
		*x1 = minx;
		*w = maxx - minx + 1;
	}
	if (maxy >= miny) {
		*y1 = miny;
		*h = maxy - miny + 1;
	}
}

void charBounds(char c, int16_t *x, int16_t *y,
	int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy) {

	if (!true) {	//If non-default font is used not usable in my quick "hack"

		//if (c == '\n') { // Newline?
		//	*x = 0;    // Reset x to zero, advance y by one line
		//	*y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
		//}
		//else if (c != '\r') { // Not a carriage return; is normal char
		//	uint8_t first = pgm_read_byte(&gfxFont->first),
		//		last = pgm_read_byte(&gfxFont->last);
		//	if ((c >= first) && (c <= last)) { // Char present in this font?
		//		GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(
		//			&gfxFont->glyph))[c - first]);
		//		uint8_t gw = pgm_read_byte(&glyph->width),
		//			gh = pgm_read_byte(&glyph->height),
		//			xa = pgm_read_byte(&glyph->xAdvance);
		//		int8_t  xo = pgm_read_byte(&glyph->xOffset),
		//			yo = pgm_read_byte(&glyph->yOffset);
		//		if (wrap && ((*x + (((int16_t)xo + gw)*textsize)) > _width)) {
		//			*x = 0; // Reset x to zero, advance y by one line
		//			*y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
		//		}
		//		int16_t ts = (int16_t)textsize,
		//			x1 = *x + xo * ts,
		//			y1 = *y + yo * ts,
		//			x2 = x1 + gw * ts - 1,
		//			y2 = y1 + gh * ts - 1;
		//		if (x1 < *minx) *minx = x1;
		//		if (y1 < *miny) *miny = y1;
		//		if (x2 > *maxx) *maxx = x2;
		//		if (y2 > *maxy) *maxy = y2;
		//		*x += xa * ts;
		//	}
		//}

	}
	else { // Default font

		if (c == '\n') {                     // Newline?
			*x = 0;                        // Reset x to zero,
			*y += tft.textsize * 8;             // advance y one line
			// min/max x/y unchaged -- that waits for next 'normal' character
		}
		else if (c != '\r') {  // Normal char; ignore carriage returns
			if (/*wrap*/ false && ((*x + tft.textsize * 6) > tft.width())) { // Off right?
				*x = 0;                    // Reset x to zero,
				*y += tft.textsize * 8;         // advance y one line
			}
			int x2 = *x + tft.textsize * 6 - 1, // Lower-right pixel of char
				y2 = *y + tft.textsize * 8 - 1;
			if (x2 > *maxx) *maxx = x2;      // Track max x, y
			if (y2 > *maxy) *maxy = y2;
			if (*x < *minx) *minx = *x;      // Track min x, y
			if (*y < *miny) *miny = *y;
			*x += tft.textsize * 6;             // Advance x one char
		}
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants