Tft lcd lock screen adafruit st7735

I'm making a lock screen display on a TFT LCD with the Adafruit ST7735 library, but what I don't understand yet is how to make the text not have a background so it can follow the background on the screen and the text can still change as in the example in the image below?

in my code

uint16_t alphaBlend(uint16_t fg, uint16_t bg, uint8_t alpha) {
  // Ekstrak komponen RGB
  uint8_t fgR = (fg >> 11) & 0x1F;
  uint8_t fgG = (fg >> 5) & 0x3F;
  uint8_t fgB = fg & 0x1F;
  
  uint8_t bgR = (bg >> 11) & 0x1F;
  uint8_t bgG = (bg >> 5) & 0x3F;
  uint8_t bgB = bg & 0x1F;
  
  // Gunakan uint16_t untuk perhitungan sementara untuk menghindari overflow
  uint16_t r = (fgR * alpha + bgR * (255 - alpha)) >> 8;
  uint16_t g = (fgG * alpha + bgG * (255 - alpha)) >> 8;
  uint16_t b = (fgB * alpha + bgB * (255 - alpha)) >> 8;
  
  // Pastikan nilai tidak melebihi batas maksimum bit-field
  r = (r > 0x1F) ? 0x1F : r;
  g = (g > 0x3F) ? 0x3F : g;
  b = (b > 0x1F) ? 0x1F : b;
  
  // Kembalikan nilai RGB565
  return (r << 11) | (g << 5) | b;
}


// Fungsi untuk menggambar persegi panjang dengan alpha blending
void fillRectAlpha(Adafruit_ST7735 &tft, int16_t x, int16_t y, int16_t w, int16_t h, 
                  uint16_t color, uint8_t alpha) {
  // Jika alpha = 255 (tidak transparan), gunakan fillRect biasa
  if (alpha == 255) {
    tft.fillRect(x, y, w, h, color);
    return;
  }
  
  // Jika alpha = 0 (transparan penuh), tidak perlu melakukan apa-apa
  if (alpha == 0) {
    return;
  }
  
  // Buffer untuk menyimpan background
  uint16_t *buffer = new uint16_t[w * h];
  
  // Bagian ini memerlukan kemampuan readRect
  // Jika kontroler TFT Anda mendukungnya:
  // tft.readRect(x, y, w, h, buffer);
  
  // Jika readRect tidak tersedia, kita perlu menyimpan background secara manual
  // Ini lebih kompleks dan memerlukan penyimpanan state
  
  // Alternatif: Untuk implementasi sederhana, kita bisa menggunakan warna background yang diketahui
  for (int i = 0; i < w * h; i++) {
    buffer[i] = backgroundColor;
  }
  
  // Lakukan alpha blending untuk setiap pixel
  for (int j = 0; j < h; j++) {
    for (int i = 0; i < w; i++) {
      uint16_t blendedColor = alphaBlend(color, buffer[j * w + i], alpha);
      tft.drawPixel(x + i, y + j, blendedColor);
    }
  }
  
  // Hapus buffer
  delete[] buffer;
}

// If you need to clear a specific area, use this
void clearTextArea(int x, int y, const String& text, uint16_t clearColor) { // Tambahkan parameter clearColor
  int16_t x1, y1;
  uint16_t w, h;
  tft.getTextBounds(text, x, y, &x1, &y1, &w, &h);
  tft.fillRect(x1, y1, w, h, clearColor); // Gunakan clearColor untuk mengisi area
}

void updateTimeAndDate() {
  // Update waktu
  String hourStr = (hour() < 10 ? "0" : "") + String(hour());
  String minStr = (minute() < 10 ? "0" : "") + String(minute());

  // Simpan data jam dan menit
  String newTimeStr = hourStr + ":" + minStr;
  timeStr = newTimeStr;

  // Dapatkan hari dalam minggu (0-6, Minggu-Sabtu)
  int dayOfWeek = weekday() - 1; // Sesuaikan jika weekday() dimulai dari 1
  if (dayOfWeek < 0) dayOfWeek = 6; // Handling untuk memastikan indeks valid

  // Array nama bulan
  const char* monthNames[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
  const char* dayNames[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

  // Format tanggal baru: "WED, OCT 01"
  String dayStr = String(dayNames[dayOfWeek]) + ", " +
                  String(monthNames[month() - 1]) + " " +
                  (day() < 10 ? "0" : "") + String(day());

  dateStr = dayStr;
}

void displayMainTimeDate(int alignment) {
  int yBase = BORDER_START_Y + 81;
  // Mengatur font untuk waktu
  tft.setFont(&MADE_Tommy_Soft15pt7b);
  
  // Deklarasi variabel untuk dimensi dan posisi
  int16_t digitX1, digitY1;
  uint16_t digitW, digitH;
  
  // Mendapatkan detik saat ini
  int currentSecond = second();
  static int lastSecond = -1;
  
  // Mendapatkan digit-digit jam dan menit
  String hourDigit1 = String(timeStr[0]);
  String hourDigit2 = String(timeStr[1]);
  String colonStr = ":";
  String minDigit1 = String(timeStr[3]);
  String minDigit2 = String(timeStr[4]);
  
  // Mendapatkan lebar setiap digit
  tft.getTextBounds("0", 0, 0, &digitX1, &digitY1, &digitW, &digitH); // Menggunakan "0" sebagai referensi lebar
  
  // Menghitung lebar titik dua
  int16_t colonX1, colonY1;
  uint16_t colonW, colonH;
  tft.getTextBounds(colonStr, 0, 0, &colonX1, &colonY1, &colonW, &colonH);
  
  // Menghitung lebar total dengan spacing
  const int DIGIT_SPACING = 5; // Spacing antar semua karakter = 5px
  int fixedTotalWidth = (digitW * 4) + colonW + (DIGIT_SPACING * 4); // 4 digit + 1 titik dua + 4 spacing
  
  // Menghitung posisi awal berdasarkan alignment
  int startX;
  
  switch (alignment) {
    case TEXT_LEFT:
      startX = BORDER_START_X + CONTENT_MARGIN;
      break;
    case TEXT_RIGHT:
      startX = (BORDER_START_X + BORDER_WIDTH) - fixedTotalWidth - CONTENT_MARGIN;
      break;
    case TEXT_CENTER:
    default:
      startX = BORDER_START_X + (BORDER_WIDTH - fixedTotalWidth) / 2;
      break;
  }
  
  int y = yBase + 43;
  
  // Cek apakah waktu berubah untuk menggambar jam dan menit
  if (timeStr != prevTimeStr) {
    // Hapus seluruh area waktu dengan alpha blending (semi-transparan)
    fillRectAlpha(
      tft,
      BORDER_START_X, // Hapus seluruh area horizontal
      y + digitY1 - 4,
      BORDER_WIDTH,   // Lebar border penuh
      digitH + 8,
      backgroundColor,  // Warna dasar
      255               // Alpha value (0-255), 255 = tidak transparan
    );
    
    tft.setTextColor(safeColor565(255, 255, 255));
    
    // Gambar digit pertama jam
    tft.setCursor(startX, y);
    tft.print(hourDigit1);
    
    // Gambar digit kedua jam
    tft.setCursor(startX + digitW + DIGIT_SPACING, y);
    tft.print(hourDigit2);
    
    // Posisi untuk titik dua
    int colonX = startX + (digitW * 2) + (DIGIT_SPACING * 2);
    
    // Gambar digit pertama menit
    tft.setCursor(startX + (digitW * 2) + colonW + (DIGIT_SPACING * 3), y);
    tft.print(minDigit1);
    
    // Gambar digit kedua menit
    tft.setCursor(startX + (digitW * 3) + colonW + (DIGIT_SPACING * 4), y);
    tft.print(minDigit2);
    
    prevTimeStr = timeStr;
  }
  
  // Perbarui tanda : hanya jika detik berubah
  if (currentSecond != lastSecond) {
    lastSecond = currentSecond;
    // Posisi untuk titik dua
    int colonX = startX + (digitW * 2) + (DIGIT_SPACING * 2);
    int colonY = y;
    
    // Hapus area tanda : dengan alpha blending
    fillRectAlpha(
      tft,
      colonX + colonX1 - 2,
      colonY + colonY1 - 2,
      colonW + 4,
      colonH + 4,
      backgroundColor,  // Warna dasar
      255               // Alpha value (0-255), 255 = tidak transparan
    );
    
    // Menentukan visibilitas tanda : (detik genap tampil, ganjil hilang)
    bool shouldShowColon = (currentSecond % 2 == 0);
    
    // Gambar tanda : hanya jika harus terlihat
    if (shouldShowColon) {
      tft.setTextColor(safeColor565(255, 255, 255));
      tft.setCursor(colonX, colonY);
      tft.print(colonStr);
    }
  }
  
  // Display date with alignment matching the time
  tft.setFont(&MADE_Tommy_Soft5pt7b);
  if (dateStr != prevDateStr) {
    int16_t x1, y1;
    uint16_t w, h;
    tft.getTextBounds(dateStr, 0, 0, &x1, &y1, &w, &h);
    
    // Hitung posisi x untuk tanggal berdasarkan alignment yang sama
    int x;
    switch (alignment) {
      case TEXT_LEFT:
        x = BORDER_START_X + CONTENT_MARGIN;
        break;
      case TEXT_RIGHT:
        x = (BORDER_START_X + BORDER_WIDTH) - w - CONTENT_MARGIN;
        break;
      case TEXT_CENTER:
      default:
        x = BORDER_START_X + (BORDER_WIDTH - w) / 2;
        break;
    }
    
    int y = yBase + 58;
    const int CLEAR_PADDING = 2;
    
    // Menggunakan alpha blending untuk area tanggal
    fillRectAlpha(
      tft,
      BORDER_START_X,  // Hapus seluruh area horizontal
      y + y1 - CLEAR_PADDING,
      BORDER_WIDTH,    // Lebar border penuh
      h + (CLEAR_PADDING * 2),
      backgroundColor,  // Warna dasar
      255               // Alpha value (0-255), 255 = tidak transparan
    );
    
    tft.setTextColor(safeColor565(255, 255, 255));
    tft.setCursor(x, y);
    tft.print(dateStr);
    
    prevDateStr = dateStr;
  }
}

@bimosora by default the AdafruitGFX fonts have a transparent background. I believe with the newer fonts there is not even the option to set a background color. If you are using a custom font it might be worth considering replacing it with a similar Adafruit font.