Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
GraphicsDisplay.cpp
00001 /* mbed UniGraphic library - Graphics class 00002 * Copyright (c) 2015 Giuliano Dianda 00003 * Released under the MIT License: http://mbed.org/license/mit 00004 * 00005 * Derived work of: 00006 * 00007 * mbed GraphicsDisplay Display Library Base Class 00008 * Copyright (c) 2007-2009 sford 00009 * Released under the MIT License: http://mbed.org/license/mit 00010 * 00011 * mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller 00012 * Copyright (c) 2013 Peter Drescher - DC2PD 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00023 00024 00025 #include "GraphicsDisplay.h" 00026 #define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } 00027 GraphicsDisplay::GraphicsDisplay(const char *name):TextDisplay(name) { 00028 set_font((unsigned char*)Terminal6x8,32,127,true); 00029 // foreground(0xFFFF); 00030 // background(0x0000); 00031 char_x = 0; 00032 char_y = 0; 00033 oriented_width=0; 00034 oriented_height=0; 00035 fontzoomver=1; 00036 fontzoomhor=1; 00037 auto_up = true; 00038 } 00039 00040 void GraphicsDisplay::WindowMax (void) 00041 { 00042 window (0, 0, oriented_width, oriented_height); 00043 } 00044 void GraphicsDisplay::set_width(int width) 00045 { 00046 oriented_width = width; 00047 } 00048 void GraphicsDisplay::set_height(int height) 00049 { 00050 oriented_height = height; 00051 } 00052 int GraphicsDisplay::width() 00053 { 00054 return oriented_width; 00055 } 00056 int GraphicsDisplay::height() 00057 { 00058 return oriented_height; 00059 } 00060 void GraphicsDisplay::circle(int x0, int y0, int r, unsigned short color) 00061 { 00062 int x = -r, y = 0, err = 2-2*r, e2; 00063 do { 00064 pixel(x0-x, y0+y,color); 00065 pixel(x0+x, y0+y,color); 00066 pixel(x0+x, y0-y,color); 00067 pixel(x0-x, y0-y,color); 00068 e2 = err; 00069 if (e2 <= y) { 00070 err += ++y*2+1; 00071 if (-x == y && e2 <= x) e2 = 0; 00072 } 00073 if (e2 > x) err += ++x*2+1; 00074 } while (x <= 0); 00075 if(auto_up) copy_to_lcd(); 00076 } 00077 void GraphicsDisplay::fillcircle(int x0, int y0, int r, unsigned short color) 00078 { 00079 bool old_auto_up=auto_up; 00080 if(auto_up) auto_up=false; 00081 int x = -r, y = 0, err = 2-2*r, e2; 00082 do { 00083 vline(x0-x, y0-y, y0+y, color); 00084 vline(x0+x, y0-y, y0+y, color); 00085 e2 = err; 00086 if (e2 <= y) { 00087 err += ++y*2+1; 00088 if (-x == y && e2 <= x) e2 = 0; 00089 } 00090 if (e2 > x) err += ++x*2+1; 00091 } while (x <= 0); 00092 if(old_auto_up) 00093 { 00094 auto_up=true; 00095 copy_to_lcd(); 00096 } 00097 } 00098 void GraphicsDisplay::hline(int x0, int x1, int y, unsigned short color) 00099 { 00100 int len = x1 - x0 + 1; 00101 window(x0,y,len,1); 00102 // for (int j=0; j<len; j++) window_pushpixel(color); 00103 window_pushpixel(color, len); 00104 if(auto_up) copy_to_lcd(); 00105 return; 00106 } 00107 void GraphicsDisplay::vline(int x, int y0, int y1, unsigned short color) 00108 { 00109 int len = y1 - y0 + 1; 00110 window(x,y0,1,len); 00111 // for (int y=0; y<len; y++) window_pushpixel(color); 00112 window_pushpixel(color, len); 00113 if(auto_up) copy_to_lcd(); 00114 return; 00115 } 00116 void GraphicsDisplay::line(int x0, int y0, int x1, int y1, unsigned short color) 00117 { 00118 //WindowMax(); 00119 int dx = 0, dy = 0; 00120 int dx_sym = 0, dy_sym = 0; 00121 int dx_x2 = 0, dy_x2 = 0; 00122 int di = 0; 00123 00124 dx = x1-x0; 00125 dy = y1-y0; 00126 00127 if (dx == 0) { /* vertical line */ 00128 if (y1 < y0) SWAP(y0,y1); 00129 vline(x0,y0,y1,color); 00130 return; 00131 } 00132 00133 if (dx > 0) { 00134 dx_sym = 1; 00135 } else { 00136 dx_sym = -1; 00137 } 00138 if (dy == 0) { /* horizontal line */ 00139 if (x1 < x0) SWAP(x1,x0); 00140 hline(x0,x1,y0,color); 00141 return; 00142 } 00143 00144 if (dy > 0) { 00145 dy_sym = 1; 00146 } else { 00147 dy_sym = -1; 00148 } 00149 00150 dx = dx_sym*dx; 00151 dy = dy_sym*dy; 00152 00153 dx_x2 = dx*2; 00154 dy_x2 = dy*2; 00155 00156 if (dx >= dy) { 00157 di = dy_x2 - dx; 00158 while (x0 != x1) { 00159 00160 pixel(x0, y0, color); 00161 x0 += dx_sym; 00162 if (di<0) { 00163 di += dy_x2; 00164 } else { 00165 di += dy_x2 - dx_x2; 00166 y0 += dy_sym; 00167 } 00168 } 00169 pixel(x0, y0, color); 00170 } else { 00171 di = dx_x2 - dy; 00172 while (y0 != y1) { 00173 pixel(x0, y0, color); 00174 y0 += dy_sym; 00175 if (di < 0) { 00176 di += dx_x2; 00177 } else { 00178 di += dx_x2 - dy_x2; 00179 x0 += dx_sym; 00180 } 00181 } 00182 pixel(x0, y0, color); 00183 } 00184 if(auto_up) copy_to_lcd(); 00185 return; 00186 } 00187 void GraphicsDisplay::rect(int x0, int y0, int x1, int y1, unsigned short color) 00188 { 00189 bool old_auto_up=auto_up; 00190 if(auto_up) auto_up=0; 00191 if (x1 > x0) hline(x0,x1,y0,color); 00192 else hline(x1,x0,y0,color); 00193 00194 if (y1 > y0) vline(x0,y0,y1,color); 00195 else vline(x0,y1,y0,color); 00196 00197 if (x1 > x0) hline(x0,x1,y1,color); 00198 else hline(x1,x0,y1,color); 00199 00200 if (y1 > y0) vline(x1,y0,y1,color); 00201 else vline(x1,y1,y0,color); 00202 if(old_auto_up) 00203 { 00204 auto_up=true; 00205 copy_to_lcd(); 00206 } 00207 return; 00208 } 00209 void GraphicsDisplay::fillrect(int x0, int y0, int x1, int y1, unsigned short color) 00210 { 00211 if(x0 > x1) SWAP(x0,x1); 00212 if(y0 > y1) SWAP(y0,y1); 00213 00214 int h = y1 - y0 + 1; 00215 int w = x1 - x0 + 1; 00216 unsigned int pixels = h * w; 00217 window(x0,y0,w,h); 00218 // for (unsigned int p=0; p<pixels; p++) window_pushpixel(color); 00219 window_pushpixel(color, pixels); 00220 if(auto_up) copy_to_lcd(); 00221 return; 00222 } 00223 void GraphicsDisplay::locate(int x, int y) 00224 { 00225 char_x = x; 00226 char_y = y; 00227 } 00228 int GraphicsDisplay::columns() 00229 { 00230 return oriented_width / fonthor; 00231 } 00232 int GraphicsDisplay::rows() 00233 { 00234 return oriented_height / fontvert; 00235 } 00236 void GraphicsDisplay::set_font(unsigned char* f, unsigned char firstascii, unsigned char lastascii, bool proportional) 00237 { 00238 font = f; 00239 // read font parameter from start of array 00240 //fontoffset = font[0]; // bytes / char 00241 fonthor = font[1]; // get hor size of font 00242 fontvert = font[2]; // get vert size of font 00243 //fontbpl = font[3]; // bytes per line 00244 fontbpl = (fontvert+7)>>3; //bytes per line, rounded up to multiple of 8 00245 fontoffset = (fonthor*fontbpl)+1; 00246 firstch = firstascii; // first ascii code present in font array (usually 32) 00247 lastch = lastascii; // last ascii code present in font array (usually 127) 00248 fontprop=proportional; 00249 set_font_zoom(1,1); 00250 } 00251 void GraphicsDisplay::set_font_zoom(unsigned char x_mul, unsigned char y_mul) 00252 { 00253 fontzoomhor=((x_mul==0) ? 1:x_mul); 00254 fontzoomver=((y_mul==0) ? 1:y_mul); 00255 } 00256 int GraphicsDisplay::_putc(int value) 00257 { 00258 if (value == '\n') { // new line 00259 char_x = 0; 00260 char_y = char_y + fontvert*fontzoomver; 00261 if (char_y >= oriented_height - fontvert*fontzoomver) { 00262 char_y = 0; 00263 } 00264 } else { 00265 character(char_x, char_y, value); 00266 if(auto_up) copy_to_lcd(); 00267 } 00268 return value; 00269 } 00270 void GraphicsDisplay::character(int x, int y, int c) 00271 { 00272 char_x=x; 00273 char_y=y; 00274 int j,i,b; 00275 unsigned char* zeichen; 00276 unsigned char z,w,v; 00277 00278 /* // read font parameter from start of array 00279 offset = font[0]; // bytes / char 00280 hor = font[1]; // get hor size of font 00281 vert = font[2]; // get vert size of font 00282 bpl = font[3]; // bytes per line 00283 */ 00284 if (char_x + fonthor*fontzoomhor > oriented_width) { 00285 char_x = 0; 00286 char_y = char_y + fontvert*fontzoomver; 00287 if (char_y > oriented_height - fontvert*fontzoomver) { 00288 char_y = 0; 00289 } 00290 } 00291 window(char_x, char_y,fonthor*fontzoomhor,fontvert*fontzoomver); // char box 00292 if ((c < firstch) || (c > lastch)) { // test char range - if not exist fill with blank 00293 for (i = 0; i < fonthor*fontvert*fontzoomver;i++){ 00294 window_pushpixel(_background, fontzoomhor); //(color, howmany) 00295 } 00296 } 00297 else{ 00298 zeichen = &font[((c-firstch) * fontoffset) + 4]; // start of char bitmap 00299 w = zeichen[0]; // width of actual char 00300 // construct the char into the buffer 00301 for (j=0; j<fontvert; j++) { // vert line 00302 for (v=0; v<fontzoomver; v++) { // repeat horiz line for vertical zooming 00303 for (i=0; i<fonthor; i++) { // horz line 00304 z = zeichen[(fontbpl * i) + ((j & 0xF8) >> 3)+1]; 00305 b = 1 << (j & 0x07); 00306 if (( z & b ) == 0x00) { 00307 // pixel(char_x+i,char_y+j,0); 00308 window_pushpixel(_background, fontzoomhor); //(color, howmany) 00309 } else { 00310 // pixel(char_x+i,char_y+j,1); 00311 window_pushpixel(_foreground, fontzoomhor); 00312 } 00313 } 00314 } //for each zoomed vert 00315 } 00316 } 00317 if(fontprop) 00318 { 00319 if((w+1)<fonthor) char_x += (w*fontzoomhor)+1; // put at least 1 blank after variable-width characters, except characters that occupy whole fonthor space like "_" 00320 else char_x += fonthor*fontzoomhor; 00321 } 00322 else char_x += fonthor*fontzoomhor; // fixed width 00323 } 00324 void GraphicsDisplay::Bitmap_BW(Bitmap_s bm, int x, int y) 00325 { 00326 int h,v,b; 00327 // int cropX; 00328 char d; 00329 if(x<0) x=0; 00330 if(y<0) y=0; 00331 int cropX = (x+bm.xSize)-oriented_width; 00332 if(cropX<0) cropX=0; 00333 window(x, y, bm.xSize-cropX, bm.ySize); 00334 for(v=0; v < bm.ySize; v++) { // lines 00335 if((v + y) >= oriented_height) break; // no need to crop Y 00336 for(h=0; h < bm.xSize; h++) { // pixel 00337 if((h + x) >= oriented_width) break; 00338 d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)]; 00339 b = 0x80 >> (h & 0x07); 00340 if((d & b) == 0) { 00341 window_pushpixel(_background); 00342 } else { 00343 window_pushpixel(_foreground); 00344 } 00345 } 00346 } 00347 if(auto_up) copy_to_lcd(); 00348 } 00349 void GraphicsDisplay::Bitmap(int x, int y, int w, int h,unsigned char *bitmap) 00350 { 00351 int j; 00352 unsigned char padd; 00353 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 00354 00355 padd = w%2; // the lines are padded to multiple of 4 bytes in a bitmap 00356 if(x<0) x=0; 00357 else if(x>=oriented_width) return; 00358 if(y<0) y=0; 00359 else if(y>=oriented_height) return; 00360 int cropX = (x+w)-oriented_width; 00361 if(cropX<0) cropX=0; 00362 int cropY = (y+h)-oriented_height; 00363 if(cropY<0) cropY=0; 00364 window(x, y, w-cropX, h-cropY); 00365 bitmap_ptr += ((h - 1)* (w + padd)); // begin of last line in array (first line of image)(standard bmp scan direction is left->right bottom->top) 00366 for (j = 0; j < h-cropY; j++) { //Lines 00367 window_pushpixelbuf(bitmap_ptr, w-cropX); 00368 bitmap_ptr -= w+padd; 00369 } 00370 if(auto_up) copy_to_lcd(); 00371 } 00372 00373 // local filesystem is not implemented in kinetis board , but you can add a SD card 00374 // fixme this whole functions needs testing and speedup 00375 int GraphicsDisplay::BMP_16(int x, int y, const char *Name_BMP) 00376 { 00377 00378 #define OffsetPixelWidth 18 00379 #define OffsetPixelHeigh 22 00380 #define OffsetFileSize 34 00381 #define OffsetPixData 10 00382 #define OffsetBPP 28 00383 00384 char filename[50]; 00385 unsigned char BMP_Header[54]; 00386 unsigned short BPP_t; 00387 unsigned int PixelWidth,PixelHeigh,start_data; 00388 unsigned int i,off; 00389 int padd,j; 00390 unsigned short *line; 00391 00392 // get the filename 00393 i=0; 00394 while (*Name_BMP!='\0') { 00395 filename[i++]=*Name_BMP++; 00396 } 00397 filename[i] = 0; 00398 00399 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 00400 if (!Image) { 00401 return(0); // error file not found ! 00402 } 00403 00404 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00405 00406 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00407 fclose(Image); 00408 return(-1); // error no BMP file 00409 } 00410 00411 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00412 if (BPP_t != 0x0010) { 00413 fclose(Image); 00414 return(-2); // error no 16 bit BMP 00415 } 00416 00417 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00418 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00419 if (PixelHeigh > oriented_height + y || PixelWidth > oriented_width + x) { 00420 fclose(Image); 00421 return(-3); // to big 00422 } 00423 00424 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00425 00426 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 00427 if (line == NULL) { 00428 return(-4); // error no memory 00429 } 00430 00431 // the bmp lines are padded to multiple of 4 bytes 00432 padd = -1; 00433 do { 00434 padd ++; 00435 } while ((PixelWidth * 2 + padd)%4 != 0); 00436 00437 window(x, y,PixelWidth ,PixelHeigh); 00438 // wr_cmd(0x2C); // send pixel 00439 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 00440 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 00441 fseek(Image, off ,SEEK_SET); 00442 fread(line,1,PixelWidth * 2,Image); // read a line - slow 00443 /* for (i = 0; i < PixelWidth; i++) 00444 { // copy pixel data to TFT 00445 // wr_16(line[i]); // one 16 bit pixel 00446 window_pushpixel(line[i]); 00447 00448 } */ 00449 window_pushpixelbuf(line, PixelWidth); 00450 } 00451 free (line); 00452 fclose(Image); 00453 if(auto_up) copy_to_lcd(); 00454 return(1); 00455 } 00456 00457 void GraphicsDisplay::cls (void) 00458 { 00459 unsigned int pixels = ( oriented_width * oriented_height); 00460 WindowMax(); 00461 for (unsigned int i = 0; i < pixels; i++) 00462 { 00463 window_pushpixel(_background); 00464 } 00465 } 00466 void GraphicsDisplay::set_auto_up(bool up) 00467 { 00468 if(up) auto_up = true; 00469 else auto_up = false; 00470 } 00471 bool GraphicsDisplay::get_auto_up(void) 00472 { 00473 return (auto_up); 00474 } 00475 00476
Generated on Fri Jul 15 2022 13:58:04 by
