/*
Forum: https://forum.arduino.cc/t/best-way-to-print-letters-with-strikethrough/1355282
Wokwi: https://wokwi.com/projects/423592044676936705
2025-02-22
ec2021
Realization of a "Strike Through" function for TFT displays that handles wrapping
Not "perfect": Word wrapping creates different text widths of a line.
This leads to the situation that the final letter(s) of a string is/are not always handled correctly.
Correction data have been implemented for this specific case here.
*/
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
struct FontData {
int charHeight;
int totalWidth;
int totalHeight;
} fontData;
constexpr int correction[5] = {0,0,10,10,10};
void setup() {
tft.begin();
tft.setRotation(0);
}
void loop() {
for (int i = 1; i < 6; i++) {
StrikeThrough("Strike This Through Strike This Through", 10, 10, i, ILI9341_RED);
delay(2000);
tft.fillScreen(ILI9341_BLACK);
}
}
void StrikeThrough(char * txt, int atX, int atY, int tSize, uint16_t col) {
tft.setCursor(atX, atY);
tft.setTextColor(col);
tft.setTextSize(tSize);
tft.println(txt);
fontData = getFontData(txt, atX, atY);
int i = 0;
while (fontData.totalWidth > 0) {
tft.drawFastHLine(atX, atY + fontData.charHeight / 2 + i * fontData.charHeight, fontData.totalWidth, ILI9341_YELLOW);
fontData.totalWidth = fontData.totalWidth-(tft.width()-atX);
if (fontData.totalWidth > 0 && fontData.totalWidth < tft.width() ) {
fontData.totalWidth = fontData.totalWidth + correction[tSize-1];
}
atX = 0;
i++;
}
};
FontData getFontData(char * txt, int atX, int atY) {
int boxX, boxY, width, height;
FontData ftData;
tft.setTextWrap(false);
tft.getTextBounds(txt, atX, atY, &boxX, &boxY, &width, &height);
ftData.charHeight = height;
ftData.totalWidth = width;
tft.setTextWrap(true);
tft.getTextBounds(txt, atX, atY, &boxX, &boxY, &width, &height);
ftData.totalHeight = height;
return ftData;
}