Шрифт в PROGMEM
- Войдите на сайт для отправки комментариев
Чт, 23/11/2017 - 11:14
Добрый день!
Есть шрифт с переменной шириной символов, сгенерированные в TheDotFactory, да еще и с несколькими массивами описания (для экономии памяти, так как часть символов не используется). Шрифт сжирает крайне много ОЗУ. Если же массив шрифта хранить в PROGMEM, то на дисплее отображаются каракули, нагуглил функцию pgm_read_byte, но как её применить в функции отрисовки символа, не могу понять. Хелп...
uint8_t ww;
uint16_t oo;
void Gui_GetFontDescr(char c)
{
for(int i=font.count_descr; i>0; i--)
{
if ((c>=font.charInfoLookup[i].startChar)&&(c<=font.charInfoLookup[i].endChar))
{
ww=font.charInfoLookup[i].charInfo[c-(font.charInfoLookup[i].startChar)].char_width;
oo=font.charInfoLookup[i].charInfo[c-(font.charInfoLookup[i].startChar)].char_offset;
return;
}
}
ww=0;
oo=0;
}
uint8_t Gui_DrawChar(const char c, uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor)
{
const unsigned char *bitmap_ptr;
const unsigned char *__bitmap_ptr;
unsigned char tmp;
uint8_t i, j, k, font_height_bytes;
uint8_t current_char_width;
uint16_t offset;
uint8_t __x = x;
uint8_t __y = y;
// Get height in bytes
font_height_bytes = (font.font_height)/8;
if ((font.font_height)%8) font_height_bytes++;
// Get width of current character
Gui_GetFontDescr(c);
current_char_width=ww;
offset=oo;
// Get pointer to data
bitmap_ptr = &(font.font_bitmap_array[offset]);
// Copy to temporary ptr
__bitmap_ptr = bitmap_ptr;
Gui_DrawRectFill(x,y,current_char_width,font.font_height,bgcolor);
for(k=current_char_width; k>0; k--)
{
// Width of character
for(i=font_height_bytes; i>0; i--)
{
// Height of character
// Get data to "shift"
tmp = *__bitmap_ptr;
__bitmap_ptr += current_char_width;
for(j=8; j>0; j--)
{
// Push byte
if( (tmp & 0x01) ){Gui_DrawPoint(__x,__y,color);}
else{/*Gui_DrawPoint(__x,__y,bgcolor);*/}
tmp >>= 1;
__y++;
}
}
__x++;
__y = y;
__bitmap_ptr = ++bitmap_ptr;
}
return current_char_width;
}
Не вижу в коде, чтобы вы пытались использовать pgm_read_byte(). Ждете готового решения? - зря
В ваших многомерных описаниях фонтов копайтесь сами, а в общем случае работа с массивом в PROGMEM совсем несложна:
// если шрифт описан как массив const byte PROGMEM array[] = {0,1,3,4,5,6}; // доступ к n-тому байту массива aa = pgm_read_byte(&array[n]);Код выложен исходный, который работает на данный момент с шрифтом в ОЗУ. С множественным описанием я разберусь, мне главное чтобы массив считывался правильно. Естественно я пытался и так и сяк использовать pgm_read_byte. Но или шрифт не рисуется совсем, или не компилируется. Не въезжаю я во все эти указатели и ссылки, потому и прошу помощи.
Не въезжаю я во все эти указатели и ссылки
Ага. Мы это видем, а без этого нифига не будет. Учите матчасть.
Естественно я пытался и так и сяк использовать pgm_read_byte. Но или шрифт не рисуется совсем, или не компилируется. Не въезжаю я во все эти указатели и ссылки, потому и прошу помощи.
выкладывайте код, где пытались использовать pgm_read_byte
for(j=8; j>0; j--) { // Push byte unsigned char ddd=pgm_read_byte(&tmp); if( (ddd & 0x01) ){Gui_DrawPoint(__x,__y,color);} else{/*Gui_DrawPoint(__x,__y,bgcolor);*/} ddd >>= 1; __y++; }вот например. остальное в функции без изменений.
for(j=8; j>0; j--) { // Push byte unsigned char ddd=pgm_read_byte(&tmp); if( (ddd & 0x01) ){Gui_DrawPoint(__x,__y,color);} else{/*Gui_DrawPoint(__x,__y,bgcolor);*/} ddd >>= 1; __y++; }вот например. остальное в функции без изменений.
так работать не будет, tmp у вас - временная переменная в оперативке, зачем ее читать функцией pgm_read_byte() ?
Вам нужно читать непосредственно из массива фонта в прог-меме, то есть функцию нужно вставить в ту строку, где у вас считывается tmp:
- в строке 32 исходного кода попробуйте изменить оператор на
tmp = pgm_read_byte(__bitmap_ptr);
, остальное верните как было
Да, так работает, спасибо! А я еще пробовал вот так pgm_read_byte(&bitmap_ptr), потому что во всех примерах, что я находил, был амперсанд, и переменную брал bitmap_ptr, а не __bitmap_ptr, ведь выше они приравнивались, я и посчитал, что это одно и то же. А почему они разные?