Skip to content

Commit

Permalink
More printing fixes (#399)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ropg committed Mar 17, 2024
1 parent 344fb49 commit 2ef5428
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 30 deletions.
77 changes: 51 additions & 26 deletions src/OLEDDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,8 @@ void OLEDDisplay::setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment) {

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

void OLEDDisplay::displayOn(void) {
Expand Down Expand Up @@ -820,6 +822,10 @@ void OLEDDisplay::clear(void) {
}

void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
Serial.println("[deprecated] Print functionality now handles buffer management automatically. This is a no-op.");
}

void OLEDDisplay::drawLogBuffer() {
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
// Always align left
setTextAlignment(TEXT_ALIGN_LEFT);
Expand All @@ -832,15 +838,15 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
// If the lineHeight and the display height are not cleanly divisible, we need
// to start off the screen when the buffer has logBufferMaxLines so that the
// first line, and not the last line, drops off.
uint16_t shiftUp = (this->logBufferLine == this->logBufferMaxLines) ? displayHeight % lineHeight : 0;
uint16_t shiftUp = (this->logBufferLine == this->logBufferMaxLines) ? (lineHeight - (displayHeight % lineHeight)) % lineHeight : 0;

for (uint16_t i=0;i<this->logBufferFilled;i++){
length++;
// Everytime we have a \n print
if (this->logBuffer[i] == 10) {
// Draw string on line `line` from lastPos to length
// Passing 0 as the lenght because we are in TEXT_ALIGN_LEFT
drawStringInternal(xMove, yMove - shiftUp + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0, false);
drawStringInternal(0, 0 - shiftUp + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0, false);
// Remember last pos
lastPos = i;
// Reset length
Expand All @@ -849,7 +855,7 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
}
// Draw the remaining string
if (length > 0) {
drawStringInternal(xMove, yMove - shiftUp + line * lineHeight, &this->logBuffer[lastPos], length, 0, false);
drawStringInternal(0, 0 - shiftUp + line * lineHeight, &this->logBuffer[lastPos], length, 0, false);
}
}

Expand All @@ -868,21 +874,44 @@ void OLEDDisplay::cls() {
display();
}

bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
if (logBuffer != NULL) free(logBuffer);
bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars) {
Serial.println("[deprecated] Print functionality now handles buffer management automatically. This is a no-op.");
return true;
}

bool OLEDDisplay::setLogBuffer(){
// don't know how big we need it without a font set.
if (!fontData)
return false;

// we're always starting over
if (logBuffer != NULL)
free(logBuffer);

// figure out how big it needs to be
uint8_t textHeight = pgm_read_byte(fontData + HEIGHT_POS);
if (!textHeight)
return false; // Prevent division by zero crashes
uint16_t lines = this->displayHeight / textHeight + (this->displayHeight % textHeight ? 1 : 0);
uint16_t chars = 5 * (this->displayWidth / textHeight);
uint16_t size = lines * (chars + 1); // +1 is for \n
if (size > 0) {
this->logBufferLine = 0; // Lines printed
this->logBufferFilled = 0; // Nothing stored yet
this->logBufferMaxLines = lines; // Lines max printable
this->logBufferLineLen = chars; // Chars per line
this->logBufferSize = size; // Total number of characters the buffer can hold
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
if(!this->logBuffer) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\n");
return false;
}

// Something weird must have happened
if (size == 0)
return false;

// All good, initialize logBuffer
this->logBufferLine = 0; // Lines printed
this->logBufferFilled = 0; // Nothing stored yet
this->logBufferMaxLines = lines; // Lines max printable
this->logBufferLineLen = chars; // Chars per line
this->logBufferSize = size; // Total number of characters the buffer can hold
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
if(!this->logBuffer) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\n");
return false;
}

return true;
}

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

// Create a logBuffer if there isn't one
if (!logBufferSize) {
uint8_t textHeight = pgm_read_byte(fontData + HEIGHT_POS);
uint16_t lines = this->displayHeight / textHeight;
uint16_t chars = 5 * (this->displayWidth / textHeight);

if (this->displayHeight % textHeight)
lines++;
setLogBuffer(lines, chars);
// Give up if we can't create a logBuffer somehow
if (!setLogBuffer())
return 1;
}

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

// We are always claim we printed it all
// We always claim we printed it all
return 1;
}

Expand All @@ -975,7 +1000,7 @@ size_t OLEDDisplay::write(const char* str) {
}
this->inhibitDrawLogBuffer = false;
clear();
drawLogBuffer(0, 0);
drawLogBuffer();
display();
return length;
}
Expand Down
12 changes: 8 additions & 4 deletions src/OLEDDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,7 @@ class OLEDDisplay : public Stream {
// graphics buffer, which can then be shown on the display with display().
void cls();

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

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

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

// (re)creates the logBuffer that printing uses to remember what was on the
// screen already
bool setLogBuffer();

// Draws the contents of the logBuffer to the screen
void drawLogBuffer();

FontTableLookupFunction fontTableLookupFunction;
};

Expand Down

0 comments on commit 2ef5428

Please sign in to comment.