General graphics tool

Dependents:   EPD_GDE021A1_demo

Committer:
steeven
Date:
Wed Apr 15 11:29:50 2015 +0000
Revision:
0:404c38e71c68
General graphic lib

Who changed what in which revision?

UserRevisionLine numberNew contents of line
steeven 0:404c38e71c68 1 #include "Graphic.h"
steeven 0:404c38e71c68 2
steeven 0:404c38e71c68 3 /*
steeven 0:404c38e71c68 4 * Code derived from:
steeven 0:404c38e71c68 5 * http://developer.mbed.org/users/dreschpe/code/EaEpaper/
steeven 0:404c38e71c68 6 */
steeven 0:404c38e71c68 7 Graphic::Graphic(uint8_t *buf, int w, int h, int bits) :
steeven 0:404c38e71c68 8 _buf(buf), _w(w), _h(h), _bits(bits) {
steeven 0:404c38e71c68 9 clear();
steeven 0:404c38e71c68 10 color(0, (1 << bits) - 1);
steeven 0:404c38e71c68 11 }
steeven 0:404c38e71c68 12
steeven 0:404c38e71c68 13 // erase pixel after power up
steeven 0:404c38e71c68 14 void Graphic::clear() {
steeven 0:404c38e71c68 15 memset(_buf, 0, _w * _h / (1 << _bits));
steeven 0:404c38e71c68 16 _charX = 0;
steeven 0:404c38e71c68 17 _charY = 0;
steeven 0:404c38e71c68 18 }
steeven 0:404c38e71c68 19
steeven 0:404c38e71c68 20 void Graphic::color(int foreground, int background) {
steeven 0:404c38e71c68 21 int mask = (1 << _bits) - 1;
steeven 0:404c38e71c68 22 _foreColor = foreground & mask;
steeven 0:404c38e71c68 23 _backgroundColor = background & mask;
steeven 0:404c38e71c68 24 }
steeven 0:404c38e71c68 25
steeven 0:404c38e71c68 26 // set one pixel in buffer _newImage
steeven 0:404c38e71c68 27 void Graphic::pixel(int x, int y, unsigned int color) {
steeven 0:404c38e71c68 28 unsigned char *v;
steeven 0:404c38e71c68 29 unsigned char bak, pos;
steeven 0:404c38e71c68 30 // first check parameter
steeven 0:404c38e71c68 31 if (x > _w || y > _h || x < 0 || y < 0)
steeven 0:404c38e71c68 32 return;
steeven 0:404c38e71c68 33
steeven 0:404c38e71c68 34 color &= ((1 << _bits) - 1); // get valid color
steeven 0:404c38e71c68 35 //memory:y first, then x
steeven 0:404c38e71c68 36 v = &_buf[(x * _h * _bits / 8) + (y * _bits / 8)];
steeven 0:404c38e71c68 37
steeven 0:404c38e71c68 38 //pix saved in reverse order in a byte
steeven 0:404c38e71c68 39 pos = 8 - ((y * _bits) % 8) - _bits;
steeven 0:404c38e71c68 40
steeven 0:404c38e71c68 41 bak = *v & ~(((1 << _bits) - 1) << pos);
steeven 0:404c38e71c68 42 *v = bak + (color << pos);
steeven 0:404c38e71c68 43 }
steeven 0:404c38e71c68 44
steeven 0:404c38e71c68 45 // print line
steeven 0:404c38e71c68 46 void Graphic::line(int x0, int y0, int x1, int y1) {
steeven 0:404c38e71c68 47 int dx = 0, dy = 0;
steeven 0:404c38e71c68 48 int dx_sym = 0, dy_sym = 0;
steeven 0:404c38e71c68 49 int dx_x2 = 0, dy_x2 = 0;
steeven 0:404c38e71c68 50 int di = 0;
steeven 0:404c38e71c68 51
steeven 0:404c38e71c68 52 dx = x1 - x0;
steeven 0:404c38e71c68 53 dy = y1 - y0;
steeven 0:404c38e71c68 54
steeven 0:404c38e71c68 55 if (dx > 0) {
steeven 0:404c38e71c68 56 dx_sym = 1;
steeven 0:404c38e71c68 57 } else {
steeven 0:404c38e71c68 58 dx_sym = -1;
steeven 0:404c38e71c68 59 }
steeven 0:404c38e71c68 60
steeven 0:404c38e71c68 61 if (dy > 0) {
steeven 0:404c38e71c68 62 dy_sym = 1;
steeven 0:404c38e71c68 63 } else {
steeven 0:404c38e71c68 64 dy_sym = -1;
steeven 0:404c38e71c68 65 }
steeven 0:404c38e71c68 66
steeven 0:404c38e71c68 67 dx = dx_sym * dx;
steeven 0:404c38e71c68 68 dy = dy_sym * dy;
steeven 0:404c38e71c68 69
steeven 0:404c38e71c68 70 dx_x2 = dx * 2;
steeven 0:404c38e71c68 71 dy_x2 = dy * 2;
steeven 0:404c38e71c68 72
steeven 0:404c38e71c68 73 if (dx >= dy) {
steeven 0:404c38e71c68 74 di = dy_x2 - dx;
steeven 0:404c38e71c68 75 while (x0 != x1) {
steeven 0:404c38e71c68 76
steeven 0:404c38e71c68 77 pixel(x0, y0, _foreColor);
steeven 0:404c38e71c68 78 x0 += dx_sym;
steeven 0:404c38e71c68 79 if (di < 0) {
steeven 0:404c38e71c68 80 di += dy_x2;
steeven 0:404c38e71c68 81 } else {
steeven 0:404c38e71c68 82 di += dy_x2 - dx_x2;
steeven 0:404c38e71c68 83 y0 += dy_sym;
steeven 0:404c38e71c68 84 }
steeven 0:404c38e71c68 85 }
steeven 0:404c38e71c68 86 pixel(x0, y0, _foreColor);
steeven 0:404c38e71c68 87 } else {
steeven 0:404c38e71c68 88 di = dx_x2 - dy;
steeven 0:404c38e71c68 89 while (y0 != y1) {
steeven 0:404c38e71c68 90 pixel(x0, y0, _foreColor);
steeven 0:404c38e71c68 91 y0 += dy_sym;
steeven 0:404c38e71c68 92 if (di < 0) {
steeven 0:404c38e71c68 93 di += dx_x2;
steeven 0:404c38e71c68 94 } else {
steeven 0:404c38e71c68 95 di += dx_x2 - dy_x2;
steeven 0:404c38e71c68 96 x0 += dx_sym;
steeven 0:404c38e71c68 97 }
steeven 0:404c38e71c68 98 }
steeven 0:404c38e71c68 99 pixel(x0, y0, _foreColor);
steeven 0:404c38e71c68 100 }
steeven 0:404c38e71c68 101 }
steeven 0:404c38e71c68 102
steeven 0:404c38e71c68 103 // print rect
steeven 0:404c38e71c68 104 void Graphic::rect(int x0, int y0, int x1, int y1) {
steeven 0:404c38e71c68 105
steeven 0:404c38e71c68 106 if (x1 > x0)
steeven 0:404c38e71c68 107 line(x0, y0, x1, y0);
steeven 0:404c38e71c68 108 else
steeven 0:404c38e71c68 109 line(x1, y0, x0, y0);
steeven 0:404c38e71c68 110
steeven 0:404c38e71c68 111 if (y1 > y0)
steeven 0:404c38e71c68 112 line(x0, y0, x0, y1);
steeven 0:404c38e71c68 113 else
steeven 0:404c38e71c68 114 line(x0, y1, x0, y0);
steeven 0:404c38e71c68 115
steeven 0:404c38e71c68 116 if (x1 > x0)
steeven 0:404c38e71c68 117 line(x0, y1, x1, y1);
steeven 0:404c38e71c68 118 else
steeven 0:404c38e71c68 119 line(x1, y1, x0, y1);
steeven 0:404c38e71c68 120
steeven 0:404c38e71c68 121 if (y1 > y0)
steeven 0:404c38e71c68 122 line(x1, y0, x1, y1);
steeven 0:404c38e71c68 123 else
steeven 0:404c38e71c68 124 line(x1, y1, x1, y0);
steeven 0:404c38e71c68 125 }
steeven 0:404c38e71c68 126
steeven 0:404c38e71c68 127 // print filled rect
steeven 0:404c38e71c68 128 void Graphic::fillrect(int x0, int y0, int x1, int y1) {
steeven 0:404c38e71c68 129 int l, c, i;
steeven 0:404c38e71c68 130 if (x0 > x1) {
steeven 0:404c38e71c68 131 i = x0;
steeven 0:404c38e71c68 132 x0 = x1;
steeven 0:404c38e71c68 133 x1 = i;
steeven 0:404c38e71c68 134 }
steeven 0:404c38e71c68 135
steeven 0:404c38e71c68 136 if (y0 > y1) {
steeven 0:404c38e71c68 137 i = y0;
steeven 0:404c38e71c68 138 y0 = y1;
steeven 0:404c38e71c68 139 y1 = i;
steeven 0:404c38e71c68 140 }
steeven 0:404c38e71c68 141
steeven 0:404c38e71c68 142 for (l = x0; l <= x1; l++) {
steeven 0:404c38e71c68 143 for (c = y0; c <= y1; c++) {
steeven 0:404c38e71c68 144 pixel(l, c, _foreColor);
steeven 0:404c38e71c68 145 }
steeven 0:404c38e71c68 146 }
steeven 0:404c38e71c68 147 }
steeven 0:404c38e71c68 148
steeven 0:404c38e71c68 149 // print circle
steeven 0:404c38e71c68 150 void Graphic::circle(int x0, int y0, int r) {
steeven 0:404c38e71c68 151 int x = -r, y = 0, err = 2 - 2 * r, e2;
steeven 0:404c38e71c68 152 do {
steeven 0:404c38e71c68 153 pixel(x0 - x, y0 + y, _foreColor);
steeven 0:404c38e71c68 154 pixel(x0 + x, y0 + y, _foreColor);
steeven 0:404c38e71c68 155 pixel(x0 + x, y0 - y, _foreColor);
steeven 0:404c38e71c68 156 pixel(x0 - x, y0 - y, _foreColor);
steeven 0:404c38e71c68 157 e2 = err;
steeven 0:404c38e71c68 158 if (e2 <= y) {
steeven 0:404c38e71c68 159 err += ++y * 2 + 1;
steeven 0:404c38e71c68 160 if (-x == y && e2 <= x)
steeven 0:404c38e71c68 161 e2 = 0;
steeven 0:404c38e71c68 162 }
steeven 0:404c38e71c68 163 if (e2 > x)
steeven 0:404c38e71c68 164 err += ++x * 2 + 1;
steeven 0:404c38e71c68 165 } while (x <= 0);
steeven 0:404c38e71c68 166
steeven 0:404c38e71c68 167 }
steeven 0:404c38e71c68 168
steeven 0:404c38e71c68 169 // print filled circle
steeven 0:404c38e71c68 170 void Graphic::fillcircle(int x0, int y0, int r) {
steeven 0:404c38e71c68 171 int x = -r, y = 0, err = 2 - 2 * r, e2;
steeven 0:404c38e71c68 172 do {
steeven 0:404c38e71c68 173 line(x0 - x, y0 - y, x0 - x, y0 + y);
steeven 0:404c38e71c68 174 line(x0 + x, y0 - y, x0 + x, y0 + y);
steeven 0:404c38e71c68 175 e2 = err;
steeven 0:404c38e71c68 176 if (e2 <= y) {
steeven 0:404c38e71c68 177 err += ++y * 2 + 1;
steeven 0:404c38e71c68 178 if (-x == y && e2 <= x)
steeven 0:404c38e71c68 179 e2 = 0;
steeven 0:404c38e71c68 180 }
steeven 0:404c38e71c68 181 if (e2 > x)
steeven 0:404c38e71c68 182 err += ++x * 2 + 1;
steeven 0:404c38e71c68 183 } while (x <= 0);
steeven 0:404c38e71c68 184 }
steeven 0:404c38e71c68 185
steeven 0:404c38e71c68 186 // set cursor position
steeven 0:404c38e71c68 187 void Graphic::locate(int column, int row) {
steeven 0:404c38e71c68 188 _charX = column;
steeven 0:404c38e71c68 189 _charY = row;
steeven 0:404c38e71c68 190 }
steeven 0:404c38e71c68 191
steeven 0:404c38e71c68 192 // calc char columns
steeven 0:404c38e71c68 193 int Graphic::columns() {
steeven 0:404c38e71c68 194 int fontW = _font[1];
steeven 0:404c38e71c68 195 return _w / fontW;
steeven 0:404c38e71c68 196 }
steeven 0:404c38e71c68 197
steeven 0:404c38e71c68 198 // calc char rows
steeven 0:404c38e71c68 199 int Graphic::rows() {
steeven 0:404c38e71c68 200 int fontH = _font[2];
steeven 0:404c38e71c68 201 return _h / fontH;
steeven 0:404c38e71c68 202 }
steeven 0:404c38e71c68 203
steeven 0:404c38e71c68 204 // print char
steeven 0:404c38e71c68 205 void Graphic::putc(int c) {
steeven 0:404c38e71c68 206 int y, x, w, offset; //font
steeven 0:404c38e71c68 207 unsigned char* font;
steeven 0:404c38e71c68 208
steeven 0:404c38e71c68 209 int fontBytes = _font[0];
steeven 0:404c38e71c68 210 //int fontW = _font[1];
steeven 0:404c38e71c68 211 int fontH = _font[2];
steeven 0:404c38e71c68 212 int fontColBytes = _font[3];
steeven 0:404c38e71c68 213
steeven 0:404c38e71c68 214
steeven 0:404c38e71c68 215 if (c == '\n') { // new line
steeven 0:404c38e71c68 216 _charX = 0;
steeven 0:404c38e71c68 217 _charY = _charY + fontH;
steeven 0:404c38e71c68 218 if (_charY >= _h - fontH) {
steeven 0:404c38e71c68 219 _charY = 0;
steeven 0:404c38e71c68 220 }
steeven 0:404c38e71c68 221 return;
steeven 0:404c38e71c68 222 }
steeven 0:404c38e71c68 223 if ((c < 31) || (c > 127))
steeven 0:404c38e71c68 224 return; // test char range
steeven 0:404c38e71c68 225
steeven 0:404c38e71c68 226
steeven 0:404c38e71c68 227 font = &_font[((c - 32) * fontBytes) + 4]; // start of char bitmap
steeven 0:404c38e71c68 228 w = font[0]; // width of actual char
steeven 0:404c38e71c68 229 if (_charX + w > _w) {
steeven 0:404c38e71c68 230 _charX = 0;
steeven 0:404c38e71c68 231 _charY = _charY + fontH;
steeven 0:404c38e71c68 232 if (_charY >= _h - fontH) {
steeven 0:404c38e71c68 233 _charY = 0;
steeven 0:404c38e71c68 234 }
steeven 0:404c38e71c68 235 }
steeven 0:404c38e71c68 236
steeven 0:404c38e71c68 237 font++;
steeven 0:404c38e71c68 238 for (y = 0; y < fontH; y++) { // vert line
steeven 0:404c38e71c68 239 for (x = 0; x < w; x++) { // horz line
steeven 0:404c38e71c68 240 // vertical then horz in memory
steeven 0:404c38e71c68 241 offset = (x * fontColBytes + y / 8);
steeven 0:404c38e71c68 242 pixel(_charX + x, _charY + y,
steeven 0:404c38e71c68 243 ((font[offset] >> (y % 8)) & 1) ?
steeven 0:404c38e71c68 244 _foreColor : _backgroundColor);
steeven 0:404c38e71c68 245 }
steeven 0:404c38e71c68 246 }
steeven 0:404c38e71c68 247
steeven 0:404c38e71c68 248 _charX += w;
steeven 0:404c38e71c68 249 }
steeven 0:404c38e71c68 250
steeven 0:404c38e71c68 251 // set actual font
steeven 0:404c38e71c68 252 void Graphic::font(const unsigned char* f) {
steeven 0:404c38e71c68 253 _font = (unsigned char *) f;
steeven 0:404c38e71c68 254 }
steeven 0:404c38e71c68 255
steeven 0:404c38e71c68 256 void Graphic::print(const char *str) {
steeven 0:404c38e71c68 257 while (*str) {
steeven 0:404c38e71c68 258 putc(*str);
steeven 0:404c38e71c68 259 str++;
steeven 0:404c38e71c68 260 }
steeven 0:404c38e71c68 261 }
steeven 0:404c38e71c68 262
steeven 0:404c38e71c68 263 void Graphic::print_bm(Bitmap bm, int x, int y) {
steeven 0:404c38e71c68 264 int h, v, b;
steeven 0:404c38e71c68 265 char d;
steeven 0:404c38e71c68 266
steeven 0:404c38e71c68 267 for (v = 0; v < bm.ySize; v++) { // lines
steeven 0:404c38e71c68 268 for (h = 0; h < bm.xSize; h++) { // pixel
steeven 0:404c38e71c68 269 if (h + x > _w)
steeven 0:404c38e71c68 270 break;
steeven 0:404c38e71c68 271 if (v + y > _h)
steeven 0:404c38e71c68 272 break;
steeven 0:404c38e71c68 273 d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)];
steeven 0:404c38e71c68 274 b = 0x80 >> (h & 0x07);
steeven 0:404c38e71c68 275 if ((d & b) == 0) {
steeven 0:404c38e71c68 276 pixel(x + h, y + v, _backgroundColor);
steeven 0:404c38e71c68 277 } else {
steeven 0:404c38e71c68 278 pixel(x + h, y + v, _foreColor);
steeven 0:404c38e71c68 279 }
steeven 0:404c38e71c68 280 }
steeven 0:404c38e71c68 281 }
steeven 0:404c38e71c68 282
steeven 0:404c38e71c68 283 }