help refreshing text with specific font - merged characters

Hello,

I have searched through the forums and have attempted several “fixes”. My issue is I am attempting to use a specific font. I don’t like the default font, so I picked one I thought looked good. For now, I am simply taking DH11 temp reading and printing it to the screen, updating the screen if the temp changes. Eventually, I will have several other things displaying on the screen so I would like to avoid doing a screen clear and repainting the entire screen.

When the temp changes and the text is refreshed. It is being painted over the existing text instead of the text area being refreshed. As you see in the code, I am setting text foreground and background in an attempt to “clear” the text area before writing the new temp.

I will also note, I am fairly new to this so I apologize if I am missing something obvious.

NOTE: setting the foreground and background color works with the default font…but not the one I am attempting to use. Which is puzzling, and the reason for this topic.

link to image - https://ibb.co/hoJ18J

//libraries for screen
#include <Adafruit_GFX.h>    // Core graphics library
#include <MCUFRIEND_kbv.h>   // Hardware-specific library
#include <Fonts/FreeSans12pt7b.h>
MCUFRIEND_kbv tft;

//stuff for DH11 sensor
double Fahrenheit(double celsius) {
  return 1.8 * celsius + 32;
}
#include <dht11.h>
dht11 DHT11;
#define DHT11PIN 40

//define colors
#define BLACK   0x0000
#define RED     0xF800
#define GREEN   0x07E0
#define WHITE   0xFFFF
#define GREY    0x8410

int temp = 0;

void setup(void)
{
    Serial.begin(9600);
    uint16_t ID = tft.readID();
    if (ID == 0xD3) ID = 0x9481;
    tft.begin(ID);
    tft.setRotation(1);
    tft.fillScreen(BLACK);
}

void loop() {

  int chk = DHT11.read(DHT11PIN);
  int tempnow = Fahrenheit(DHT11.temperature);

  if(tempnow != temp){
    
    Serial.print("temp-now is ");
    Serial.print(tempnow);
    Serial.println("");
    Serial.print("temp-was is ");
    Serial.print(temp);
    Serial.println("");
    
    temp = tempnow;
    
    homescreen_temp(tempnow);
    
  }
  delay(1000);

}

void homescreen_temp(int tempnow){
    int16_t x1, y1;
    uint16_t wid, ht;
    tft.setFont(&FreeSans12pt7b);
    //tft.setTextSize(2);
    tft.setCursor(20,20);
    tft.setTextColor(GREEN,BLACK);
    tft.print(tempnow);
    tft.print("F");
    delay(1000);
}

DON'T CROSS POST!!!!!!!!!!!!!!!!!!!!
http://forum.arduino.cc/index.php?topic=550665
I HAVE REPORTED THIS THREAD TO THE MODERATORS

Look at the example in this message

It gets fairly complicated with proportional fonts.
I suspect that your application just wants to print 99.9F.
So you know exactly what background rectangle to paint before printing the new value.

All the same, right justified numbers look much better than left justified dancing numbers.

And you can always draw text in attractive fonts but update "Sensor readings" in System font e.g. in x2.

David.

Edit. I would think that this Forum is more appropriate for this question.
Yes, it is always wise to mention if you have asked the same question elsewhere. i.e. post links on both sites and say which site is "preferred" to continue the discussion.

thank you sir!!!

I was able to follow that post and code and got it working. Spent several hours on this, thank you so much.

new code below.

//libraries for screen
#include <Adafruit_GFX.h>    // Core graphics library
#include <MCUFRIEND_kbv.h>   // Hardware-specific library
#include <Fonts/FreeSans12pt7b.h>
MCUFRIEND_kbv tft;

//stuff for DH11 sensor
double Fahrenheit(double celsius) {
  return 1.8 * celsius + 32;
}
#include <dht11.h>
dht11 DHT11;
#define DHT11PIN 40

//define colors
#define BLACK   0x0000
#define RED     0xF800
#define GREEN   0x07E0
#define WHITE   0xFFFF
#define GREY    0x8410

uint16_t bgcolor = BLACK;

int temp = 0;

void setup(void)
{
    Serial.begin(9600);
    uint16_t ID = tft.readID();
    if (ID == 0xD3) ID = 0x9481;
    tft.begin(ID);
    tft.setRotation(1);
    tft.fillScreen(BLACK);
}

void loop() {

  int chk = DHT11.read(DHT11PIN);
  int tempnow = Fahrenheit(DHT11.temperature);

  if(tempnow != temp){
    
    Serial.print("temp-now is ");
    Serial.print(tempnow);
    Serial.println("");
    Serial.print("temp-was is ");
    Serial.print(temp);
    Serial.println("");
    
    temp = tempnow;
    
    homescreen_temp(tempnow);
    
  }
  delay(1000);

}

void homescreen_temp(int tempnow){
  int x = 20;
  int y = 20;
    tft.setFont(&FreeSans12pt7b);
    tft.setCursor(x, y);
    tft.setTextColor(GREEN,BLACK);
    rightjustify(x, y, tempnow, 2, 0);
    tft.print("F");
    delay(1000);
}

//display text properly.
int rightjustify(int x, int y, double num, int wid, int prec)
{
    //calculate background every time
    char buf[12];
    int16_t x1, y1;
    uint16_t w, h;
    memset(buf, '0', wid);    //"0000000"
    buf[wid] = '\0';
    tft.getTextBounds(buf, x, y, &x1, &y1, &w, &h);
    //paint the background starting at x
    tft.fillRect(x, y1, w, h, bgcolor);
    //remember the full width of "0000000"
    uint16_t rt = w;
    //format the result.  works for integers too e.g. prec = 0
    //STM32 Core from ST MicroElectronics is bad format
    dtostrf(num, wid, prec, buf);
    //calculate the width of new string
    tft.getTextBounds(buf, x, y, &x1, &y1, &w, &h);
    int16_t xofs = x1 - x;
    //adjust for the correct print position
    tft.setCursor(x + rt - w - xofs, y);
    //this prints transparently on the fresh background
    tft.print(buf);
    return w;
}

how can you use this method to print text in a similar manner? Or is this only for numerical values.

In practice you know where you are printing text. You can either just paint a big enough background or you get the actual dimension of the previous text.