Skip to content

Commit 943dd44

Browse files
authored
Merge branch 'master' into bugfix/memory_leaks
2 parents 2a3bdf8 + 9790e13 commit 943dd44

23 files changed

+976
-156
lines changed

OLEDDisplay.cpp

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ bool OLEDDisplay::init() {
3636
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Can't establish connection to display\n");
3737
return false;
3838
}
39+
3940
if(this->buffer==NULL) {
40-
this->buffer = (uint8_t*) malloc(sizeof(uint8_t) * DISPLAY_BUFFER_SIZE);
41+
this->buffer = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize);
42+
4143
if(!this->buffer) {
4244
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create display\n");
4345
return false;
@@ -46,7 +48,8 @@ bool OLEDDisplay::init() {
4648

4749
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
4850
if(this->buffer_back==NULL) {
49-
this->buffer_back = (uint8_t*) malloc(sizeof(uint8_t) * DISPLAY_BUFFER_SIZE);
51+
this->buffer_back = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize);
52+
5053
if(!this->buffer_back) {
5154
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create back buffer\n");
5255
free(this->buffer);
@@ -72,7 +75,7 @@ void OLEDDisplay::end() {
7275
void OLEDDisplay::resetDisplay(void) {
7376
clear();
7477
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
75-
memset(buffer_back, 1, DISPLAY_BUFFER_SIZE);
78+
memset(buffer_back, 1, displayBufferSize);
7679
#endif
7780
display();
7881
}
@@ -81,6 +84,10 @@ void OLEDDisplay::setColor(OLEDDISPLAY_COLOR color) {
8184
this->color = color;
8285
}
8386

87+
OLEDDISPLAY_COLOR OLEDDisplay::getColor() {
88+
return this->color;
89+
}
90+
8491
void OLEDDisplay::setPixel(int16_t x, int16_t y) {
8592
if (x >= 0 && x < this->width() && y >= 0 && y < this->height()) {
8693
switch (color) {
@@ -349,18 +356,18 @@ void OLEDDisplay::drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16
349356
drawHorizontalLine(xRadius, y + height, width - doubleRadius + 1);
350357
drawCircleQuads(x + width - radius, yRadius, radius, 0b00001001);
351358

352-
uint16_t maxProgressWidth = (width - doubleRadius - 1) * progress / 100;
359+
uint16_t maxProgressWidth = (width - doubleRadius + 1) * progress / 100;
353360

354361
fillCircle(xRadius, yRadius, innerRadius);
355362
fillRect(xRadius + 1, y + 2, maxProgressWidth, height - 3);
356363
fillCircle(xRadius + maxProgressWidth, yRadius, innerRadius);
357364
}
358365

359-
void OLEDDisplay::drawFastImage(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *image) {
366+
void OLEDDisplay::drawFastImage(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *image) {
360367
drawInternal(xMove, yMove, width, height, image, 0, 0);
361368
}
362369

363-
void OLEDDisplay::drawXbm(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *xbm) {
370+
void OLEDDisplay::drawXbm(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *xbm) {
364371
int16_t widthInXbm = (width + 7) / 8;
365372
uint8_t data = 0;
366373

@@ -536,7 +543,7 @@ void OLEDDisplay::setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment) {
536543
this->textAlignment = textAlignment;
537544
}
538545

539-
void OLEDDisplay::setFont(const char *fontData) {
546+
void OLEDDisplay::setFont(const uint8_t *fontData) {
540547
this->fontData = fontData;
541548
}
542549

@@ -568,13 +575,23 @@ void OLEDDisplay::setContrast(char contrast, char precharge, char comdetect) {
568575
sendCommand(DISPLAYON);
569576
}
570577

578+
void OLEDDisplay::resetOrientation() {
579+
sendCommand(SEGREMAP);
580+
sendCommand(COMSCANINC); //Reset screen rotation or mirroring
581+
}
582+
571583
void OLEDDisplay::flipScreenVertically() {
572584
sendCommand(SEGREMAP | 0x01);
573585
sendCommand(COMSCANDEC); //Rotate screen 180 Deg
574586
}
575587

588+
void OLEDDisplay::mirrorScreen() {
589+
sendCommand(SEGREMAP);
590+
sendCommand(COMSCANDEC); //Mirror screen
591+
}
592+
576593
void OLEDDisplay::clear(void) {
577-
memset(buffer, 0, DISPLAY_BUFFER_SIZE);
594+
memset(buffer, 0, displayBufferSize);
578595
}
579596

580597
void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
@@ -609,6 +626,14 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
609626
}
610627
}
611628

629+
uint16_t OLEDDisplay::getWidth(void) {
630+
return displayWidth;
631+
}
632+
633+
uint16_t OLEDDisplay::getHeight(void) {
634+
return displayHeight;
635+
}
636+
612637
bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
613638
if (logBuffer != NULL) free(logBuffer);
614639
uint16_t size = lines * chars;
@@ -631,12 +656,17 @@ size_t OLEDDisplay::write(uint8_t c) {
631656
// Don't waste space on \r\n line endings, dropping \r
632657
if (c == 13) return 1;
633658

659+
// convert UTF-8 character to font table index
660+
c = (this->fontTableLookupFunction)(c);
661+
// drop unknown character
662+
if (c == 0) return 1;
663+
634664
bool maxLineNotReached = this->logBufferLine < this->logBufferMaxLines;
635665
bool bufferNotFull = this->logBufferFilled < this->logBufferSize;
636666

637667
// Can we write to the buffer?
638668
if (bufferNotFull && maxLineNotReached) {
639-
this->logBuffer[logBufferFilled] = utf8ascii(c);
669+
this->logBuffer[logBufferFilled] = c;
640670
this->logBufferFilled++;
641671
// Keep track of lines written
642672
if (c == 10) this->logBufferLine++;
@@ -700,9 +730,21 @@ void OLEDDisplay::sendInitCommands(void) {
700730
sendCommand(SEGREMAP);
701731
sendCommand(COMSCANINC);
702732
sendCommand(SETCOMPINS);
703-
sendCommand(0x12); // according to the adafruit lib, sometimes this may need to be 0x02
733+
734+
if (geometry == GEOMETRY_128_64) {
735+
sendCommand(0x12);
736+
} else if (geometry == GEOMETRY_128_32) {
737+
sendCommand(0x02);
738+
}
739+
704740
sendCommand(SETCONTRAST);
705-
sendCommand(0xCF);
741+
742+
if (geometry == GEOMETRY_128_64) {
743+
sendCommand(0xCF);
744+
} else if (geometry == GEOMETRY_128_32) {
745+
sendCommand(0x8F);
746+
}
747+
706748
sendCommand(SETPRECHARGE);
707749
sendCommand(0xF1);
708750
sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)
@@ -713,7 +755,7 @@ void OLEDDisplay::sendInitCommands(void) {
713755
sendCommand(DISPLAYON);
714756
}
715757

716-
void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData) {
758+
void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) {
717759
if (width < 0 || height < 0) return;
718760
if (yMove + height < 0 || yMove > this->height()) return;
719761
if (xMove + width < 0 || xMove > this->width()) return;
@@ -743,7 +785,7 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
743785
// int16_t yScreenPos = yMove + yOffset;
744786
int16_t dataPos = xPos + yPos;
745787

746-
if (dataPos >= 0 && dataPos < DISPLAY_BUFFER_SIZE &&
788+
if (dataPos >= 0 && dataPos < displayBufferSize &&
747789
xPos >= 0 && xPos < this->width() ) {
748790

749791
if (yOffset >= 0) {
@@ -752,7 +794,8 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
752794
case BLACK: buffer[dataPos] &= ~(currentByte << yOffset); break;
753795
case INVERSE: buffer[dataPos] ^= currentByte << yOffset; break;
754796
}
755-
if (dataPos < (DISPLAY_BUFFER_SIZE - this->width())) {
797+
798+
if (dataPos < (displayBufferSize - this->width())) {
756799
switch (this->color) {
757800
case WHITE: buffer[dataPos + this->width()] |= currentByte >> (8 - yOffset); break;
758801
case BLACK: buffer[dataPos + this->width()] &= ~(currentByte >> (8 - yOffset)); break;
@@ -781,27 +824,6 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt
781824
}
782825
}
783826

784-
// Code form http://playground.arduino.cc/Main/Utf8ascii
785-
uint8_t OLEDDisplay::utf8ascii(byte ascii) {
786-
static uint8_t LASTCHAR;
787-
788-
if ( ascii < 128 ) { // Standard ASCII-set 0..0x7F handling
789-
LASTCHAR = 0;
790-
return ascii;
791-
}
792-
793-
uint8_t last = LASTCHAR; // get last char
794-
LASTCHAR = ascii;
795-
796-
switch (last) { // conversion depnding on first UTF8-character
797-
case 0xC2: return (ascii); break;
798-
case 0xC3: return (ascii | 0xC0); break;
799-
case 0x82: if (ascii == 0xAC) return (0x80); // special case Euro-symbol
800-
}
801-
802-
return 0; // otherwise: return zero, if character has to be ignored
803-
}
804-
805827
// You need to free the char!
806828
char* OLEDDisplay::utf8ascii(String str) {
807829
uint16_t k = 0;
@@ -818,7 +840,7 @@ char* OLEDDisplay::utf8ascii(String str) {
818840
length--;
819841

820842
for (uint16_t i=0; i < length; i++) {
821-
char c = utf8ascii(s[i]);
843+
char c = (this->fontTableLookupFunction)(s[i]);
822844
if (c!=0) {
823845
s[k++]=c;
824846
}
@@ -829,3 +851,7 @@ char* OLEDDisplay::utf8ascii(String str) {
829851
// This will leak 's' be sure to free it in the calling function.
830852
return s;
831853
}
854+
855+
void OLEDDisplay::setFontTableLookupFunction(FontTableLookupFunction function) {
856+
this->fontTableLookupFunction = function;
857+
}

0 commit comments

Comments
 (0)