@@ -391,9 +391,11 @@ void OLEDDisplay::drawXbm(int16_t xMove, int16_t yMove, int16_t width, int16_t h
391
391
}
392
392
393
393
void OLEDDisplay::drawStringInternal (int16_t xMove, int16_t yMove, char * text, uint16_t textLength, uint16_t textWidth) {
394
- uint8_t textHeight = pgm_read_byte (fontData + HEIGHT_POS);
395
- uint8_t firstChar = pgm_read_byte (fontData + FIRST_CHAR_POS);
396
- uint16_t sizeOfJumpTable = pgm_read_byte (fontData + CHAR_NUM_POS) * JUMPTABLE_BYTES;
394
+ if (fontData == nullptr ) return ;
395
+ const uint8_t textHeight = pgm_read_byte (fontData + HEIGHT_POS);
396
+ const uint8_t firstChar = pgm_read_byte (fontData + FIRST_CHAR_POS);
397
+ const uint8_t numberOfChars = pgm_read_byte (fontData + CHAR_NUM_POS);
398
+ const uint16_t sizeOfJumpTable = static_cast <uint16_t >(numberOfChars) * JUMPTABLE_BYTES;
397
399
398
400
uint8_t cursorX = 0 ;
399
401
uint8_t cursorY = 0 ;
@@ -417,33 +419,37 @@ void OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, char* text, u
417
419
if (yMove + textHeight < 0 || yMove > this ->width () ) {return ;}
418
420
419
421
for (uint16_t j = 0 ; j < textLength; j++) {
420
- int16_t xPos = xMove + cursorX;
421
- int16_t yPos = yMove + cursorY;
422
+ const int16_t xPos = xMove + cursorX;
423
+ const int16_t yPos = yMove + cursorY;
422
424
423
- uint8_t code = text[j];
425
+ const uint8_t code = text[j];
424
426
if (code >= firstChar) {
425
- uint8_t charCode = code - firstChar;
426
-
427
- // 4 Bytes per char code
428
- uint8_t msbJumpToChar = pgm_read_byte ( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES ); // MSB \ JumpAddress
429
- uint8_t lsbJumpToChar = pgm_read_byte ( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_LSB); // LSB /
430
- uint8_t charByteSize = pgm_read_byte ( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_SIZE); // Size
431
- uint8_t currentCharWidth = pgm_read_byte ( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_WIDTH); // Width
432
-
433
- // Test if the char is drawable
434
- if (!(msbJumpToChar == 255 && lsbJumpToChar == 255 )) {
435
- // Get the position of the char data
436
- uint16_t charDataPosition = JUMPTABLE_START + sizeOfJumpTable + ((msbJumpToChar << 8 ) + lsbJumpToChar);
437
- drawInternal (xPos, yPos, currentCharWidth, textHeight, fontData, charDataPosition, charByteSize);
438
- }
427
+ const uint8_t charCode = code - firstChar;
428
+ if (charCode < numberOfChars) {
429
+
430
+ // 4 Bytes per char code
431
+ const char * charOffset = fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES;
432
+ const uint8_t msbJumpToChar = pgm_read_byte ( charOffset ); // MSB \ JumpAddress
433
+ const uint8_t lsbJumpToChar = pgm_read_byte ( charOffset + JUMPTABLE_LSB); // LSB /
434
+ const uint8_t charByteSize = pgm_read_byte ( charOffset + JUMPTABLE_SIZE); // Size
435
+ const uint8_t currentCharWidth = pgm_read_byte ( charOffset + JUMPTABLE_WIDTH); // Width
436
+
437
+ // Test if the char is drawable
438
+ if (!(msbJumpToChar == 255 && lsbJumpToChar == 255 )) {
439
+ // Get the position of the char data
440
+ uint16_t charDataPosition = JUMPTABLE_START + sizeOfJumpTable + ((msbJumpToChar << 8 ) + lsbJumpToChar);
441
+ drawInternal (xPos, yPos, currentCharWidth, textHeight, fontData, charDataPosition, charByteSize);
442
+ }
439
443
440
- cursorX += currentCharWidth;
444
+ cursorX += currentCharWidth;
445
+ }
441
446
}
442
447
}
443
448
}
444
449
445
450
446
451
void OLEDDisplay::drawString (int16_t xMove, int16_t yMove, const String& strUser) {
452
+ if (fontData == nullptr ) return ;
447
453
uint16_t lineHeight = pgm_read_byte (fontData + HEIGHT_POS);
448
454
449
455
// char* text must be freed!
@@ -473,6 +479,7 @@ void OLEDDisplay::drawString(int16_t xMove, int16_t yMove, const String& strUser
473
479
}
474
480
475
481
void OLEDDisplay::drawStringMaxWidth (int16_t xMove, int16_t yMove, uint16_t maxLineWidth, const String& strUser) {
482
+ if (fontData == nullptr ) return ;
476
483
uint16_t firstChar = pgm_read_byte (fontData + FIRST_CHAR_POS);
477
484
uint16_t lineHeight = pgm_read_byte (fontData + HEIGHT_POS);
478
485
@@ -519,6 +526,7 @@ void OLEDDisplay::drawStringMaxWidth(int16_t xMove, int16_t yMove, uint16_t maxL
519
526
}
520
527
521
528
uint16_t OLEDDisplay::getStringWidth (const char * text, uint16_t length) {
529
+ if (fontData == nullptr ) return 0 ;
522
530
uint16_t firstChar = pgm_read_byte (fontData + FIRST_CHAR_POS);
523
531
524
532
uint16_t stringWidth = 0 ;
@@ -544,6 +552,7 @@ uint16_t OLEDDisplay::getStringWidth(const String& strUser) {
544
552
}
545
553
546
554
uint8_t OLEDDisplay::getCharWidth (const char c) {
555
+ if (fontData == nullptr ) return 0 ;
547
556
uint8_t firstChar = pgm_read_byte (fontData + FIRST_CHAR_POS);
548
557
if (utf8ascii (c) == 0 )
549
558
return 0 ;
@@ -577,15 +586,20 @@ void OLEDDisplay::normalDisplay(void) {
577
586
}
578
587
579
588
void OLEDDisplay::setContrast (char contrast, char precharge, char comdetect) {
580
- sendCommand (SETPRECHARGE); // 0xD9
581
- sendCommand (precharge); // 0xF1 default, to lower the contrast, put 1-1F
582
- sendCommand (SETCONTRAST);
583
- sendCommand (contrast); // 0-255
584
- sendCommand (SETVCOMDETECT); // 0xDB, (additionally needed to lower the contrast)
585
- sendCommand (comdetect); // 0x40 default, to lower the contrast, put 0
586
- sendCommand (DISPLAYALLON_RESUME);
587
- sendCommand (NORMALDISPLAY);
588
- sendCommand (DISPLAYON);
589
+ const uint8_t commands[] = {
590
+ SETPRECHARGE, // 0xD9
591
+ precharge, // 0xF1 default, to lower the contrast, put 1-1F
592
+ SETCONTRAST,
593
+ contrast, // 0-255
594
+ SETVCOMDETECT, // 0xDB, (additionally needed to lower the contrast)
595
+ comdetect, // 0x40 default, to lower the contrast, put 0
596
+ DISPLAYALLON_RESUME,
597
+ NORMALDISPLAY,
598
+ DISPLAYON
599
+ };
600
+ for (uint8_t i = 0 ; i < sizeof (commands); ++i) {
601
+ sendCommand (commands[i]);
602
+ }
589
603
}
590
604
591
605
void OLEDDisplay::flipScreenVertically () {
@@ -598,6 +612,7 @@ void OLEDDisplay::clear(void) {
598
612
}
599
613
600
614
void OLEDDisplay::drawLogBuffer (uint16_t xMove, uint16_t yMove) {
615
+ if (fontData == nullptr ) return ;
601
616
uint16_t lineHeight = pgm_read_byte (fontData + HEIGHT_POS);
602
617
// Always align left
603
618
setTextAlignment (TEXT_ALIGN_LEFT);
@@ -770,32 +785,36 @@ void OLEDDisplay::SetComPins(uint8_t _compins) {
770
785
771
786
// Private functions
772
787
void OLEDDisplay::sendInitCommands (void ) {
773
- sendCommand (DISPLAYOFF);
774
- sendCommand (SETDISPLAYCLOCKDIV);
775
- sendCommand (0xF0 ); // Increase speed of the display max ~96Hz
776
- sendCommand (SETMULTIPLEX);
777
- sendCommand (this ->height () - 1 );
778
- sendCommand (SETDISPLAYOFFSET);
779
- sendCommand (0x00 );
780
- sendCommand (SETSTARTLINE);
781
- sendCommand (CHARGEPUMP);
782
- sendCommand (0x14 );
783
- sendCommand (MEMORYMODE);
784
- sendCommand (0x00 );
785
- sendCommand (SEGREMAP);
786
- sendCommand (COMSCANINC);
787
- sendCommand (SETCOMPINS);
788
- sendCommand (0x12 ); // according to the adafruit lib, sometimes this may need to be 0x02
789
- sendCommand (SETCONTRAST);
790
- sendCommand (0xCF );
791
- sendCommand (SETPRECHARGE);
792
- sendCommand (0xF1 );
793
- sendCommand (SETVCOMDETECT); // 0xDB, (additionally needed to lower the contrast)
794
- sendCommand (0x40 ); // 0x40 default, to lower the contrast, put 0
795
- sendCommand (DISPLAYALLON_RESUME);
796
- sendCommand (NORMALDISPLAY);
797
- sendCommand (0x2e ); // stop scroll
798
- sendCommand (DISPLAYON);
788
+ const uint8_t commands[] = {
789
+ DISPLAYOFF,
790
+ SETDISPLAYCLOCKDIV,
791
+ 0xF0 , // Increase speed of the display max ~96Hz
792
+ SETMULTIPLEX,
793
+ static_cast <uint8_t >(this ->height () - 1 ), // FIXME TD-er: should add some checks here?
794
+ SETDISPLAYOFFSET,
795
+ 0x00 ,
796
+ SETSTARTLINE,
797
+ CHARGEPUMP,
798
+ 0x14 ,
799
+ MEMORYMODE,
800
+ 0x00 ,
801
+ SEGREMAP,
802
+ COMSCANINC,
803
+ SETCOMPINS,
804
+ 0x12 , // according to the adafruit lib, sometimes this may need to be 0x02
805
+ SETCONTRAST,
806
+ 0xCF ,
807
+ SETPRECHARGE,
808
+ 0xF1 ,
809
+ SETVCOMDETECT, // 0xDB, (additionally needed to lower the contrast)
810
+ 0x40 , // 0x40 default, to lower the contrast, put 0
811
+ DISPLAYALLON_RESUME,
812
+ NORMALDISPLAY,
813
+ 0x2e , // stop scroll
814
+ DISPLAYON};
815
+ for (uint8_t i = 0 ; i < sizeof (commands); ++i) {
816
+ sendCommand (commands[i]);
817
+ }
799
818
}
800
819
801
820
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) {
0 commit comments