arduino-libraries / ArduinoGraphics

35 stars 21 forks source link

Add API to set font size #3

Closed sandeepmistry closed 2 months ago

sandeepmistry commented 5 years ago

From @tigoe:

To set. One of the big issues I've found is readability of different fonts across different screens (been testing ePaper too), so having the ability to adapt fonts and sizes is essential.

KurtE commented 3 months ago

Not sure if better to comment on this 5 year old Issue, or to create a new one...

I fully agree. Using the built in font code on an Arduino GIGA Display shield, the built in fonts are more or less useless.

As I mentioned up on the Forum posting: https://forum.arduino.cc/t/arduino-h7-video-h-and-arduinographics-library-fonts/1289636/2

I am experimenting without actually updating the library, but in one of my test sketches I created a subclass of the Arduino_H7_Video class, where I added a method:

    void textSize(uint8_t xs = 1, uint8_t ys = 0);

My test sketch including the .h and .cpp file for the sub-class are up at: https://github.com/KurtE/Arduino_GIGA-stuff/tree/main/sketches/tft_picture_view_sd_giga_shield_24Bit

I had to replicate several of the ArduinoGraphics class as several of the member variables are marked private, like:

    const Font* _font;
    uint8_t _strokeR, _strokeG, _strokeB;
    uint8_t _backgroundR, _backgroundG, _backgroundB;
    bool _stroke = false;

The main functions are:

void Arduino_H7_Video_Plus::text(const char* str, int x, int y) {
    if (!_font || !_stroke) {
        return;
    }
    if ((_xTextScale == 1) && (_yTextScale == 1)) {
        ArduinoGraphics::text(str, x, y);
        return;
    }

    while (*str) {
        uint8_t const c = (uint8_t)*str++;

        if (c == '\n') {
            y += _font->height * _yTextScale;
        } else if (c == '\r') {
            x = 0;
        } else if (c == 0xc2 || c == 0xc3) {
            // drop
        } else {
            const uint8_t* b = _font->data[c];

            if (b == NULL) {
                b = _font->data[0x20];
            }

            if (b) {
                scaledBitmap(b, x, y, _font->width, _font->height);
            }

            x += _font->width * _xTextScale;
        }
    }
}
void Arduino_H7_Video_Plus::scaledBitmap(const uint8_t* data, int x, int y, int w, int h) {
    if (!_stroke || !_xTextScale || !_yTextScale) {
        return;
    }

    if ((data == nullptr) || ((x + (w * _xTextScale) < 0)) || ((y + (h * _yTextScale) < 0)) || (x > width()) || (y > height())) {
        // offscreen
        return;
    }

    int xStart = x;
    for (int j = 0; j < h; j++) {
        uint8_t b = data[j];
        for (uint8_t ys = 0; ys < _yTextScale; ys++) {
            if (ys >= height()) return;  //
            x = xStart;                  // reset for each row
            for (int i = 0; i < w; i++) {
                if (b & (1 << (7 - i))) {
                    for (uint8_t xs = 0; xs < _xTextScale; xs++) set(x++, y, _strokeR, _strokeG, _strokeB);
                } else {
                    for (uint8_t xs = 0; xs < _xTextScale; xs++) set(x++, y, _backgroundR, _backgroundG, _backgroundB);
                }
                if (x >= width()) break;
            }
            y++;
        }
    }
}

I have not updated any of the other methods, that potentially could include: textFontWidth(), textFontHeight() and the like.