This is the final version of Mini Gateway for Automation and Security desgined for Renesas GR Peach Design Contest
Dependencies: GR-PEACH_video GraphicsFramework HTTPServer R_BSP mbed-rpc mbed-rtos Socket lwip-eth lwip-sys lwip FATFileSystem
Fork of mbed-os-example-mbed5-blinky by
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,int16_t* bmp_data) 00376 { 00377 00378 00379 #define OffsetPixelWidth 18 00380 #define OffsetPixelHeigh 22 00381 #define OffsetFileSize 34 00382 #define OffsetPixData 10 00383 #define OffsetBPP 28 00384 00385 char filename[50]; 00386 unsigned char BMP_Header[54]; 00387 unsigned short BPP_t; 00388 unsigned int PixelWidth,PixelHeigh,start_data; 00389 unsigned int i,off; 00390 int padd,j; 00391 unsigned short *line; 00392 00393 // get the filename 00394 i=0; 00395 while (*Name_BMP!='\0') { 00396 filename[i++]=*Name_BMP++; 00397 } 00398 filename[i] = 0; 00399 00400 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 00401 if (!Image) { 00402 return(0); // error file not found ! 00403 } 00404 00405 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00406 00407 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00408 fclose(Image); 00409 return(-1); // error no BMP file 00410 } 00411 00412 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00413 if (BPP_t != 0x0010) { 00414 fclose(Image); 00415 return(-2); // error no 16 bit BMP 00416 } 00417 00418 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00419 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00420 if (PixelHeigh > oriented_height + y || PixelWidth > oriented_width + x) { 00421 fclose(Image); 00422 return(-3); // to big 00423 } 00424 00425 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00426 00427 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 00428 if (line == NULL) { 00429 return(-4); // error no memory 00430 } 00431 00432 // the bmp lines are padded to multiple of 4 bytes 00433 padd = -1; 00434 do { 00435 padd ++; 00436 } while ((PixelWidth * 2 + padd)%4 != 0); 00437 00438 window(x, y,PixelWidth ,PixelHeigh); 00439 00440 //WindowMax(); 00441 int count=0; 00442 // wr_cmd(0x2C); // send pixel 00443 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 00444 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 00445 fseek(Image, off ,SEEK_SET); 00446 fread(line,1,PixelWidth * 2,Image); // read a line - slow 00447 for (i = 0; i < PixelWidth; i++) 00448 { // copy pixel data to TFT 00449 // wr_16(line[i]); // one 16 bit pixel 00450 // window_pushpixel(line[i]); 00451 bmp_data[count++]=line[i]; 00452 } 00453 //window_pushpixelbuf(line, PixelWidth); 00454 } 00455 // for(i=0;i<320*480;i++) 00456 // window_pushpixel(bmp_data[i]); 00457 free (line); 00458 fclose(Image); 00459 if(auto_up) copy_to_lcd(); 00460 return(1); 00461 } 00462 00463 00464 // local filesystem is not implemented in kinetis board , but you can add a SD card 00465 // fixme this whole functions needs testing and speedup 00466 int GraphicsDisplay::BMP_16(int x, int y, const char *Name_BMP) 00467 { 00468 00469 00470 #define OffsetPixelWidth 18 00471 #define OffsetPixelHeigh 22 00472 #define OffsetFileSize 34 00473 #define OffsetPixData 10 00474 #define OffsetBPP 28 00475 00476 char filename[50]; 00477 unsigned char BMP_Header[54]; 00478 unsigned short BPP_t; 00479 unsigned int PixelWidth,PixelHeigh,start_data; 00480 unsigned int i,off; 00481 int padd,j; 00482 unsigned short *line; 00483 00484 // get the filename 00485 i=0; 00486 while (*Name_BMP!='\0') { 00487 filename[i++]=*Name_BMP++; 00488 } 00489 filename[i] = 0; 00490 00491 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 00492 if (!Image) { 00493 return(0); // error file not found ! 00494 } 00495 00496 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00497 00498 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00499 fclose(Image); 00500 return(-1); // error no BMP file 00501 } 00502 00503 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00504 if (BPP_t != 0x0010) { 00505 fclose(Image); 00506 return(-2); // error no 16 bit BMP 00507 } 00508 00509 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00510 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00511 if (PixelHeigh > oriented_height + y || PixelWidth > oriented_width + x) { 00512 fclose(Image); 00513 return(-3); // to big 00514 } 00515 00516 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00517 00518 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 00519 if (line == NULL) { 00520 return(-4); // error no memory 00521 } 00522 00523 // the bmp lines are padded to multiple of 4 bytes 00524 padd = -1; 00525 do { 00526 padd ++; 00527 } while ((PixelWidth * 2 + padd)%4 != 0); 00528 00529 window(x, y,PixelWidth ,PixelHeigh); 00530 00531 //WindowMax(); 00532 00533 // wr_cmd(0x2C); // send pixel 00534 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 00535 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 00536 fseek(Image, off ,SEEK_SET); 00537 fread(line,1,PixelWidth * 2,Image); // read a line - slow 00538 for (i = 0; i < PixelWidth; i++) 00539 { // copy pixel data to TFT 00540 // wr_16(line[i]); // one 16 bit pixel 00541 window_pushpixel(line[i]); 00542 //bmp_data[i+(((PixelHeigh - 1)-j)*PixelWidth)]=line[i]; 00543 } 00544 //window_pushpixelbuf(line, PixelWidth); 00545 } 00546 // for(i=0;i<320*480;i++) 00547 // window_pushpixel(bmp_data[i]); 00548 free (line); 00549 fclose(Image); 00550 if(auto_up) copy_to_lcd(); 00551 return(1); 00552 } 00553 00554 void GraphicsDisplay::BMP_disp(int x,int y,int16_t *bmpdata,int size,int w,int h) 00555 { 00556 window(x, y,w,h); 00557 for(int i=0;i<size;i++) 00558 window_pushpixel(bmpdata[i]); 00559 } 00560 00561 void GraphicsDisplay::cls (void) 00562 { 00563 unsigned int pixels = ( oriented_width * oriented_height); 00564 WindowMax(); 00565 for (unsigned int i = 0; i < pixels; i++) 00566 { 00567 window_pushpixel(_background); 00568 } 00569 } 00570 void GraphicsDisplay::set_auto_up(bool up) 00571 { 00572 if(up) auto_up = true; 00573 else auto_up = false; 00574 } 00575 bool GraphicsDisplay::get_auto_up(void) 00576 { 00577 return (auto_up); 00578 } 00579 00580
Generated on Tue Jul 12 2022 15:10:51 by 1.7.2