General graphics tool
Graphic.cpp
- Committer:
- steeven
- Date:
- 2015-04-15
- Revision:
- 0:404c38e71c68
File content as of revision 0:404c38e71c68:
#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); } } } }