@@ -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() {
7275void 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+
8491void 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+
571583void 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+
576593void OLEDDisplay::clear (void ) {
577- memset (buffer, 0 , DISPLAY_BUFFER_SIZE );
594+ memset (buffer, 0 , displayBufferSize );
578595}
579596
580597void 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+
612637bool 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!
806828char * 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