unsigned char menu_char_draw(SCREENPOS posx, SCREENPOS posy, unsigned char font, unsigned char cdraw) { unsigned char nunbyte, charwidth, nunbit; unsigned char copyedbytes[5]; SCREENPOS tempx, tempy; unsigned char byte_eq_count,nun; unsigned char shrink; if ((font & 1)) { shrink = 0; } else shrink = 1; charwidth = 0; #ifdef ENABLE_GERMAN_UMLAUTS if (cdraw == 196) cdraw = 127; if ((cdraw == 214) || (cdraw == 246)) cdraw = 128; if ((cdraw == 220) || (cdraw == 252)) cdraw = 129; if (cdraw == 228) cdraw = 130; if (cdraw == 223) cdraw = 131; #endif cdraw -= 32; if (cdraw < MENU_CHARACTERS) { //valid character #ifdef STOREINRAM memcpy(copyedbytes,characters+cdraw*5,5); #else memcpy_P(copyedbytes,characters+cdraw*5,5); #endif //automated shortening of chars if (shrink != 0) { byte_eq_count = 0; for (nun = 0; nun < 4; nun++) { byte_eq_count++; if (copyedbytes[nun] != copyedbytes[nun+1]) { byte_eq_count = 0; } if (byte_eq_count == 2) { //remove one byte, if it repeated three times copyedbytes[nun] = 0; } if (byte_eq_count == 4) { //if there are 5 bytes equal, we remove a second one copyedbytes[nun] = 0; } } //end of loop } //end if shrink != 0 for (nunbyte = 0; nunbyte < 5;nunbyte++) { tempx = posx+charwidth; if (tempx < posx+charwidth) { break; //prevent overflow to the left side of the screen } for (nunbit = 0; nunbit < 7;nunbit++) { tempy = posy+nunbit; if ((copyedbytes[nunbyte] & (0x01<<nunbit)) != 0) { menu_screen_set(tempx, tempy, 1); } else menu_screen_set(tempx, tempy, 0); } //end: inner loop if (font & 2) menu_screen_set(tempx, posy+7, 1); if ((copyedbytes[nunbyte] != 0) || (shrink == 0)) { charwidth++; } //end: charwidth++ } //end: outer loop if (font & 2) { //underline empty part between chars (this is not perfect on word ending) //printf("%i, %i\n", posx, charwidth); menu_screen_set(posx+charwidth, posy+7, 1); } } //end: valid char return charwidth++; } //end: function
unsigned char menu_char_draw(SCREENPOS posx, SCREENPOS posy, unsigned char font, unsigned char cdraw) { unsigned char nunbyte, charwidth, nunbit, patternbyte, patternbit; #if defined(MENU_TEXT_ENABLE_8X15) unsigned char copyedbytes[MENU_TEXT_8X15_BYTES]; #else unsigned char copyedbytes[MENU_TEXT_5X7_BYTES]; #endif SCREENPOS tempx, tempy; unsigned char byte_eq_count,nun; /* level of char shrinking: 0: Fixed with 1: Width defined by character within array, only empty colums are removed. 2: three or four same colums -> remove one. five same colums -> remove two. 3: two -> remove one. three or four -> remove two. five -> remove three */ unsigned char shrink = 0; unsigned char fontheight; //------------------- UTF-8 decoding ---------------------- #if defined(MENU_USE_UTF8) unsigned long cdrawx; //catch utf8 chars #ifndef MENU_ENABLE_SPECIAL_CHARS if (cdraw >= (MENU_CHARACTERS + MENU_CHARACTER_TABLE_OFFSET)) { //its something for utf-8 if (!g_menu_utf8_state) { //a new char begins g_menu_utf8_char = cdraw; if ((cdraw & 0xE0) == 0xC0) { g_menu_utf8_state = 1; } if ((cdraw & 0xF0) == 0xE0) { g_menu_utf8_state = 2; } if ((cdraw & 0xF8) == 0xF0) { g_menu_utf8_state = 3; } return -1; //symbol not complete, 255 = -1 do not go one pixel to the right } else { g_menu_utf8_char <<= 8; g_menu_utf8_char |= cdraw; g_menu_utf8_state--; if (g_menu_utf8_state) { return 0; //symbol not complete } cdrawx = g_menu_utf8_char; //symbol complete } } else { g_menu_utf8_state = 0; //reset state cdrawx = cdraw; } #else //for backward compatibility only cdrawx = cdraw; if (cdraw == 196) cdrawx = 0xC384; //Ä if (cdraw == 214) cdrawx = 0xC396; //Ö if (cdraw == 220) cdrawx = 0xC39C; //Ü if (cdraw == 228) cdrawx = 0xC3A4; //ä if (cdraw == 246) cdrawx = 0xC3B6; //ö if (cdraw == 252) cdrawx = 0xC3BC; //ü if (cdraw == 223) cdrawx = 0xC39F; //ß if (cdraw == 0xB0) cdrawx = 0xC2B0; //° #endif #else unsigned char cdrawx = cdraw; #endif //--------------- special handling... ------------------------------------------ if (MENU_CHECK_FONT_5X5) { if (cdraw == 9) { //its a tab, make same width as digits -> easy blinking (safe to use cdraw instead of cdrawx here) return 3; } } //--------------- determine data source ---------------------------------------- const char * bmpsource = NULL; char bmpsize = 0; char bmpwidth = 0; if (MENU_CHECK_FONT_5X5) { bmpsize = MENU_TEXT_5X5_BYTES; bmpwidth = MENU_TEXT_5X5_WIDTH; } if (MENU_CHECK_FONT_5X7) { bmpsize = MENU_TEXT_5X7_BYTES; bmpwidth = MENU_TEXT_5X7_WIDTH; } if (MENU_CHECK_FONT_8X15) { bmpsize = MENU_TEXT_8X15_BYTES; bmpwidth = MENU_TEXT_8X15_WIDTH; } if ((cdrawx < (MENU_CHARACTERS + MENU_CHARACTER_TABLE_OFFSET)) && (cdrawx >= MENU_CHARACTER_TABLE_OFFSET)) { //simple ASCII case, cdraw = cdrawx cdraw -= MENU_CHARACTER_TABLE_OFFSET; if (MENU_CHECK_FONT_5X5) { bmpsource = &(characters_5x5[MENU_TEXT_5X5_BYTES * cdraw]); } if (MENU_CHECK_FONT_5X7) { bmpsource = &(characters_5x7[MENU_TEXT_5X7_BYTES * cdraw]); } if (MENU_CHECK_FONT_8X15) { bmpsource = &(characters_8x15[MENU_TEXT_8X15_BYTES * cdraw]); } } #if defined(MENU_USE_UTF8) else { bmpsource = menu_get_pBitmap(cdrawx, font); } #endif if (!bmpsource) { MENU_DEBUGMSG("Error: no bitmap for char 0x%lx\r\n", (unsigned long)cdrawx); return 0; } //--------------- copy bitmask to buffer --------------------------------------- COPYFUNCTION(copyedbytes, bmpsource, bmpsize); //------------- prepare drawing by evaluating actual size of the character ----- if (MENU_CHECK_FONT_5X5) { shrink = font - 12; } if (MENU_CHECK_FONT_5X7) { if ((font == 0) || (font == 2)) { shrink = 2; } } if (MENU_CHECK_FONT_8X15) { if ((font == 4) || (font == 6)) { shrink = 2; } } charwidth = 0; //automated shortening of chars if (shrink > 1) { byte_eq_count = 0; for (nun = 0; nun < bmpwidth-1; nun++) { byte_eq_count++; if (copyedbytes[nun] != copyedbytes[nun+1]) { byte_eq_count = 0; } if (MENU_CHECK_FONT_5X5) { if ((byte_eq_count == 1) && (shrink == 3)) { copyedbytes[nun] = 0; } if ((nun > 0) && (font == 14) && (byte_eq_count == 1) && (copyedbytes[nun-1]) && (cdraw >= ('0' - MENU_CHARACTER_TABLE_OFFSET)) && (cdraw <= ('9' - MENU_CHARACTER_TABLE_OFFSET))) { //shortens numbers to 3 pixel witdh, but no less. Relevant for 3 and 7. copyedbytes[nun] = 0; } } if (MENU_CHECK_FONT_8X15) { if (copyedbytes[nun + MENU_TEXT_8X15_WIDTH] != copyedbytes[nun + MENU_TEXT_8X15_WIDTH + 1]) { byte_eq_count = 0; } } if (byte_eq_count == 2) { //remove one byte, if it repeated three times copyedbytes[nun] = 0; if (MENU_CHECK_FONT_8X15) { copyedbytes[nun + MENU_TEXT_8X15_WIDTH] = 0; } } if (byte_eq_count == 4) { //if there are 5 bytes equal, we remove a second one copyedbytes[nun] = 0; if (MENU_CHECK_FONT_8X15) { copyedbytes[nun + MENU_TEXT_8X15_WIDTH] = 0; } } } //end of loop } //end if shrink != 0 fontheight = menu_font_heigth(font); if (MENU_CHECK_FONT_UNDERLINED) { //only valid for font 2, 3, 6, 7 fontheight--; //no underline here } //------------------- actually draw -------------------------------------------- for (nunbyte = 0; nunbyte < bmpwidth; nunbyte++) { tempx = posx+charwidth; if (tempx < posx+charwidth) { break; //prevent overflow to the left side of the screen } patternbyte = copyedbytes[nunbyte]; patternbit = 1; for (nunbit = 0; nunbit < fontheight; nunbit++) { if (MENU_CHECK_FONT_8X15) { if (!patternbit) { patternbit = 1; patternbyte = copyedbytes[nunbyte + bmpwidth]; } } tempy = posy+nunbit; if ((patternbyte & patternbit) != 0) { menu_screen_set(tempx, tempy, 1); } else { menu_screen_set(tempx, tempy, 0); } patternbit <<= 1; } //end: inner loop if (MENU_CHECK_FONT_UNDERLINED) { //only valid for font 2, 3, 6, 7 menu_screen_set(tempx, posy + fontheight, 1);//underline fonts } if ((copyedbytes[nunbyte] != 0) || (shrink == 0) || ((MENU_CHECK_FONT_8X15) && (copyedbytes[nunbyte + MENU_TEXT_8X15_WIDTH] != 0))) { charwidth++; } //end: charwidth++ } //end: outer loop #ifdef MENU_USE_FONT_14 if ((font == 14) && (cdraw == ('1' - MENU_CHARACTER_TABLE_OFFSET))) { charwidth = 3; } #endif if (MENU_CHECK_FONT_UNDERLINED) { //only valid for font 2, 3, 6, 7 menu_screen_set(posx + charwidth, posy + fontheight, 1); //underline empty part between chars (this is not perfect on word ending) } return charwidth++; } //end: function