Adafruit gxf Textlänge in Pixel

Hallo in die Runde.
Ich möchte einen Text zentriert bzw rechtsbündig auf einem TFT-Display Ausgeben. Da die Zeichenbreite nicht konstant ist, möchte ich die Anzahl der Pixel berechnen.
In der Fontdatei gibt es die Liste mit den entsprechenden Werten.
Z.B.

const GFXglyph Lato_Bold_24Glyphs[] PROGMEM = {
// bitmapOffset, width, height, xAdvance, xOffset, yOffset
    {     0,   1,   1,   7,    0,    0 }, // ' '
    {     1,   4,  18,   8,    2,  -18 }, // '!'
    {    10,   8,   7,  10,    1,  -18 }, // '"'
    {    17,  15,  18,  15,    0,  -18 }, // '#'
    {    51,  13,  24,  15,    1,  -21 }, // '

Jetzt war mein Ansatz, die width-Werte der entsprechenden Buchstaben zu addieren.
Leider haut es nicht hin.
Ich hab folgendes probiert:

  Serial.println(Lato_Bold_24Glyphs[43].width);
  for (uint8_t i=40;i<51;i++) {
    Serial.print(i);
    Serial.print(" --> ");
    Serial.println(Lato_Bold_24Glyphs[ i].width);
  }
  Serial.println(Lato_Bold_24Glyphs[43].width);

Als Ergebnis erhalte ich folgendes:

16
40 --> 235
41 --> 163
42 --> 139
43 --> 205
44 --> 223
45 --> 158
46 --> 246
47 --> 157
48 --> 205
49 --> 211
50 --> 253
16

Solange ich den Wert fest eingebe, bekomme ich das richtige Ergebnis. Benutze ich eine Variable kommt ein falscher Wert heraus.
Wo ist mein Denkfehler?

Kalli


Jetzt war mein Ansatz, die width-Werte der entsprechenden Buchstaben zu addieren.
Leider haut es nicht hin.
Ich hab folgendes probiert:

§DISCOURSE_HOISTED_CODE_1§


Als Ergebnis erhalte ich folgendes:

§DISCOURSE_HOISTED_CODE_2§


Solange ich den Wert fest eingebe, bekomme ich das richtige Ergebnis. Benutze ich eine Variable kommt ein falscher Wert heraus.
Wo ist mein Denkfehler?

Kalli

Hallo Kalli,
ich glaube, es sind zwei Denkfehler drin.

Der erste (klein) ist die Verwendung von “width”. Ich würde intutiv eher “xAdvance” verwenden. Wenn der Schriftexperte mit Unterschneidungen arbeitete, sollte das der resultierenden Breite des Textes eher entsprechen.
Die Definition in gfxfont.h ist so:

/// Font data stored PER GLYPH
typedef struct {
  uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap
  uint8_t width;         ///< Bitmap dimensions in pixels
  uint8_t height;        ///< Bitmap dimensions in pixels
  uint8_t xAdvance;      ///< Distance to advance cursor (x axis)
  int8_t xOffset;        ///< X dist from cursor pos to UL corner
  int8_t yOffset;        ///< Y dist from cursor pos to UL corner
} GFXglyph;

Der zweite (größere) ist, dass die Font-Daten ja im PROGMEM stecken. Die kann man nicht mal eben einfach so verwenden, sondern man muss Zugriffsmethoden à la pgm_read_byte() verwenden.
Edit #1: Ich schrub Unsinn.
In der letzten Zeile (mit der festen 43) sieht man ja, dass es geht.
Muss ich nochmal genauer nachsehen.

Edit #2: Ich habe nachgesehen. Die Library bringt die gewünschte Funktion schon mit: getTextBounds() liefert u.a. auch die Breite des minimalen Rechtecks für den Text.

Wenn man da mal grob reinspickt, sieht man Aufrufe einer Methode charBounds() - die nutzt den xAdvance und liest die Werte tatsächlich mittels pgm_read_byte(). War also wohl doch nicht kompletter Unsinn.

Falls Du es doch selber machen willst:
In der Fontbeschreibung (Strukturtyp GFXfont) ist angegeben, welchen ASCII-Code das erste im Speicher abgelegte Zeichen hat (.first). Den Wert solltest Du dann von Deinem Zeichencode vorher abziehen.

Gruß Walter

Hallo Walter,
danke für die Auskunft. Es klappt alles wie gewünscht.

Kalli