Skip to content

Commit 2ef5428

Browse files
authored
More printing fixes (#399)
* setLogBuffer needs to be re-called (and past buffer cleared) every time a `setFont` happens, as this changes the number of lines and chars. It now does not take arguments anymore and does things internally and is clearer about when it gives up. * calculation of shiftUp for when on last line was wrong * setLogBuffer() and drawLogBuffer() old versions with arguments deprecated, new versions protected. * Made no-op setLogBuffer return true to pass compiler error
1 parent 344fb49 commit 2ef5428

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

src/OLEDDisplay.cpp

+51-26
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,8 @@ void OLEDDisplay::setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment) {
752752

753753
void OLEDDisplay::setFont(const uint8_t *fontData) {
754754
this->fontData = fontData;
755+
// New font, so must recalculate. Whatever was there is gone at next print.
756+
setLogBuffer();
755757
}
756758

757759
void OLEDDisplay::displayOn(void) {
@@ -820,6 +822,10 @@ void OLEDDisplay::clear(void) {
820822
}
821823

822824
void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
825+
Serial.println("[deprecated] Print functionality now handles buffer management automatically. This is a no-op.");
826+
}
827+
828+
void OLEDDisplay::drawLogBuffer() {
823829
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
824830
// Always align left
825831
setTextAlignment(TEXT_ALIGN_LEFT);
@@ -832,15 +838,15 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
832838
// If the lineHeight and the display height are not cleanly divisible, we need
833839
// to start off the screen when the buffer has logBufferMaxLines so that the
834840
// first line, and not the last line, drops off.
835-
uint16_t shiftUp = (this->logBufferLine == this->logBufferMaxLines) ? displayHeight % lineHeight : 0;
841+
uint16_t shiftUp = (this->logBufferLine == this->logBufferMaxLines) ? (lineHeight - (displayHeight % lineHeight)) % lineHeight : 0;
836842

837843
for (uint16_t i=0;i<this->logBufferFilled;i++){
838844
length++;
839845
// Everytime we have a \n print
840846
if (this->logBuffer[i] == 10) {
841847
// Draw string on line `line` from lastPos to length
842848
// Passing 0 as the lenght because we are in TEXT_ALIGN_LEFT
843-
drawStringInternal(xMove, yMove - shiftUp + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0, false);
849+
drawStringInternal(0, 0 - shiftUp + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0, false);
844850
// Remember last pos
845851
lastPos = i;
846852
// Reset length
@@ -849,7 +855,7 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
849855
}
850856
// Draw the remaining string
851857
if (length > 0) {
852-
drawStringInternal(xMove, yMove - shiftUp + line * lineHeight, &this->logBuffer[lastPos], length, 0, false);
858+
drawStringInternal(0, 0 - shiftUp + line * lineHeight, &this->logBuffer[lastPos], length, 0, false);
853859
}
854860
}
855861

@@ -868,21 +874,44 @@ void OLEDDisplay::cls() {
868874
display();
869875
}
870876

871-
bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
872-
if (logBuffer != NULL) free(logBuffer);
877+
bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars) {
878+
Serial.println("[deprecated] Print functionality now handles buffer management automatically. This is a no-op.");
879+
return true;
880+
}
881+
882+
bool OLEDDisplay::setLogBuffer(){
883+
// don't know how big we need it without a font set.
884+
if (!fontData)
885+
return false;
886+
887+
// we're always starting over
888+
if (logBuffer != NULL)
889+
free(logBuffer);
890+
891+
// figure out how big it needs to be
892+
uint8_t textHeight = pgm_read_byte(fontData + HEIGHT_POS);
893+
if (!textHeight)
894+
return false; // Prevent division by zero crashes
895+
uint16_t lines = this->displayHeight / textHeight + (this->displayHeight % textHeight ? 1 : 0);
896+
uint16_t chars = 5 * (this->displayWidth / textHeight);
873897
uint16_t size = lines * (chars + 1); // +1 is for \n
874-
if (size > 0) {
875-
this->logBufferLine = 0; // Lines printed
876-
this->logBufferFilled = 0; // Nothing stored yet
877-
this->logBufferMaxLines = lines; // Lines max printable
878-
this->logBufferLineLen = chars; // Chars per line
879-
this->logBufferSize = size; // Total number of characters the buffer can hold
880-
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
881-
if(!this->logBuffer) {
882-
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\n");
883-
return false;
884-
}
898+
899+
// Something weird must have happened
900+
if (size == 0)
901+
return false;
902+
903+
// All good, initialize logBuffer
904+
this->logBufferLine = 0; // Lines printed
905+
this->logBufferFilled = 0; // Nothing stored yet
906+
this->logBufferMaxLines = lines; // Lines max printable
907+
this->logBufferLineLen = chars; // Chars per line
908+
this->logBufferSize = size; // Total number of characters the buffer can hold
909+
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
910+
if(!this->logBuffer) {
911+
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\n");
912+
return false;
885913
}
914+
886915
return true;
887916
}
888917

@@ -892,13 +921,9 @@ size_t OLEDDisplay::write(uint8_t c) {
892921

893922
// Create a logBuffer if there isn't one
894923
if (!logBufferSize) {
895-
uint8_t textHeight = pgm_read_byte(fontData + HEIGHT_POS);
896-
uint16_t lines = this->displayHeight / textHeight;
897-
uint16_t chars = 5 * (this->displayWidth / textHeight);
898-
899-
if (this->displayHeight % textHeight)
900-
lines++;
901-
setLogBuffer(lines, chars);
924+
// Give up if we can't create a logBuffer somehow
925+
if (!setLogBuffer())
926+
return 1;
902927
}
903928

904929
// Don't waste space on \r\n line endings, dropping \r
@@ -957,11 +982,11 @@ size_t OLEDDisplay::write(uint8_t c) {
957982
// Draw to screen unless we're writing a whole string at a time
958983
if (!this->inhibitDrawLogBuffer) {
959984
clear();
960-
drawLogBuffer(0, 0);
985+
drawLogBuffer();
961986
display();
962987
}
963988

964-
// We are always claim we printed it all
989+
// We always claim we printed it all
965990
return 1;
966991
}
967992

@@ -975,7 +1000,7 @@ size_t OLEDDisplay::write(const char* str) {
9751000
}
9761001
this->inhibitDrawLogBuffer = false;
9771002
clear();
978-
drawLogBuffer(0, 0);
1003+
drawLogBuffer();
9791004
display();
9801005
return length;
9811006
}

src/OLEDDisplay.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,7 @@ class OLEDDisplay : public Stream {
323323
// graphics buffer, which can then be shown on the display with display().
324324
void cls();
325325

326-
// This will define the lines and characters you can print to the screen.
327-
// When you exeed the buffer size (lines * chars) the output may be
328-
// truncated due to the size constraint. (Automatically called with the
329-
// correct parameters when you first print to the display.)
326+
// Replaced by setLogBuffer() , which is protected
330327
bool setLogBuffer(uint16_t lines, uint16_t chars);
331328

332329
// Draw the log buffer at position (x, y)
@@ -401,6 +398,13 @@ class OLEDDisplay : public Stream {
401398

402399
uint16_t drawStringInternal(int16_t xMove, int16_t yMove, const char* text, uint16_t textLength, uint16_t textWidth, bool utf8);
403400

401+
// (re)creates the logBuffer that printing uses to remember what was on the
402+
// screen already
403+
bool setLogBuffer();
404+
405+
// Draws the contents of the logBuffer to the screen
406+
void drawLogBuffer();
407+
404408
FontTableLookupFunction fontTableLookupFunction;
405409
};
406410

0 commit comments

Comments
 (0)