ILI9341_t3n did setTextBounds change?

clinker8

Well-known member
My old code used the following construct:
Code:
uint16_t x1, y1, w, h;
    oldZval = Zval;
    String newstr = "XXXXXXXXXXXX"; 
    tft.setFont(DroidSansMono_18);
    tft.setTextColor(ILI9341_GREEN, thisGREY);
    tft.getTextBounds(newstr, cxgZ, cygZ, &x1, &y1, &w, &h);
    tft.fillRect(x1, y1-1, w, h+1, thisGREY);

cxgZ and cygZ are int16_t. It worked fine until recently. Now I am getting a warning that there is a problem.
Code:
/home/bruce/Arduino/ELS_IDE2/DRO.ino: In function 'void updateZ()':
/home/bruce/Arduino/ELS_IDE2/DRO.ino:23:43: warning: invalid conversion from 'uint16_t*' {aka 'short unsigned int*'} to 'int16_t*' {aka 'short int*'} [-fpermissive]
   23 |     tft.getTextBounds(newstr, cxgZ, cygZ, &x1, &y1, &w, &h);
      |                                           ^~~
      |                                           |
      |                                           uint16_t* {aka short unsigned int*}

If I look up the method it seems there are two of them with the same name, but differing number of arguments.
Code:
  void getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
  void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);

What is the recommended way of getting this to work again? newstr was just a dummy so I'd be able to fill the rectangle.

Boy updated libs & IDE is a bugger. Shouldn't have done that... Changing 12 things at once - what a terrible idea.
 
Yes updating to new compiler that checks things more... can get you lots of warnings.

I did a quick look of the github source for the header file and the blame view says that the api changed 2 years ago.

Note some parameters are uint16_t (unsigned) and some are int16_t (signed).
Code:
void getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x, int16_t y,
                     int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
 
Odd, I haven't even been using Teensy that long... I only started 1 May 2022. I downloaded a zip file. Maybe the zip file was old?

Been a lot of confusion lately. So how does one use this? Minimal example? There are three methods in the source.
Code:
// Add in Adafruit versions of text bounds calculations.
void ILI9341_t3n::getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x,
                                int16_t y, int16_t *x1, int16_t *y1,
                                uint16_t *w, uint16_t *h) {
  *x1 = x;
  *y1 = y;
  *w = *h = 0;

  int16_t minx = _width, miny = _height, maxx = -1, maxy = -1;

  while (len--) {
    uint8_t c = *buffer++;
    charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy);
    //Serial.printf("%c in(%d %d) out(%d %d) - min(%d %d) max(%d %d)\n", c, *x1, *y1, x, y, minx, miny, maxx, maxy);
  }

  if (maxx >= minx) {
    *x1 = minx;
    *w = maxx - minx + 1;
  }
  if (maxy >= miny) {
    *y1 = miny;
    *h = maxy - miny + 1;
  }
  //Serial.printf("GTB %d %d %d %d\n", *x1, *y1, *w, *h);
}

void ILI9341_t3n::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 = _width, miny = _height, maxx = -1, maxy = -1;

  while ((c = *str++)) {
    charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy);
    //Serial.printf("%c in(%d %d) out(%d %d) - min(%d %d) max(%d %d)\n", c, *x1, *y1, x, y, minx, miny, maxx, maxy);
  }

  if (maxx >= minx) {
    *x1 = minx;
    *w = maxx - minx + 1;
  }
  if (maxy >= miny) {
    *y1 = miny;
    *h = maxy - miny + 1;
  }
  //Serial.printf("GTB %d %d %u %u\n", *x1, *y1, *w, *h);
}

void ILI9341_t3n::getTextBounds(const String &str, int16_t x, int16_t y,
                                int16_t *x1, int16_t *y1, uint16_t *w,
                                uint16_t *h) {
  if (str.length() != 0) {
    getTextBounds(const_cast<char *>(str.c_str()), x, y, x1, y1, w, h);
  }
}
Guess I am confused on how to make them work! What bugs me is the way I did it (at the top) did work from May 2022, until yesterday, until IDE2 was installed. Then everything broke. @KurtE can you throw me a bone? Thanks.
 
Guessing that you used older compiler and maybe either did not see the warnings or maybe did not generate them.

Yes there are three of them:
Code:
  void getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x, int16_t y,
                     int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
  void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1,
                     int16_t *y1, uint16_t *w, uint16_t *h);
  void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1,
                     int16_t *y1, uint16_t *w, uint16_t *h);
All very similar:
First one you can pass in buffer and length, second one you pass in character string, and it will search for terminating null character, and 3rd one you can pass in String object...
Looks like you are using the 2nd one.
Just change x1, y1 to int16_t instead of uint16_t.

Why...

Sometimes this has been used where you pass in X and Y of 0, and it returns the bounds. But some fonts draw outside of the bounds. That is they may draw part of a character
in the space of the previous character. Ran into this with GFX fonts. which is why they didn't support drawing in opaque mode.
 
Guessing that you used older compiler and maybe either did not see the warnings or maybe did not generate them.

Yes there are three of them:
Code:
  void getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x, int16_t y,
                     int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
  void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1,
                     int16_t *y1, uint16_t *w, uint16_t *h);
  void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1,
                     int16_t *y1, uint16_t *w, uint16_t *h);
All very similar:
First one you can pass in buffer and length, second one you pass in character string, and it will search for terminating null character, and 3rd one you can pass in String object...
Looks like you are using the 2nd one.
Just change x1, y1 to int16_t instead of uint16_t.

Why...

Sometimes this has been used where you pass in X and Y of 0, and it returns the bounds. But some fonts draw outside of the bounds. That is they may draw part of a character
in the space of the previous character. Ran into this with GFX fonts. which is why they didn't support drawing in opaque mode.

Hmm. Ok.

It seems in fillRect, the arguments are int16_t x, int16_t y, int16_t w, int16_t h, whereas w and h in getTextBounds are uint16_t. Guess I have to roll with it. Doesn't feel consistent, but that's me.
 
Back
Top