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 mbed-os-examples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GraphicsDisplay.cpp Source File

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