General graphics tool
Embed:
(wiki syntax)
Show/hide line numbers
Graphic.cpp
00001 #include "Graphic.h" 00002 00003 /* 00004 * Code derived from: 00005 * http://developer.mbed.org/users/dreschpe/code/EaEpaper/ 00006 */ 00007 Graphic::Graphic(uint8_t *buf, int w, int h, int bits) : 00008 _buf(buf), _w(w), _h(h), _bits(bits) { 00009 clear(); 00010 color(0, (1 << bits) - 1); 00011 } 00012 00013 // erase pixel after power up 00014 void Graphic::clear() { 00015 memset(_buf, 0, _w * _h / (1 << _bits)); 00016 _charX = 0; 00017 _charY = 0; 00018 } 00019 00020 void Graphic::color(int foreground, int background) { 00021 int mask = (1 << _bits) - 1; 00022 _foreColor = foreground & mask; 00023 _backgroundColor = background & mask; 00024 } 00025 00026 // set one pixel in buffer _newImage 00027 void Graphic::pixel(int x, int y, unsigned int color) { 00028 unsigned char *v; 00029 unsigned char bak, pos; 00030 // first check parameter 00031 if (x > _w || y > _h || x < 0 || y < 0) 00032 return; 00033 00034 color &= ((1 << _bits) - 1); // get valid color 00035 //memory:y first, then x 00036 v = &_buf[(x * _h * _bits / 8) + (y * _bits / 8)]; 00037 00038 //pix saved in reverse order in a byte 00039 pos = 8 - ((y * _bits) % 8) - _bits; 00040 00041 bak = *v & ~(((1 << _bits) - 1) << pos); 00042 *v = bak + (color << pos); 00043 } 00044 00045 // print line 00046 void Graphic::line(int x0, int y0, int x1, int y1) { 00047 int dx = 0, dy = 0; 00048 int dx_sym = 0, dy_sym = 0; 00049 int dx_x2 = 0, dy_x2 = 0; 00050 int di = 0; 00051 00052 dx = x1 - x0; 00053 dy = y1 - y0; 00054 00055 if (dx > 0) { 00056 dx_sym = 1; 00057 } else { 00058 dx_sym = -1; 00059 } 00060 00061 if (dy > 0) { 00062 dy_sym = 1; 00063 } else { 00064 dy_sym = -1; 00065 } 00066 00067 dx = dx_sym * dx; 00068 dy = dy_sym * dy; 00069 00070 dx_x2 = dx * 2; 00071 dy_x2 = dy * 2; 00072 00073 if (dx >= dy) { 00074 di = dy_x2 - dx; 00075 while (x0 != x1) { 00076 00077 pixel(x0, y0, _foreColor); 00078 x0 += dx_sym; 00079 if (di < 0) { 00080 di += dy_x2; 00081 } else { 00082 di += dy_x2 - dx_x2; 00083 y0 += dy_sym; 00084 } 00085 } 00086 pixel(x0, y0, _foreColor); 00087 } else { 00088 di = dx_x2 - dy; 00089 while (y0 != y1) { 00090 pixel(x0, y0, _foreColor); 00091 y0 += dy_sym; 00092 if (di < 0) { 00093 di += dx_x2; 00094 } else { 00095 di += dx_x2 - dy_x2; 00096 x0 += dx_sym; 00097 } 00098 } 00099 pixel(x0, y0, _foreColor); 00100 } 00101 } 00102 00103 // print rect 00104 void Graphic::rect(int x0, int y0, int x1, int y1) { 00105 00106 if (x1 > x0) 00107 line(x0, y0, x1, y0); 00108 else 00109 line(x1, y0, x0, y0); 00110 00111 if (y1 > y0) 00112 line(x0, y0, x0, y1); 00113 else 00114 line(x0, y1, x0, y0); 00115 00116 if (x1 > x0) 00117 line(x0, y1, x1, y1); 00118 else 00119 line(x1, y1, x0, y1); 00120 00121 if (y1 > y0) 00122 line(x1, y0, x1, y1); 00123 else 00124 line(x1, y1, x1, y0); 00125 } 00126 00127 // print filled rect 00128 void Graphic::fillrect(int x0, int y0, int x1, int y1) { 00129 int l, c, i; 00130 if (x0 > x1) { 00131 i = x0; 00132 x0 = x1; 00133 x1 = i; 00134 } 00135 00136 if (y0 > y1) { 00137 i = y0; 00138 y0 = y1; 00139 y1 = i; 00140 } 00141 00142 for (l = x0; l <= x1; l++) { 00143 for (c = y0; c <= y1; c++) { 00144 pixel(l, c, _foreColor); 00145 } 00146 } 00147 } 00148 00149 // print circle 00150 void Graphic::circle(int x0, int y0, int r) { 00151 int x = -r, y = 0, err = 2 - 2 * r, e2; 00152 do { 00153 pixel(x0 - x, y0 + y, _foreColor); 00154 pixel(x0 + x, y0 + y, _foreColor); 00155 pixel(x0 + x, y0 - y, _foreColor); 00156 pixel(x0 - x, y0 - y, _foreColor); 00157 e2 = err; 00158 if (e2 <= y) { 00159 err += ++y * 2 + 1; 00160 if (-x == y && e2 <= x) 00161 e2 = 0; 00162 } 00163 if (e2 > x) 00164 err += ++x * 2 + 1; 00165 } while (x <= 0); 00166 00167 } 00168 00169 // print filled circle 00170 void Graphic::fillcircle(int x0, int y0, int r) { 00171 int x = -r, y = 0, err = 2 - 2 * r, e2; 00172 do { 00173 line(x0 - x, y0 - y, x0 - x, y0 + y); 00174 line(x0 + x, y0 - y, x0 + x, y0 + y); 00175 e2 = err; 00176 if (e2 <= y) { 00177 err += ++y * 2 + 1; 00178 if (-x == y && e2 <= x) 00179 e2 = 0; 00180 } 00181 if (e2 > x) 00182 err += ++x * 2 + 1; 00183 } while (x <= 0); 00184 } 00185 00186 // set cursor position 00187 void Graphic::locate(int column, int row) { 00188 _charX = column; 00189 _charY = row; 00190 } 00191 00192 // calc char columns 00193 int Graphic::columns() { 00194 int fontW = _font[1]; 00195 return _w / fontW; 00196 } 00197 00198 // calc char rows 00199 int Graphic::rows() { 00200 int fontH = _font[2]; 00201 return _h / fontH; 00202 } 00203 00204 // print char 00205 void Graphic::putc(int c) { 00206 int y, x, w, offset; //font 00207 unsigned char* font; 00208 00209 int fontBytes = _font[0]; 00210 //int fontW = _font[1]; 00211 int fontH = _font[2]; 00212 int fontColBytes = _font[3]; 00213 00214 00215 if (c == '\n') { // new line 00216 _charX = 0; 00217 _charY = _charY + fontH; 00218 if (_charY >= _h - fontH) { 00219 _charY = 0; 00220 } 00221 return; 00222 } 00223 if ((c < 31) || (c > 127)) 00224 return; // test char range 00225 00226 00227 font = &_font[((c - 32) * fontBytes) + 4]; // start of char bitmap 00228 w = font[0]; // width of actual char 00229 if (_charX + w > _w) { 00230 _charX = 0; 00231 _charY = _charY + fontH; 00232 if (_charY >= _h - fontH) { 00233 _charY = 0; 00234 } 00235 } 00236 00237 font++; 00238 for (y = 0; y < fontH; y++) { // vert line 00239 for (x = 0; x < w; x++) { // horz line 00240 // vertical then horz in memory 00241 offset = (x * fontColBytes + y / 8); 00242 pixel(_charX + x, _charY + y, 00243 ((font[offset] >> (y % 8)) & 1) ? 00244 _foreColor : _backgroundColor); 00245 } 00246 } 00247 00248 _charX += w; 00249 } 00250 00251 // set actual font 00252 void Graphic::font(const unsigned char* f) { 00253 _font = (unsigned char *) f; 00254 } 00255 00256 void Graphic::print(const char *str) { 00257 while (*str) { 00258 putc(*str); 00259 str++; 00260 } 00261 } 00262 00263 void Graphic::print_bm(Bitmap bm, int x, int y) { 00264 int h, v, b; 00265 char d; 00266 00267 for (v = 0; v < bm.ySize; v++) { // lines 00268 for (h = 0; h < bm.xSize; h++) { // pixel 00269 if (h + x > _w) 00270 break; 00271 if (v + y > _h) 00272 break; 00273 d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)]; 00274 b = 0x80 >> (h & 0x07); 00275 if ((d & b) == 0) { 00276 pixel(x + h, y + v, _backgroundColor); 00277 } else { 00278 pixel(x + h, y + v, _foreColor); 00279 } 00280 } 00281 } 00282 00283 }
Generated on Wed Jul 13 2022 04:16:09 by 1.7.2