diff --git a/src/helpers/ui/OLEDDisplay.cpp b/src/helpers/ui/OLEDDisplay.cpp index dca2ad1b98..c59a3acd8a 100644 --- a/src/helpers/ui/OLEDDisplay.cpp +++ b/src/helpers/ui/OLEDDisplay.cpp @@ -619,11 +619,8 @@ uint16_t OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, const cha uint16_t OLEDDisplay::drawString(int16_t xMove, int16_t yMove, const String &strUser) { uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS); - - // char* text must be freed! - char* text = strdup(strUser.c_str()); - if (!text) { - DEBUG_OLEDDISPLAY("[OLEDDISPLAY][drawString] Can't allocate char array.\n"); + const char* text = strUser.c_str(); + if (text == nullptr) { return 0; } @@ -642,13 +639,27 @@ uint16_t OLEDDisplay::drawString(int16_t xMove, int16_t yMove, const String &str uint16_t charDrawn = 0; uint16_t line = 0; - char* textPart = strtok(text,"\n"); - while (textPart != NULL) { - uint16_t length = strlen(textPart); - charDrawn += drawStringInternal(xMove, yMove - yOffset + (line++) * lineHeight, textPart, length, getStringWidth(textPart, length, true), true); - textPart = strtok(NULL, "\n"); + const char* lineStart = text; + while (true) { + const char* lineEnd = lineStart; + while (*lineEnd != 0 && *lineEnd != '\n') { + lineEnd++; + } + + if (lineEnd == lineStart && *lineEnd == '\n') { + lineStart = lineEnd + 1; + continue; + } + + uint16_t length = lineEnd - lineStart; + charDrawn += drawStringInternal(xMove, yMove - yOffset + (line++) * lineHeight, lineStart, length, + getStringWidth(lineStart, length, true), true); + + if (*lineEnd == 0) { + break; + } + lineStart = lineEnd + 1; } - free(text); return charDrawn; } diff --git a/src/helpers/ui/ST7789Spi.h b/src/helpers/ui/ST7789Spi.h index 09af6457df..d471cd45c9 100644 --- a/src/helpers/ui/ST7789Spi.h +++ b/src/helpers/ui/ST7789Spi.h @@ -103,9 +103,11 @@ class ST7789Spi : public OLEDDisplay { int _mosi; int _clk; SPIClass * _spi; - SPISettings _spiSettings; + SPISettings _spiSettings; uint16_t _RGB=0xFFFF; uint8_t _buffheight; + uint16_t* _pixbuf = nullptr; + uint32_t _pixbuf_capacity = 0; public: /* pass _cs as -1 to indicate "do not use CS pin", for cases where it is hard wired low */ ST7789Spi(SPIClass *spiClass,uint8_t _rst, uint8_t _dc, uint8_t _cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_RAWMODE,uint16_t width=240,uint16_t height=135,int mosi=-1,int miso=-1,int clk=-1) { @@ -121,9 +123,29 @@ class ST7789Spi : public OLEDDisplay { setGeometry(g,width,height); } + ~ST7789Spi() { + if (_pixbuf != nullptr) { + rtos_free(_pixbuf); + _pixbuf = nullptr; + _pixbuf_capacity = 0; + } + } + bool connect(){ this->_buffheight=displayHeight / 8; this->_buffheight+=displayHeight % 8 ? 1:0; + if (_pixbuf == nullptr || _pixbuf_capacity < displayWidth) { + uint16_t* new_pixbuf = (uint16_t *)rtos_malloc(sizeof(uint16_t) * displayWidth); + if (new_pixbuf == nullptr) { + _pixbuf_capacity = 0; + return false; + } + if (_pixbuf != nullptr) { + rtos_free(_pixbuf); + } + _pixbuf = new_pixbuf; + _pixbuf_capacity = displayWidth; + } pinMode(_cs, OUTPUT); pinMode(_dc, OUTPUT); //pinMode(_ledA, OUTPUT); @@ -186,27 +208,25 @@ class ST7789Spi : public OLEDDisplay { set_CS(LOW); _spi->beginTransaction(_spiSettings); - for (y = minBoundY; y <= maxBoundY; y++) - { - for(int temp = 0; temp<8;temp++) - { - //setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); - setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); - //setAddrWindow(y*8+temp,minBoundX,1,maxBoundX-minBoundX+1); - uint32_t const pixbufcount = maxBoundX-minBoundX+1; - uint16_t *pixbuf = (uint16_t *)rtos_malloc(2 * pixbufcount); - for (x = minBoundX; x <= maxBoundX; x++) - { - pixbuf[x-minBoundX] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0; - } + for (y = minBoundY; y <= maxBoundY; y++) + { + for(int temp = 0; temp<8;temp++) + { + //setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); + setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); + //setAddrWindow(y*8+temp,minBoundX,1,maxBoundX-minBoundX+1); + uint32_t const pixbufcount = maxBoundX-minBoundX+1; + for (x = minBoundX; x <= maxBoundX; x++) + { + _pixbuf[x-minBoundX] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0; + } #ifdef ESP_PLATFORM - _spi->transferBytes((uint8_t *)pixbuf, NULL, 2 * pixbufcount); + _spi->transferBytes((uint8_t *)_pixbuf, NULL, 2 * pixbufcount); #else - _spi->transfer(pixbuf, NULL, 2 * pixbufcount); + _spi->transfer(_pixbuf, NULL, 2 * pixbufcount); #endif - rtos_free(pixbuf); - } - } + } + } _spi->endTransaction(); set_CS(HIGH); @@ -214,27 +234,25 @@ class ST7789Spi : public OLEDDisplay { set_CS(LOW); _spi->beginTransaction(_spiSettings); uint8_t x, y; - for (y = 0; y < _buffheight; y++) - { - for(int temp = 0; temp<8;temp++) - { - //setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); - //setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); - setAddrWindow(y*8+temp,0,1,displayWidth); - uint32_t const pixbufcount = displayWidth; - uint16_t *pixbuf = (uint16_t *)rtos_malloc(2 * pixbufcount); - for (x = 0; x < displayWidth; x++) - { - pixbuf[x] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0; - } + for (y = 0; y < _buffheight; y++) + { + for(int temp = 0; temp<8;temp++) + { + //setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); + //setAddrWindow(minBoundX,y*8+temp,maxBoundX-minBoundX+1,1); + setAddrWindow(y*8+temp,0,1,displayWidth); + uint32_t const pixbufcount = displayWidth; + for (x = 0; x < displayWidth; x++) + { + _pixbuf[x] = ((buffer[x + y * displayWidth]>>temp)&0x01)==1?_RGB:0; + } #ifdef ESP_PLATFORM - _spi->transferBytes((uint8_t *)pixbuf, NULL, 2 * pixbufcount); + _spi->transferBytes((uint8_t *)_pixbuf, NULL, 2 * pixbufcount); #else - _spi->transfer(pixbuf, NULL, 2 * pixbufcount); + _spi->transfer(_pixbuf, NULL, 2 * pixbufcount); #endif - rtos_free(pixbuf); - } - } + } + } _spi->endTransaction(); set_CS(HIGH);