void LCD_PrintCharXY(unsigned int x, unsigned int y, u32 c) { u8 row, col, width; const u8 *offset = char_offset(c, &width); if (! offset || ! width) { printf("Could not locate character U-%04x\n", (int)c); return; } // Check if the requested character is available LCD_DrawStart(x, y, x + width - 1, y + HEIGHT(cur_str.font) - 1, DRAW_NWSE); for (col = 0; col < width; col++) { const u8 *data = offset++; u8 bit = 0; // Data is right aligned,adrawn top to bottom for (row = 0; row < HEIGHT(cur_str.font); ++row) { if (bit == 8) { data = offset++; bit = 0; } if (*data & (1 << bit)) { LCD_DrawPixelXY(x + col, y + row, cur_str.color); } bit++; } } LCD_DrawStop(); }
void LCD_DrawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { LCD_DrawStart(x, y, x, y + h -1, DRAW_NWSE); // bug fix: should be y+ h-1 while(h--) LCD_DrawPixel(color); LCD_DrawStop(); }
void LCD_FillRect(u16 x, u16 y, u16 w, u16 h, u16 color) { u32 bytes = (u32)w * h; LCD_DrawStart(x, y, x + w - 1, y + h -1, DRAW_NWSE); // Bug fix: should be y+h-1 instead of y+h while(bytes--) LCD_DrawPixel(color); LCD_DrawStop(); }
void LCD_DrawDashedVLine(int16_t x, int16_t y, int16_t h, int16_t space, uint16_t color) { LCD_DrawStart(x, y, x, y + h -1, DRAW_NWSE); int16_t y1; for (y1 = 0; y1 < h; y1++) if ((y1 / space) & 0x01) LCD_DrawPixelXY(x, y1 + y, color); LCD_DrawStop(); }
void LCD_DrawDashedHLine(int16_t x, int16_t y, int16_t w, int16_t space, uint16_t color) { LCD_DrawStart(x, y, x + w -1, y, DRAW_NWSE); int16_t x1; for (x1 = 0; x1 < w; x1++) if ((x1 / space) & 0x01) LCD_DrawPixelXY(x1 + x, y, color); LCD_DrawStop(); }
void LCD_DrawUSBLogo(int lcd_width, int lcd_height) { int width = (usb_logo[0] << 8) | usb_logo[1]; int height= (usb_logo[2] << 8) | usb_logo[3]; int size = (usb_logo[4] << 8) | usb_logo[5]; int x = (lcd_width - width) / 2; int y = (lcd_height - height) / 2; LCD_DrawStart(x, y, x + width-1, y + height, DRAW_NWSE); LCD_DrawRLE(usb_logo+6, size, 0xffff); LCD_DrawStop(); }
void LCD_DrawWindowedImageFromFile(u16 x, u16 y, const char *file, s16 w, s16 h, u16 x_off, u16 y_off) { FILE *fh; u32 black, white; u8 buf[48]; u16 img_w = 0, img_h = 0; fh = fopen(file, "rb"); if(! fh) { printf("DEBUG: LCD_DrawWindowedImageFromFile: Image not found: %s\n", file); if (w > 0 && h > 0) LCD_FillRect(x, y, w, h, 0); return; } if (! image_read_header(fh, &img_w, &img_h, &black, &white)) { fclose(fh); return; } //printf("DEBUG: LCD_DrawWindowedImageFromFile: %s %dx%d %06x %06x\n", file, img_w, img_h, black, white); if (img_w > sizeof(buf)*8) { printf("DEBUG: LCD_DrawWindowedImageFromFile: Image is too wide: %d > %d\n", img_w, sizeof(buf)*8); fclose(fh); return; } if (w < 0) w = img_w; if (h < 0) h = img_h; LCD_DrawStart(x, y, x + w - 1, y + h -1, DRAW_NWSE); unsigned bytes = (img_w + 7) / 8; fseek(fh, bytes * y_off, SEEK_CUR); for (int i = 0; i < h; i++) { int ret = fread(buf, bytes, 1, fh); if (ret != 1) { //printf("DEBUG: LCD_DrawWindowedImageFromFile: Buffer read issue? (%s, %d, %d)\n", file, ret, i); break; } for (int j = 0; j < w; j++) { unsigned val = buf[(j + x_off) / 8] & (1 << (7 - ((j + x_off) % 8))); LCD_DrawPixelXY(x+j, y+i, val ? black : white); } } fclose(fh); LCD_DrawStop(); }
void LCD_DrawWindowedImageFromFile(u16 x, u16 y, const char *file, s16 w, s16 h, u16 x_off, u16 y_off) { u16 i, j; FILE *fh; u8 transparent = 0; u8 row_has_transparency = 0; (void)row_has_transparency; u8 buf[480 * 2]; if (w == 0 || h == 0) return; fh = fopen(file, "rb"); if(! fh) { printf("DEBUG: LCD_DrawWindowedImageFromFile: Image not found: %s\n", file); if (w > 0 && h > 0) LCD_FillRect(x, y, w, h, 0); return; } setbuf(fh, 0); u32 img_w, img_h, offset, compression; if(fread(buf, 0x46, 1, fh) != 1 || buf[0] != 'B' || buf[1] != 'M') { fclose(fh); printf("DEBUG: LCD_DrawWindowedImageFromFile: Buffer read issue?\n"); return; } compression = *((u32 *)(buf + 0x1e)); if(*((u16 *)(buf + 0x1a)) != 1 /* 1 plane */ || *((u16 *)(buf + 0x1c)) != 16 /* 16bpp */ || (compression != 0 && compression != 3) /* BI_RGB or BI_BITFIELDS */ ) { fclose(fh); printf("DEBUG: LCD_DrawWindowedImageFromFile: BMP Format not correct\n"); return; } if(compression == 3) { if(*((u16 *)(buf + 0x36)) == 0x7c00 && *((u16 *)(buf + 0x3a)) == 0x03e0 && *((u16 *)(buf + 0x3e)) == 0x001f && *((u16 *)(buf + 0x42)) == 0x8000) { transparent = 1; } else if(*((u16 *)(buf + 0x36)) != 0xf800 || *((u16 *)(buf + 0x3a)) != 0x07e0 || *((u16 *)(buf + 0x3e)) != 0x001f) { fclose(fh); printf("DEBUG: LCD_DrawWindowedImageFromFile: BMP Format not correct second check\n"); return; } } offset = *((u32 *)(buf + 0x0a)); img_w = *((u32 *)(buf + 0x12)); img_h = *((u32 *)(buf + 0x16)); if(w < 0) w = img_w; if(h < 0) h = img_h; if((u16)w + x_off > img_w || (u16)h + y_off > img_h) { printf("DEBUG: LCD_DrawWindowedImageFromFile: Dimensions asked for are out of bounds\n"); printf("size: (%d x %d) bounds(%d x %d)\n", (u16)img_w, (u16)img_h, (u16)(w + x_off), (u16)(h + y_off)); fclose(fh); return; } offset += (img_w * (img_h - (y_off + h)) + x_off) * 2; fseek(fh, offset, SEEK_SET); LCD_DrawStart(x, y, x + w - 1, y + h - 1, DRAW_SWNE); /* Bitmap start is at lower-left corner */ for (j = 0; j < h; j++) { if (fread(buf, 2 * w, 1, fh) != 1) break; u16 *color = (u16 *)buf; if(transparent) { #ifdef TRANSPARENT_COLOR //Display supports a transparent color for (i = 0; i < w; i++ ) { u32 c; if((*color & 0x8000)) { //convert 1555 -> 565 c = ((*color & 0x7fe0) << 1) | (*color & 0x1f); } else { c = TRANSPARENT_COLOR; } LCD_DrawPixel(c); color++; } #else u8 last_pixel_transparent = row_has_transparency; row_has_transparency = 0; for (i = 0; i < w; i++ ) { if((*color & 0x8000)) { //convert 1555 -> 565 u16 c = ((*color & 0x7fe0) << 1) | (*color & 0x1f); if(last_pixel_transparent) { LCD_DrawPixelXY(x + i, y + h - j - 1, c); last_pixel_transparent = 0; } else { LCD_DrawPixel(c); } } else { //When we see a transparent pixel, the next real pixel // will need to be drawn with XY coordinates row_has_transparency = 1; last_pixel_transparent = 1; } color++; } #endif } else { for (i = 0; i < w; i++ ) { if (LCD_DEPTH == 1) *color = (*color & 0x8410) == 0x8410 ? 0 : 0xffff; LCD_DrawPixel(*color++); } } if((u16)w < img_w) { fseek(fh, 2 * (img_w - w), SEEK_CUR); } } LCD_DrawStop(); fclose(fh); }
void LCD_DrawFastHLine(u16 x, u16 y, u16 w, u16 color) { LCD_DrawStart(x, y, x + w -1, y, DRAW_NWSE); while(w--) LCD_DrawPixel(color); LCD_DrawStop(); }
void GUI_DrawXYGraph(struct guiObject *obj) { struct guiBox *box = &obj->box; struct guiXYGraph *graph = (struct guiXYGraph *)obj; u32 x, y; #define VAL_TO_X(xval) \ (u32)(box->x + (((s32)(xval)) - graph->min_x) * box->width / (1 + graph->max_x - graph->min_x)) #define VAL_TO_Y(yval) \ (u32)(box->y + box->height - (((s32)(yval)) - graph->min_y) * box->height / (1 + graph->max_y - graph->min_y)) _GUI_DrawMappedStart(); _GUI_ClearMappedBox(box, Display.xygraph.bg_color); if (graph->grid_x) { int xval; for (xval = graph->min_x + graph->grid_x; xval < graph->max_x; xval += graph->grid_x) { if (! xval) continue; x = VAL_TO_X(xval); //LCD_DrawDashedVLine(x, box->y, box->height, 5, RGB888_to_RGB565(0x30, 0x30, 0x30)); LCD_DrawFastVLine(x, box->y, box->height, Display.xygraph.grid_color); } } if (graph->grid_y) { int yval; for (yval = graph->min_y + graph->grid_y; yval < graph->max_y; yval += graph->grid_y) { if (! yval) continue; y = VAL_TO_Y(yval); //LCD_DrawDashedHLine(box->x, y, box->width, 5, RGB888_to_RGB565(0x30, 0x30, 0x30)); LCD_DrawFastHLine(box->x, y, box->width, Display.xygraph.grid_color); } } if (graph->min_x < 0 && graph->max_x > 0) { int x = box->x + box->width * (0 - graph->min_x) / (graph->max_x - graph->min_x); LCD_DrawFastVLine(x, box->y, box->height, Display.xygraph.axis_color); } if (graph->min_y < 0 && graph->max_y > 0) { y = box->y + box->height - box->height * (0 - graph->min_y) / (graph->max_y - graph->min_y); LCD_DrawFastHLine(box->x, y, box->width, Display.xygraph.axis_color); } u16 lastx = box->x; u16 lasty = box->y + box->height -1; LCD_DrawStart(box->x, box->y, box->x + box->width - 1, box->y + box->height - 1, DRAW_NWSE); for (x = 0; x < box->width; x++) { s32 xval, yval; xval = graph->min_x + x * (1 + graph->max_x - graph->min_x) / box->width; yval = graph->CallBack(xval, graph->cb_data); y = (yval - graph->min_y) * box->height / (1 + graph->max_y - graph->min_y); //printf("(%d, %d - %d, %d) -> (%d, %d)\n", // (int)lastx, (int)lasty, (int)x, (int)y, (int)xval, (int)yval); if (x != 0) { LCD_DrawLine(lastx, lasty, x + box->x, box->y + box->height - y - 1, Display.xygraph.fg_color); //Yellow } lastx = x + box->x; lasty = box->y + box->height - y - 1; } LCD_DrawStop(); if (graph->point_cb) { u8 pos = 0; s16 xval, yval; while (graph->point_cb(&xval, &yval, pos++, graph->cb_data)) { s16 x1 = VAL_TO_X(xval); s16 y1 = VAL_TO_Y(yval); s16 x2 = x1 + 2; s16 y2 = y1 + 2; //bounds check x1 = ( x1 < 2 + box->x) ? box->x : x1 - 2; y1 = ( y1 < 2 + box->y) ? box->y : y1 - 2; if ( x2 >= box->x + box->width) x2 = box->x + box->width - 1; if ( y2 >= box->y + box->height) y2 = box->y + box->height - 1; LCD_FillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1, Display.xygraph.point_color); } } if(Display.xygraph.outline_color != Display.xygraph.bg_color) LCD_DrawRect(box->x, box->y, box->width, box->height, Display.xygraph.outline_color); _GUI_DrawMappedStop(); }