void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor) { /* No mutex required as we only call high level functions which have their own mutex */ coord_t w, h, p; char c; int first; if (!str) return; first = 1; h = font->height * font->yscale; p = font->charPadding * font->xscale; while(*str) { /* Get the next printable character */ c = *str++; w = _getCharWidth(font, c) * font->xscale; if (!w) continue; /* Handle inter-character padding */ if (p) { if (!first) { gdispFillArea(x, y, p, h, bgcolor); x += p; } else first = 0; } /* Print the character */ gdispFillChar(x, y, c, font, color, bgcolor); x += w; } }
coord_t gdispGetStringWidth(const char* str, font_t font) { /* No mutex required as we only read static data */ coord_t w, p, x; char c; int first; first = 1; x = 0; p = font->charPadding * font->xscale; while(*str) { /* Get the next printable character */ c = *str++; w = _getCharWidth(font, c) * font->xscale; if (!w) continue; /* Handle inter-character padding */ if (p) { if (!first) x += p; else first = 0; } /* Add the character width */ x += w; } return x; }
void lld_gdisp_draw_char(coord_t x, coord_t y, char c, font_t font, color_t color) { const fontcolumn_t *ptr; fontcolumn_t column; coord_t width, height, xscale, yscale; coord_t i, j, xs, ys; /* Check we actually have something to print */ width = _getCharWidth(font, c); if (!width) return; xscale = font->xscale; yscale = font->yscale; height = font->height * yscale; width *= xscale; ptr = _getCharData(font, c); /* Loop through the data and display. The font data is LSBit first, down the column */ for(i=0; i < width; i+=xscale) { /* Get the font bitmap data for the column */ column = *ptr++; /* Draw each pixel */ for(j=0; j < height; j+=yscale, column >>= 1) { if (column & 0x01) { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) lld_gdisp_draw_pixel(x+i+xs, y+j+ys, color); } } } }
coord_t gdispGetCharWidth(char c, font_t font) { /* No mutex required as we only read static data */ return _getCharWidth(font, c) * font->xscale; }
void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgcolor, justify_t justify) { /* No mutex required as we only call high level functions which have their own mutex */ coord_t w, h, p, ypos, xpos; char c; int first; const char *rstr; if (!str) str = ""; h = font->height * font->yscale; p = font->charPadding * font->xscale; /* Oops - font too large for the area */ if (h > cy) return; /* See if we need to fill above the font */ ypos = (cy - h + 1)/2; if (ypos > 0) { gdispFillArea(x, y, cx, ypos, bgcolor); y += ypos; cy -= ypos; } /* See if we need to fill below the font */ ypos = cy - h; if (ypos > 0) { gdispFillArea(x, y+cy-ypos, cx, ypos, bgcolor); cy -= ypos; } /* get the start of the printable string and the xpos */ switch(justify) { case justifyCenter: /* Get the length of the entire string */ w = gdispGetStringWidth(str, font); if (w <= cx) xpos = x + (cx - w)/2; else { /* Calculate how much of the string we need to get rid of */ ypos = (w - cx)/2; xpos = 0; first = 1; while(*str) { /* Get the next printable character */ c = *str++; w = _getCharWidth(font, c) * font->xscale; if (!w) continue; /* Handle inter-character padding */ if (p) { if (!first) { xpos += p; if (xpos > ypos) break; } else first = 0; } /* Print the character */ xpos += w; if (xpos > ypos) break; } xpos = ypos - xpos + x; } break; case justifyRight: /* Find the end of the string */ for(rstr = str; *str; str++); xpos = x+cx - 2; first = 1; for(str--; str >= rstr; str--) { /* Get the next printable character */ c = *str; w = _getCharWidth(font, c) * font->xscale; if (!w) continue; /* Handle inter-character padding */ if (p) { if (!first) { if (xpos - p < x) break; xpos -= p; } else first = 0; } /* Print the character */ if (xpos - w < x) break; xpos -= w; } str++; break; case justifyLeft: /* Fall through */ default: xpos = x+1; break; } /* Fill any space to the left */ if (x < xpos) gdispFillArea(x, y, xpos-x, cy, bgcolor); /* Print characters until we run out of room */ first = 1; while(*str) { /* Get the next printable character */ c = *str++; w = _getCharWidth(font, c) * font->xscale; if (!w) continue; /* Handle inter-character padding */ if (p) { if (!first) { if (xpos + p > x+cx) break; gdispFillArea(xpos, y, p, cy, bgcolor); xpos += p; } else first = 0; } /* Print the character */ if (xpos + w > x+cx) break; gdispFillChar(xpos, y, c, font, color, bgcolor); xpos += w; } /* Fill any space to the right */ if (xpos < x+cx) gdispFillArea(xpos, y, x+cx-xpos, cy, bgcolor); }
void lld_gdisp_fill_char(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { coord_t width, height; coord_t xscale, yscale; /* Check we actually have something to print */ width = _getCharWidth(font, c); if (!width) return; xscale = font->xscale; yscale = font->yscale; height = font->height * yscale; width *= xscale; /* Method 1: Use background fill and then draw the text */ #if GDISP_HARDWARE_TEXT || GDISP_SOFTWARE_TEXTFILLDRAW /* Fill the area */ lld_gdisp_fill_area(x, y, width, height, bgcolor); /* Draw the text */ lld_gdisp_draw_char(x, y, c, font, color); /* Method 2: Create a single column bitmap and then blit it */ #elif GDISP_HARDWARE_BITFILLS && GDISP_SOFTWARE_TEXTBLITCOLUMN { const fontcolumn_t *ptr; fontcolumn_t column; coord_t i, j, xs, ys; /* Working buffer for fast non-transparent text rendering [patch by Badger] This needs to be larger than the largest character we can print. Assume the max is double sized by one column. */ static pixel_t buf[sizeof(fontcolumn_t)*8*2]; #if GDISP_NEED_VALIDATION /* Check our buffer is big enough */ if ((unsigned)height > sizeof(buf)/sizeof(buf[0])) return; #endif ptr = _getCharData(font, c); /* Loop through the data and display. The font data is LSBit first, down the column */ for(i = 0; i < width; i+=xscale) { /* Get the font bitmap data for the column */ column = *ptr++; /* Draw each pixel */ for(j = 0; j < height; j+=yscale, column >>= 1) { if (column & 0x01) { for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, 1, j+ys, 0, color); } else { for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, 1, j+ys, 0, bgcolor); } } for(xs=0; xs < xscale; xs++) lld_gdisp_blit_area_ex(x+i+xs, y, 1, height, 0, 0, 1, buf); } } /* Method 3: Create a character bitmap and then blit it */ #elif GDISP_HARDWARE_BITFILLS { const fontcolumn_t *ptr; fontcolumn_t column; coord_t i, j, xs, ys; /* Working buffer for fast non-transparent text rendering [patch by Badger] This needs to be larger than the largest character we can print. Assume the max is double sized. */ static pixel_t buf[20*(sizeof(fontcolumn_t)*8)*2]; #if GDISP_NEED_VALIDATION /* Check our buffer is big enough */ if ((unsigned)(width * height) > sizeof(buf)/sizeof(buf[0])) return; #endif ptr = _getCharData(font, c); /* Loop through the data and display. The font data is LSBit first, down the column */ for(i = 0; i < width; i+=xscale) { /* Get the font bitmap data for the column */ column = *ptr++; /* Draw each pixel */ for(j = 0; j < height; j+=yscale, column >>= 1) { if (column & 0x01) { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, width, i+xs, j+ys, color); } else { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, width, i+xs, j+ys, bgcolor); } } } /* [Patch by Badger] Write all in one stroke */ lld_gdisp_blit_area_ex(x, y, width, height, 0, 0, width, buf); } /* Method 4: Draw pixel by pixel */ #else { const fontcolumn_t *ptr; fontcolumn_t column; coord_t i, j, xs, ys; ptr = _getCharData(font, c); /* Loop through the data and display. The font data is LSBit first, down the column */ for(i = 0; i < width; i+=xscale) { /* Get the font bitmap data for the column */ column = *ptr++; /* Draw each pixel */ for(j = 0; j < height; j+=yscale, column >>= 1) { if (column & 0x01) { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) lld_gdisp_draw_pixel(x+i+xs, y+j+ys, color); } else { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) lld_gdisp_draw_pixel(x+i+xs, y+j+ys, bgcolor); } } } } #endif }
/** * @brief Draw a character using a filled background. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The top-left corner of the text * @param[in] c The character to print * @param[in] color The color of the character * @param[in] bgcolor The background color * * @notapi */ void GDISP_LLD(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { volatile coord_t width, height; // TODO check why volatile is needed. Otherwise width * height = 0 if height is optimized out coord_t xscale, yscale; /* Check we actually have something to print */ width = _getCharWidth(font, c); if (!width) return; xscale = font->xscale; yscale = font->yscale; height = font->height * yscale; width *= xscale; const fontcolumn_t *ptr; fontcolumn_t column; coord_t i, j, xs, ys; /* Working buffer for fast non-transparent text rendering [patch by Badger] This needs to be larger than the largest character we can print. Assume the max is double sized. */ static pixel_t buf[20*(sizeof(fontcolumn_t)*8)*2]; #if GDISP_NEED_VALIDATION /* Check our buffer is big enough */ if ((unsigned)(width * height) > sizeof(buf)/sizeof(buf[0])) return; #endif ptr = _getCharData(font, c); /* Loop through the data and display. The font data is LSBit first, down the column */ for(i = 0; i < width; i+=xscale) { /* Get the font bitmap data for the column */ column = *ptr++; /* Draw each pixel */ for(j = 0; j < height; j+=yscale, column >>= 1) { if (column & 0x01) { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, width, i+xs, j+ys, color); } else { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, width, i+xs, j+ys, bgcolor); } } } /* * write char in display memory (after end of normal memory) */ lld_lcdBurstWriteMemory(480 * 272 * 2, buf, width * height); uint16_t lcdBitBLTBuffer[10]; lcdBitBLTBuffer[0] = 0x05; /* 0x82 16bpp, source linear */ lcdBitBLTBuffer[2] = 0x00; /* 0x86 Move positive */ lcdBitBLTBuffer[3] = ((480*272)*2) & 0xffff; /* 0x88 Source start address */ lcdBitBLTBuffer[4] = (480*272*2)>>16; /* 0x8A Source start address */ lcdBitBLTBuffer[5] = (y * GDISP_SCREEN_WIDTH * 2) + (x * 2); /* 0x8C Destination start address */ lcdBitBLTBuffer[6] = ((y * GDISP_SCREEN_WIDTH * 2) + (x * 2)) >> 16; /* 0x8E Destination start address */ lcdBitBLTBuffer[7] = GDISP_SCREEN_WIDTH; /* 0x90 Rectangle offset (screen width) */ lcdBitBLTBuffer[8] = width; /* 0x92 Width */ lcdBitBLTBuffer[9] = height; /* 0x94 Height */ lld_lcdBurstWriteMemory(0x60882, lcdBitBLTBuffer, 10); lld_lcdWriteReg( 0x80, 0x01); /* Start blit */ }