From 105c675622bf0ee61445b025db16d38921af76f4 Mon Sep 17 00:00:00 2001
From: Fabrice Weinberg <Fabrice@weinberg.me>
Date: Mon, 30 May 2016 11:06:26 +0200
Subject: [PATCH] Implement basic Print interface #35

---
 OLEDDisplay.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
 OLEDDisplay.h   | 26 +++++++++++++++++++++--
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/OLEDDisplay.cpp b/OLEDDisplay.cpp
index 445d41b..6b41dcc 100644
--- a/OLEDDisplay.cpp
+++ b/OLEDDisplay.cpp
@@ -506,6 +506,62 @@ void OLEDDisplay::clear(void) {
   memset(buffer, 0, DISPLAY_BUFFER_SIZE);
 }
 
+void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
+  setTextAlignment(TEXT_ALIGN_LEFT);
+  uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
+  uint16_t length = 0;
+  uint16_t line = 0;
+  uint16_t lastPos = 0;
+  for (uint16_t i=0;i<this->logBufferFilled;i++){
+    if (this->logBuffer[i] == 10) {
+      drawStringInternal(xMove, yMove + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0);
+      lastPos = i;
+      length = 0;
+    } else {
+      length++;
+    }
+  }
+  drawStringInternal(xMove, yMove + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0);
+}
+
+bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
+  if (logBuffer != NULL) free(logBuffer);
+  uint16_t size = lines * chars;
+  if (size > 0) {
+    this->logBufferMaxLines = lines;
+    this->logBufferLine     = 0;
+    this->logBufferSize     = size;
+    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;
+}
+
+size_t OLEDDisplay::write(uint8_t c) {
+  if (this->logBufferSize > 0) {
+    if (this->logBufferFilled < this->logBufferSize && this->logBufferLine < this->logBufferMaxLines) {
+      this->logBuffer[logBufferFilled] = utf8ascii(c);
+      this->logBufferFilled++;
+      if (c == 10) this->logBufferLine++;
+    } else {
+      if (this->logBufferLine <= this->logBufferMaxLines) this->logBufferLine = 0;
+      this->logBufferFilled = 0;
+      write(c);
+    }
+  }
+
+}
+
+size_t OLEDDisplay::write(const char* str) {
+  size_t length = strlen(str);
+  for (size_t i = 0; i < length; i++) {
+    write(str[i]);
+  }
+}
+
 // Private functions
 void OLEDDisplay::sendInitCommands(void) {
   sendCommand(DISPLAYOFF);
diff --git a/OLEDDisplay.h b/OLEDDisplay.h
index 226ecef..55fa694 100644
--- a/OLEDDisplay.h
+++ b/OLEDDisplay.h
@@ -108,7 +108,7 @@ enum OLEDDISPLAY_TEXT_ALIGNMENT {
 };
 
 
-class OLEDDisplay {
+class OLEDDisplay : public Print {
   public:
     // Initialize the display
     bool init();
@@ -210,6 +210,20 @@ class OLEDDisplay {
     // Clear the local pixel buffer
     void clear(void);
 
+    // Log buffer implementation
+
+    // 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.
+    bool setLogBuffer(uint16_t lines, uint16_t chars);
+
+    // Draw the log buffer at position (x, y)
+    void drawLogBuffer(uint16_t x, uint16_t y);
+
+    // Implementent needed function to be compatible with Print class
+    size_t write(uint8_t c);
+    size_t write(const char* s);
+
     uint8_t            *buffer;
 
     #ifdef OLEDDISPLAY_DOUBLE_BUFFER
@@ -217,10 +231,18 @@ class OLEDDisplay {
     #endif
 
   protected:
+
     OLEDDISPLAY_TEXT_ALIGNMENT   textAlignment = TEXT_ALIGN_LEFT;
     OLEDDISPLAY_COLOR            color         = WHITE;
 
-    const char          *fontData          = ArialMT_Plain_10;
+    const char          *fontData              = ArialMT_Plain_10;
+
+    // State values for logBuffer
+    uint16_t   logBufferSize                   = 0;
+    uint16_t   logBufferFilled                 = 0;
+    uint16_t   logBufferLine                   = 0;
+    uint16_t   logBufferMaxLines               = 0;
+    char      *logBuffer                       = NULL;
 
     // Send a command to the display (low level function)
     virtual void sendCommand(uint8_t com);
-- 
GitLab