General graphics tool

Dependents:   EPD_GDE021A1_demo

Files at this revision

API Documentation at this revision

Comitter:
steeven
Date:
Wed Apr 15 11:29:50 2015 +0000
Commit message:
General graphic lib

Changed in this revision

Graphic.cpp Show annotated file Show diff for this revision Revisions of this file
Graphic.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 404c38e71c68 Graphic.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphic.cpp	Wed Apr 15 11:29:50 2015 +0000
@@ -0,0 +1,283 @@
+#include "Graphic.h"
+
+/*
+ * Code derived from:
+ *  http://developer.mbed.org/users/dreschpe/code/EaEpaper/
+ */
+Graphic::Graphic(uint8_t *buf, int w, int h, int bits) :
+        _buf(buf), _w(w), _h(h), _bits(bits) {
+    clear();
+    color(0, (1 << bits) - 1);
+}
+
+// erase pixel after power up
+void Graphic::clear() {
+    memset(_buf, 0, _w * _h / (1 << _bits));
+    _charX = 0;
+    _charY = 0;
+}
+
+void Graphic::color(int foreground, int background) {
+    int mask = (1 << _bits) - 1;
+    _foreColor = foreground & mask;
+    _backgroundColor = background & mask;
+}
+
+// set one pixel in buffer _newImage
+void Graphic::pixel(int x, int y, unsigned int color) {
+    unsigned char *v;
+    unsigned char bak, pos;
+    // first check parameter
+    if (x > _w || y > _h || x < 0 || y < 0)
+        return;
+
+    color &= ((1 << _bits) - 1); // get valid color
+    //memory:y first, then x
+    v = &_buf[(x * _h * _bits / 8) + (y * _bits / 8)];
+
+    //pix saved in reverse order in a byte
+    pos = 8 - ((y * _bits) % 8) - _bits;
+
+    bak = *v & ~(((1 << _bits) - 1) << pos);
+    *v = bak + (color << pos);
+}
+
+// print line
+void Graphic::line(int x0, int y0, int x1, int y1) {
+    int dx = 0, dy = 0;
+    int dx_sym = 0, dy_sym = 0;
+    int dx_x2 = 0, dy_x2 = 0;
+    int di = 0;
+
+    dx = x1 - x0;
+    dy = y1 - y0;
+
+    if (dx > 0) {
+        dx_sym = 1;
+    } else {
+        dx_sym = -1;
+    }
+
+    if (dy > 0) {
+        dy_sym = 1;
+    } else {
+        dy_sym = -1;
+    }
+
+    dx = dx_sym * dx;
+    dy = dy_sym * dy;
+
+    dx_x2 = dx * 2;
+    dy_x2 = dy * 2;
+
+    if (dx >= dy) {
+        di = dy_x2 - dx;
+        while (x0 != x1) {
+
+            pixel(x0, y0, _foreColor);
+            x0 += dx_sym;
+            if (di < 0) {
+                di += dy_x2;
+            } else {
+                di += dy_x2 - dx_x2;
+                y0 += dy_sym;
+            }
+        }
+        pixel(x0, y0, _foreColor);
+    } else {
+        di = dx_x2 - dy;
+        while (y0 != y1) {
+            pixel(x0, y0, _foreColor);
+            y0 += dy_sym;
+            if (di < 0) {
+                di += dx_x2;
+            } else {
+                di += dx_x2 - dy_x2;
+                x0 += dx_sym;
+            }
+        }
+        pixel(x0, y0, _foreColor);
+    }
+}
+
+// print rect
+void Graphic::rect(int x0, int y0, int x1, int y1) {
+
+    if (x1 > x0)
+        line(x0, y0, x1, y0);
+    else
+        line(x1, y0, x0, y0);
+
+    if (y1 > y0)
+        line(x0, y0, x0, y1);
+    else
+        line(x0, y1, x0, y0);
+
+    if (x1 > x0)
+        line(x0, y1, x1, y1);
+    else
+        line(x1, y1, x0, y1);
+
+    if (y1 > y0)
+        line(x1, y0, x1, y1);
+    else
+        line(x1, y1, x1, y0);
+}
+
+// print filled rect
+void Graphic::fillrect(int x0, int y0, int x1, int y1) {
+    int l, c, i;
+    if (x0 > x1) {
+        i = x0;
+        x0 = x1;
+        x1 = i;
+    }
+
+    if (y0 > y1) {
+        i = y0;
+        y0 = y1;
+        y1 = i;
+    }
+
+    for (l = x0; l <= x1; l++) {
+        for (c = y0; c <= y1; c++) {
+            pixel(l, c, _foreColor);
+        }
+    }
+}
+
+// print circle
+void Graphic::circle(int x0, int y0, int r) {
+    int x = -r, y = 0, err = 2 - 2 * r, e2;
+    do {
+        pixel(x0 - x, y0 + y, _foreColor);
+        pixel(x0 + x, y0 + y, _foreColor);
+        pixel(x0 + x, y0 - y, _foreColor);
+        pixel(x0 - x, y0 - y, _foreColor);
+        e2 = err;
+        if (e2 <= y) {
+            err += ++y * 2 + 1;
+            if (-x == y && e2 <= x)
+                e2 = 0;
+        }
+        if (e2 > x)
+            err += ++x * 2 + 1;
+    } while (x <= 0);
+
+}
+
+// print filled circle
+void Graphic::fillcircle(int x0, int y0, int r) {
+    int x = -r, y = 0, err = 2 - 2 * r, e2;
+    do {
+        line(x0 - x, y0 - y, x0 - x, y0 + y);
+        line(x0 + x, y0 - y, x0 + x, y0 + y);
+        e2 = err;
+        if (e2 <= y) {
+            err += ++y * 2 + 1;
+            if (-x == y && e2 <= x)
+                e2 = 0;
+        }
+        if (e2 > x)
+            err += ++x * 2 + 1;
+    } while (x <= 0);
+}
+
+// set cursor position
+void Graphic::locate(int column, int row) {
+    _charX = column;
+    _charY = row;
+}
+
+// calc char columns
+int Graphic::columns() {
+    int fontW = _font[1];
+    return _w / fontW;
+}
+
+// calc char rows
+int Graphic::rows() {
+    int fontH = _font[2];
+    return _h / fontH;
+}
+
+// print char
+void Graphic::putc(int c) {
+    int y, x, w, offset; //font
+    unsigned char* font;
+
+    int fontBytes = _font[0];
+    //int fontW = _font[1];
+    int fontH = _font[2];
+    int fontColBytes = _font[3];
+
+
+    if (c == '\n') {    // new line
+        _charX = 0;
+        _charY = _charY + fontH;
+        if (_charY >= _h - fontH) {
+            _charY = 0;
+        }
+        return;
+    }
+    if ((c < 31) || (c > 127))
+        return;   // test char range
+
+
+    font = &_font[((c - 32) * fontBytes) + 4]; // start of char bitmap
+    w = font[0];                          // width of actual char
+    if (_charX + w > _w) {
+        _charX = 0;
+        _charY = _charY + fontH;
+        if (_charY >= _h - fontH) {
+            _charY = 0;
+        }
+    }
+
+    font++;
+    for (y = 0; y < fontH; y++) {  //  vert line
+        for (x = 0; x < w; x++) {   //  horz line
+            // vertical then horz in memory
+            offset = (x * fontColBytes + y / 8);
+            pixel(_charX + x, _charY + y,
+                    ((font[offset] >> (y % 8)) & 1) ?
+                            _foreColor : _backgroundColor);
+        }
+    }
+
+    _charX += w;
+}
+
+// set actual font
+void Graphic::font(const unsigned char* f) {
+    _font = (unsigned char *) f;
+}
+
+void Graphic::print(const char *str) {
+    while (*str) {
+        putc(*str);
+        str++;
+    }
+}
+
+void Graphic::print_bm(Bitmap bm, int x, int y) {
+    int h, v, b;
+    char d;
+
+    for (v = 0; v < bm.ySize; v++) {   // lines
+        for (h = 0; h < bm.xSize; h++) { // pixel
+            if (h + x > _w)
+                break;
+            if (v + y > _h)
+                break;
+            d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)];
+            b = 0x80 >> (h & 0x07);
+            if ((d & b) == 0) {
+                pixel(x + h, y + v, _backgroundColor);
+            } else {
+                pixel(x + h, y + v, _foreColor);
+            }
+        }
+    }
+
+}
diff -r 000000000000 -r 404c38e71c68 Graphic.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphic.h	Wed Apr 15 11:29:50 2015 +0000
@@ -0,0 +1,218 @@
+/* mbed library for 264*176 pixel 2.7 INCH E-PAPER DISPLAY from Pervasive Displays
+ * Copyright (c) 2013 Peter Drescher - DC2PD
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+// 09.11.2013   initial Version
+
+#ifndef Graphic_H
+#define Graphic_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+/** Bitmap
+ */
+struct Bitmap{
+    int xSize;
+    int ySize;
+    int Byte_in_Line;
+    char* data;
+    };
+
+/* color definitions   */
+#define Black           0x0
+#define White           0x3
+
+/** Display control class, based on sDisplay and TextDisplay
+ *
+ * Example with pinning for KL25Z:
+ * @code
+ * #include "mbed.h"
+ * #include "Graphic.h"
+ * #include "Arial28x28.h" 
+ * #include "Arial12x12.h"
+ * #include "font_big.h"
+ * #include "s.h"
+
+ * // the E-Paper board from embedded artists has a LM75 temp sensor to compensate the temperature effect. If it is cold the display reacts slower.
+ * // The LM75 need a I2C -> 2 pins : sda and scl 
+ * // The display data is written via SPI -> 3 pins : mosi,miso,sck
+ * // There are also some control signals 
+ * // The pwm pin has to be connected to a PWM enabled pin : pwm
+ * // The other signals are connected to normal IO`s
+ * //              
+ * Graphic epaper(PTD7,            // PWR_CTRL
+ *                 PTD6,            // BORDER
+ *                 PTE31,           // DISCHARGE
+ *                 PTA17,           // RESET_DISP
+ *                 PTA16,           // BUSY
+ *                 PTC17,           // SSEL
+ *                 PTD4,            // PWM
+ *                 PTD2,PTD3,PTD1,  // MOSI,MISO,SCLK
+ *                 PTE0,PTE1);      // SDA,SCL 
+ *
+ * int main() {
+ *
+ *   epaper.cls();                                  // clear screen                        
+ *   epaper.set_font((unsigned char*) Arial28x28);  // select the font
+ *   epaper.locate(5,20);                           // set cursor
+ *   epaper.printf("Hello Mbed");                   // print text
+ *   epaper.rect(3,15,150,50,1);                    // draw frame
+ *   epaper.write_disp();                           // update screen
+ *
+ * @endcode
+ */
+ 
+
+class Graphic {
+
+public:
+
+    /**
+     * Constructor.
+     */ 
+    Graphic(uint8_t *buf, int w, int h, int bits = 1);
+    
+    /**
+     * Set color
+     */
+    void color(int foreground, int background);
+
+    /**
+     * Clear the display
+     */    
+    void clear();
+    
+    /**
+     * set or reset a single pixel
+     *
+     * @param x horizontal position
+     * @param y vertical position
+     */ 
+    void pixel(int x, int y, unsigned int color);
+    
+    
+    /** draw a 1 pixel line
+     *
+     * @param x0,y0 start point
+     * @param x1,y1 stop point
+     */  
+    void line(int x0, int y0, int x1, int y1);
+    
+    /** draw a rect
+     *
+     * @param x0,y0 top left corner
+     * @param x1,y1 down right corner
+     */    
+    void rect(int x0, int y0, int x1, int y1);
+    
+    /** draw a filled rect
+     *
+     * @param x0,y0 top left corner
+     * @param x1,y1 down right corner
+     */  
+    void fillrect(int x0, int y0, int x1, int y1);
+    
+    /** draw a circle
+     *
+     * @param x0,y0 center
+     * @param r radius
+     */    
+    void circle(int x0, int y0, int r);
+    
+    /** draw a filled circle
+     *
+     * @param x0,y0 center
+     * @param r radius
+     */  
+    void fillcircle(int x0, int y0, int r);
+    
+    /** setup cursor position
+     *
+     * @param x x-position (top left)
+     * @param y y-position 
+     */   
+    void locate(int x, int y);
+    
+    /** calculate the max number of char in a line
+     *
+     * @returns max columns
+     * depends on actual font size
+     */ 
+    int columns();
+    
+    /** calculate the max number of columns
+     *
+     * @returns max column
+     * depends on actual font size
+     */   
+    int rows();
+    
+    /** put a char on the screen
+     *
+     * @param value char to print
+     * @returns printed char
+     */
+    void putc(int value);
+    
+    /** print a string on the screen
+     *
+     * @param str string to print
+     */
+    void print(const char *str);
+
+    /** select the font to use
+     *
+     * @param f pointer to font array 
+     *                                                                              
+     *   font array can created with GLCD Font Creator from http://www.mikroe.com
+     *   you have to add 4 parameter at the beginning of the font array to use: 
+     *   - the number of byte / char
+     *   - the vertial size in pixel
+     *   - the horizontal size in pixel
+     *   - the number of byte per vertical line
+     *   you also have to change the array to char[]
+     */  
+    void font(const unsigned char* f);
+    
+    /** print bitmap to buffer
+      *
+      * @param bm struct Bitmap in flash
+      * @param x  x start
+      * @param y  y start 
+      *
+      */
+    void print_bm(Bitmap bm, int x, int y);
+    
+    
+
+protected:
+
+
+    uint8_t *_buf; //drawing buffer
+
+    int _w; //screen width
+    int _h; //screeen height
+    char _bits; //per pix
+
+    int _foreColor;
+    int _backgroundColor;
+
+    unsigned char* _font;
+    int _charX;
+    int _charY;
+
+};
+ 
+ #endif /* Graphic_H */