From 06dbc893dc4bfd5d4246ab8f4051ba19c54e9f5b Mon Sep 17 00:00:00 2001
From: CaptainStouf <stouf@hardware-libre.org>
Date: Sun, 22 May 2016 03:51:06 +0200
Subject: [PATCH] Added drawLine function

Signed-off-by: CaptainStouf <stouf@hardware-libre.org>
---
 README.md   |  4 ++++
 SSD1306.cpp | 40 ++++++++++++++++++++++++++++++++++++++++
 SSD1306.h   |  7 +++++++
 3 files changed, 51 insertions(+)

diff --git a/README.md b/README.md
index 37bb619..1bc96f4 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ The SSD1306Demo is a very comprehensive example demonstrating the most important
 ## Features
 
 * Draw pixels at given coordinates
+* Draw lines from given coordinates to given coordinates
 * Draw or fill a rectangle with given dimensions
 * Draw Text at given coordinates:
  * Define Alignment: Left, Right and Center
@@ -89,6 +90,9 @@ void setColor(SSD1306_COLOR color);
 // Draw a pixel at given position
 void setPixel(int16_t x, int16_t y);
 
+// Draw a line from position 0 to position 1
+void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
+
 // Draw the border of a rectangle at the given location
 void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
 
diff --git a/SSD1306.cpp b/SSD1306.cpp
index 29f8459..6f29054 100644
--- a/SSD1306.cpp
+++ b/SSD1306.cpp
@@ -96,6 +96,46 @@ void SSD1306::setPixel(int16_t x, int16_t y) {
   }
 }
 
+// Bresenham's algorithm - thx wikipedia and Adafruit_GFX
+void SSD1306::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
+  int16_t steep = abs(y1 - y0) > abs(x1 - x0);
+  if (steep) {
+    _swap_int16_t(x0, y0);
+    _swap_int16_t(x1, y1);
+  }
+
+  if (x0 > x1) {
+    _swap_int16_t(x0, x1);
+    _swap_int16_t(y0, y1);
+  }
+
+  int16_t dx, dy;
+  dx = x1 - x0;
+  dy = abs(y1 - y0);
+
+  int16_t err = dx / 2;
+  int16_t ystep;
+
+  if (y0 < y1) {
+    ystep = 1;
+  } else {
+    ystep = -1;
+  }
+
+  for (; x0<=x1; x0++) {
+    if (steep) {
+      setPixel(y0, x0);
+    } else {
+      setPixel(x0, y0);
+    }
+    err -= dy;
+    if (err < 0) {
+      y0 += ystep;
+      err += dx;
+    }
+  }
+}
+
 void SSD1306::drawRect(int16_t x, int16_t y, int16_t width, int16_t height) {
   drawHorizontalLine(x, y, width);
   drawVerticalLine(x, y, height);
diff --git a/SSD1306.h b/SSD1306.h
index 65f0828..3b878e6 100644
--- a/SSD1306.h
+++ b/SSD1306.h
@@ -91,6 +91,10 @@
 #define SETVCOMDETECT 0xDB
 #define SWITCHCAPVCC 0x2
 
+#ifndef _swap_int16_t
+#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
+#endif
+
 enum SSD1306_COLOR {
   BLACK = 0,
   WHITE = 1,
@@ -159,6 +163,9 @@ class SSD1306 {
 
     // Draw a pixel at given position
     void setPixel(int16_t x, int16_t y);
+    
+    // Draw a line from position 0 to position 1
+    void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
 
     // Draw the border of a rectangle at the given location
     void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
-- 
GitLab