diff --git a/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.cpp b/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.cpp index 22a258e..5001d55 100644 --- a/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.cpp +++ b/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.cpp @@ -677,6 +677,63 @@ uint16_t OLEDDisplay::drawStringMaxWidth(int16_t xMove, int16_t yMove, uint16_t uint16_t firstLineChars = 0; uint16_t drawStringResult = 1; // later tested for 0 == error, so initialize to 1 + for (uint16_t i = 0; i < length; i++) { + char c = (this->fontTableLookupFunction)(text[i]); + if (c == 0) + continue; + strWidth += pgm_read_byte(fontData + JUMPTABLE_START + (c - firstChar) * JUMPTABLE_BYTES + JUMPTABLE_WIDTH); + + // Always try to break on a space, dash or slash + if (text[i] == ' ' || text[i]== '-' || text[i] == '/') { + preferredBreakpoint = i + 1; + widthAtBreakpoint = strWidth; + } + + if (strWidth >= maxLineWidth) { + if (preferredBreakpoint == 0) { + preferredBreakpoint = i; + widthAtBreakpoint = strWidth; + } + drawStringResult = drawStringInternal(xMove, yMove + (lineNumber++) * lineHeight , &text[lastDrawnPos], preferredBreakpoint - lastDrawnPos, widthAtBreakpoint, true); + if (firstLineChars == 0) + firstLineChars = preferredBreakpoint; + lastDrawnPos = preferredBreakpoint; + // It is possible that we did not draw all letters to i so we need + // to account for the width of the chars from `i - preferredBreakpoint` + // by calculating the width we did not draw yet. + strWidth = strWidth - widthAtBreakpoint; + preferredBreakpoint = 0; + if (drawStringResult == 0) // we are past the display already? + break; + } + } + + // Draw last part if needed + if (drawStringResult != 0 && lastDrawnPos < length) { + drawStringResult = drawStringInternal(xMove, yMove + (lineNumber++) * lineHeight , &text[lastDrawnPos], length - lastDrawnPos, getStringWidth(&text[lastDrawnPos], length - lastDrawnPos, true), true); + } + + if (drawStringResult == 0 || (yMove + lineNumber * lineHeight) >= this->height()) // text did not fit on screen + return firstLineChars; + return 0; // everything was drawn +} + +uint16_t OLEDDisplay::FDRS_drawStringMaxWidth(int16_t xMove, int16_t yMove, uint16_t maxLineWidth, const String &strUser) { + uint16_t firstChar = pgm_read_byte(fontData + FIRST_CHAR_POS); + uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS); + + const char* text = strUser.c_str(); + + uint16_t length = strlen(text); + uint16_t lastDrawnPos = 0; + uint16_t lineNumber = 0; + uint16_t strWidth = 0; + + uint16_t preferredBreakpoint = 0; + uint16_t widthAtBreakpoint = 0; + uint16_t firstLineChars = 0; + uint16_t drawStringResult = 1; // later tested for 0 == error, so initialize to 1 + for (uint16_t i = 0; i < length; i++) { char c = (this->fontTableLookupFunction)(text[i]); if (c == 0) diff --git a/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.h b/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.h index 12cc0c3..7d670a6 100644 --- a/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.h +++ b/src/ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/OLEDDisplay.h @@ -254,7 +254,12 @@ class OLEDDisplay : public Stream { // returns 0 if everything fits on the screen or the numbers of characters in the // first line if not uint16_t drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text); - + + + // Modified version with closer spacing. Also returns number of lines used. + + uint16_t FDRS_drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text); + // Returns the width of the const char* with the current // font settings uint16_t getStringWidth(const char* text, uint16_t length, bool utf8 = false); diff --git a/src/fdrs_gateway_oled.h b/src/fdrs_gateway_oled.h index 1fa5061..a409dc9 100644 --- a/src/fdrs_gateway_oled.h +++ b/src/fdrs_gateway_oled.h @@ -34,7 +34,7 @@ void debug_OLED(String debug_text) uint8_t lineNumber = 0; for (uint8_t i = 0; i < 5; i++) { - uint8_t ret = display.drawStringMaxWidth(0, 17 + (lineNumber * 9), 127, debug_buffer[i]); + uint8_t ret = display.FDRS_drawStringMaxWidth(0, 17 + (lineNumber * 9), 127, debug_buffer[i]); lineNumber = ret + lineNumber; if (lineNumber > 5) break;