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.
Fork of UniGraphicCyrillic 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 static int flagCyr; 00259 if (value>=208){flagCyr=value;} else 00260 if (value == '\n') { // new line 00261 char_x = 0; 00262 char_y = char_y + fontvert*fontzoomver; 00263 if (char_y >= oriented_height - fontvert*fontzoomver) { 00264 char_y = 0; 00265 } 00266 } else { 00267 character(char_x, char_y,flagCyr*256+value); 00268 flagCyr=0; 00269 if(auto_up) copy_to_lcd(); 00270 } 00271 return value; 00272 } 00273 void GraphicsDisplay::character(int x, int y, int c) 00274 { 00275 switch (c){ 00276 case (208*256+129): c=168; break; 00277 case (208*256+132): c=170; break; 00278 case (208*256+134): c=178; break; 00279 case (208*256+135): c=175; break; 00280 case (209*256+145): c=184; break; 00281 case (209*256+148): c=186; break; 00282 case (209*256+150): c=179; break; 00283 case (209*256+151): c=191; break; 00284 case (210*256+144): c=165; break; 00285 case (210*256+145): c=180; break; 00286 } 00287 00288 int val = 209; // Read D8..D15 00289 val <<= 8; 00290 val |= 128; //Read D0..D7 */ 00291 if (c>=val){c=c-val+240;} 00292 00293 val = 208; // Read D8..D15 00294 val <<= 8; 00295 val |= 144; //Read D0..D7 */ 00296 if (c>=val){c=c-val+192;} 00297 00298 char_x=x; 00299 char_y=y; 00300 int j,i,b; 00301 unsigned char* zeichen; 00302 unsigned char z,w,v; 00303 00304 /* // read font parameter from start of array 00305 offset = font[0]; // bytes / char 00306 hor = font[1]; // get hor size of font 00307 vert = font[2]; // get vert size of font 00308 bpl = font[3]; // bytes per line 00309 */ 00310 if (char_x + fonthor*fontzoomhor > oriented_width) { 00311 char_x = 0; 00312 char_y = char_y + fontvert*fontzoomver; 00313 if (char_y > oriented_height - fontvert*fontzoomver) { 00314 char_y = 0; 00315 } 00316 } 00317 window(char_x, char_y,fonthor*fontzoomhor,fontvert*fontzoomver); // char box 00318 if ((c < firstch) || (c > lastch)) { // test char range - if not exist fill with blank 00319 for (i = 0; i < fonthor*fontvert*fontzoomver;i++){ 00320 window_pushpixel(_background, fontzoomhor); //(color, howmany) 00321 } 00322 } 00323 else{ 00324 zeichen = &font[((c-firstch) * fontoffset) + 4]; // start of char bitmap 00325 w = zeichen[0]; // width of actual char 00326 // construct the char into the buffer 00327 for (j=0; j<fontvert; j++) { // vert line 00328 for (v=0; v<fontzoomver; v++) { // repeat horiz line for vertical zooming 00329 for (i=0; i<fonthor; i++) { // horz line 00330 z = zeichen[(fontbpl * i) + ((j & 0xF8) >> 3)+1]; 00331 b = 1 << (j & 0x07); 00332 if (( z & b ) == 0x00) { 00333 // pixel(char_x+i,char_y+j,0); 00334 window_pushpixel(_background, fontzoomhor); //(color, howmany) 00335 } else { 00336 // pixel(char_x+i,char_y+j,1); 00337 window_pushpixel(_foreground, fontzoomhor); 00338 } 00339 } 00340 } //for each zoomed vert 00341 } 00342 } 00343 if(fontprop) 00344 { 00345 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 "_" 00346 else char_x += fonthor*fontzoomhor; 00347 } 00348 else char_x += fonthor*fontzoomhor; // fixed width 00349 00350 } 00351 void GraphicsDisplay::Bitmap_BW(Bitmap_s bm, int x, int y) 00352 { 00353 int h,v,b; 00354 // int cropX; 00355 char d; 00356 if(x<0) x=0; 00357 if(y<0) y=0; 00358 int cropX = (x+bm.xSize)-oriented_width; 00359 if(cropX<0) cropX=0; 00360 window(x, y, bm.xSize-cropX, bm.ySize); 00361 for(v=0; v < bm.ySize; v++) { // lines 00362 if((v + y) >= oriented_height) break; // no need to crop Y 00363 for(h=0; h < bm.xSize; h++) { // pixel 00364 if((h + x) >= oriented_width) break; 00365 d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)]; 00366 b = 0x80 >> (h & 0x07); 00367 if((d & b) == 0) { 00368 window_pushpixel(_background); 00369 } else { 00370 window_pushpixel(_foreground); 00371 } 00372 } 00373 } 00374 if(auto_up) copy_to_lcd(); 00375 } 00376 void GraphicsDisplay::Bitmap(int x, int y, int w, int h,unsigned char *bitmap) 00377 { 00378 int j; 00379 unsigned char padd; 00380 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 00381 00382 padd = w%2; // the lines are padded to multiple of 4 bytes in a bitmap 00383 if(x<0) x=0; 00384 else if(x>=oriented_width) return; 00385 if(y<0) y=0; 00386 else if(y>=oriented_height) return; 00387 int cropX = (x+w)-oriented_width; 00388 if(cropX<0) cropX=0; 00389 int cropY = (y+h)-oriented_height; 00390 if(cropY<0) cropY=0; 00391 window(x, y, w-cropX, h-cropY); 00392 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) 00393 for (j = 0; j < h-cropY; j++) { //Lines 00394 window_pushpixelbuf(bitmap_ptr, w-cropX); 00395 bitmap_ptr -= w+padd; 00396 } 00397 if(auto_up) copy_to_lcd(); 00398 } 00399 00400 // local filesystem is not implemented in kinetis board , but you can add a SD card 00401 // fixme this whole functions needs testing and speedup 00402 int GraphicsDisplay::BMP_16(int x, int y, const char *Name_BMP) 00403 { 00404 00405 #define OffsetPixelWidth 18 00406 #define OffsetPixelHeigh 22 00407 #define OffsetFileSize 34 00408 #define OffsetPixData 10 00409 #define OffsetBPP 28 00410 00411 char filename[50]; 00412 unsigned char BMP_Header[54]; 00413 unsigned short BPP_t; 00414 unsigned int PixelWidth,PixelHeigh,start_data; 00415 unsigned int i,off; 00416 int padd,j; 00417 unsigned short *line; 00418 00419 // get the filename 00420 i=0; 00421 while (*Name_BMP!='\0') { 00422 filename[i++]=*Name_BMP++; 00423 } 00424 filename[i] = 0; 00425 00426 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 00427 if (!Image) { 00428 return(0); // error file not found ! 00429 } 00430 00431 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00432 00433 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00434 fclose(Image); 00435 return(-1); // error no BMP file 00436 } 00437 00438 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00439 if (BPP_t != 0x0010) { 00440 fclose(Image); 00441 return(-2); // error no 16 bit BMP 00442 } 00443 00444 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00445 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00446 if (PixelHeigh > oriented_height + y || PixelWidth > oriented_width + x) { 00447 fclose(Image); 00448 return(-3); // to big 00449 } 00450 00451 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00452 00453 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 00454 if (line == NULL) { 00455 return(-4); // error no memory 00456 } 00457 00458 // the bmp lines are padded to multiple of 4 bytes 00459 padd = -1; 00460 do { 00461 padd ++; 00462 } while ((PixelWidth * 2 + padd)%4 != 0); 00463 00464 window(x, y,PixelWidth ,PixelHeigh); 00465 // wr_cmd(0x2C); // send pixel 00466 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 00467 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 00468 fseek(Image, off ,SEEK_SET); 00469 fread(line,1,PixelWidth * 2,Image); // read a line - slow 00470 /* for (i = 0; i < PixelWidth; i++) 00471 { // copy pixel data to TFT 00472 // wr_16(line[i]); // one 16 bit pixel 00473 window_pushpixel(line[i]); 00474 00475 } */ 00476 window_pushpixelbuf(line, PixelWidth); 00477 } 00478 free (line); 00479 fclose(Image); 00480 if(auto_up) copy_to_lcd(); 00481 return(1); 00482 } 00483 00484 void GraphicsDisplay::cls (void) 00485 { 00486 unsigned int pixels = ( oriented_width * oriented_height); 00487 WindowMax(); 00488 for (unsigned int i = 0; i < pixels; i++) 00489 { 00490 window_pushpixel(_background); 00491 } 00492 } 00493 void GraphicsDisplay::set_auto_up(bool up) 00494 { 00495 if(up) auto_up = true; 00496 else auto_up = false; 00497 } 00498 bool GraphicsDisplay::get_auto_up(void) 00499 { 00500 return (auto_up); 00501 } 00502 00503
Generated on Tue Jul 12 2022 20:38:04 by
1.7.2
