Closed karawin closed 6 years ago
Which font did you use?
u8g2_font_6x13_t_cyrillic
Ok, good. Can you post the complete code?
It is a big project https://github.com/karawin/Ka-Radio32 but the github is not up to date. output of scrollU8g2 function x= 128,scroll: +iline[i]= 0, len=43, x-onechar= 124 scroll: len=19, num= 20, str=СупердиÑкотека 90Ñ…
The concerned module is addonu8g2.c `/**
***/
// nams <--> num of line
static uint16_t y ; //Height of a line static uint16_t yy; //Height of screen static uint16_t x ; //Width static uint16_t z ; // an internal offset for y
//static struct tm *dt; static char strsec[30]; static uint16_t volume;
static char station[BUFLEN]; //received station static char title[BUFLEN]; // received title static char nameset[BUFLEN]; // the local name of the station
static char* lline[LINES] ; // array of ptr of n lines static uint8_t iline[LINES] ; //array of index for scrolling static uint8_t tline[LINES] ; static uint8_t mline[LINES] ; // mark to display
static char nameNum[5] ; // the number of the current station static char genre[BUFLEN/2]; // the local name of the station
/*static uint8_t charset = false;
//////////////////////////////////////// uint8_t getCharset() { return charset; } void setCharset(uint8_t cy) { charset = cy; } / //////////////////////////////////////// typedef enum sizefont {small, text,middle,large} sizefont; void setfont8(sizefont size) { // printf("setfont8 size: %d, yy: %d\n",size,yy); switch(size) { case small: switch(yy) { case 200: u8g2_SetFont(&u8g2,u8g2_font_6x12_tf); break; case 128: u8g2_SetFont(&u8g2,u8g2_font_6x12_tf); break; case 32: u8g2_SetFont(&u8g2,u8g2_font_u8glib_4_tr); break; case 64: default: // u8g2_SetFont(&u8g2, u8g2_font_5x8_tr); ; } break; case text: switch(yy) { / case 200: charset?u8g2_SetFont(&u8g2,u8g2_font_7x13_t_cyrillic):u8g2_SetFont(&u8g2,u8g2_font_7x14_tf);// break; case 128: charset?u8g2_SetFont(&u8g2,u8g2_font_7x13_t_cyrillic):u8g2_SetFont(&u8g2, u8g2_font_7x14_tf);// break; case 32: charset?u8g2_SetFont(&u8g2,u8g2_font_5x7_t_cyrillic):u8g2_SetFont(&u8g2,u8g2_font_5x7_tf);// break; case 64: default: // charset?u8g2_SetFont(&u8g2, u8g2_font_haxrcorp4089_t_cyrillic ):u8g2_SetFont(&u8g2, u8g2_font_6x12_tf); */ case 200: u8g2_SetFont(&u8g2, u8g2_font_8x13_t_latcyr);// break; case 128: u8g2_SetFont(&u8g2, u8g2_font_8x13_t_latcyr);// break; case 32: u8g2_SetFont(&u8g2, u8g2_font_5x7_t_latcyr);// break; case 64: default: // // u8g2_SetFont(&u8g2, u8g2_font_6x12_t_latcyr); u8g2_SetFont(&u8g2, u8g2_font_6x13_t_cyrillic); } break; case middle: switch(yy) { case 200: u8g2_SetFont(&u8g2, u8g2_font_9x18_tf); break; case 128: u8g2_SetFont(&u8g2, u8g2_font_9x18_tf); break; case 32: u8g2_SetFont(&u8g2, u8g2_font_5x8_tf); break; case 64: default: // u8g2_SetFont(&u8g2, u8g2_font_7x14_tf); ;
}
break;
case large:
switch(yy)
{
case 200:
u8g2_SetFont(&u8g2, u8g2_font_helvR24_tf);
break;
case 128:
u8g2_SetFont(&u8g2, u8g2_font_helvR24_tf);
break;
case 32:
u8g2_SetFont(&u8g2, u8g2_font_7x14_tf);
break;
case 64:
default: //
u8g2_SetFont(&u8g2, u8g2_font_ncenR18_tf);
;
}
break;
default:
printf("Default for size %d\n",size);
}
}
//////////////////////////////////////// char* getNameNumU8g2() { return nameNum; }
void setVolumeU8g2(uint16_t vol){ volume = vol;}
static uint8_t getFontLineSpacing()
{
return (u8g2_GetAscent(&u8g2) - u8g2_GetDescent(&u8g2));
}
////////////////////////////////////////
// Clear all buffers and indexes
void clearAllU8g2()
{
title[0] = 0;
station[0]=0;
for (int i=1;i<LINES;i++) {lline[i] = NULL;iline[i] = 0;tline[i] = 0;;mline[i]=1;}
}
////////////////////////////////////////
void cleartitleU8g2(uint8_t froml)
{
title[0] = 0;
for (int i = froml;i<LINES;i++) // clear lines
{
lline[i] = NULL;
iline[i] = 0;
tline[i] = 0;
mline[i] = 1;
}
}
// Mark the lines to draw void markDrawU8g2(int i) { mline[i] = 1; }
////////////////////////////////////////
// scroll each line
void scrollU8g2()
{
unsigned len , onechar;
for (int i = 0;i < LINES;i++)
{
if (tline[i]>0)
{
if (tline[i] == 4) {iline[i]= 0;markDrawU8g2(i);}
tline[i]--;
}
else
{
if ((lline[i] != NULL))
{
onechar = u8g2_GetUTF8Width(&u8g2,"M");
len = u8g2_GetUTF8Width(&u8g2,lline[i]+iline[i]);
if (i == 0) printf("scroll: len=%d, num= %d, str=%s\n",len,u8g2_GetUTF8Width(&u8g2,nameNum),lline[i]+iline[i]);
if (i == 0) len += u8g2_GetUTF8Width(&u8g2,nameNum)+ onechar;
if (i == 0) printf("x= %d,scroll: +iline[i]= %d, len=%d, x-onechar= %d\n",x,iline[i],len,x-onechar);
if (len >= x-onechar)
{iline[i]++;markDrawU8g2(i);}
else
tline[i] = 6;
}
}
}
}
// Bottom of screens
static void screenBottomU8g2()
{
//VOLUME
u8g2_DrawFrame(&u8g2,0,yy-3,x-1,3);
u8g2_DrawHLine(&u8g2,0,yy-2,((uint16_t)(x*volume)/255));
//TIME
if (yy != 32) // not enough room
{
setfont8(small);
u8g2_DrawUTF8(&u8g2,x/2-(u8g2_GetUTF8Width(&u8g2,strsec)/2),yy-y-3,strsec);
}
}
// draw the screen from buffer void drawLinesU8g2() { u8g2_SendBuffer(&u8g2); }
//Thanks to Max
void eraseSlashes(char str) {
//Symbols: \" \' \ \? \/
char sym = str, sym1;
if (str != NULL) {
while (sym != 0) {
if (sym == 0x5c) {
sym1 = sym + 1;
if (sym1 == 0x22 || sym1 == 0x27 || sym1 == 0x5c || sym1 == 0x3f || sym1 == 0x2f) {
*sym = 0x1f; //Erase \ to non-printable symbol
sym++;
}
}
sym++;
}
}
}
//-Max
//////////////////////////////////////// // draw all lines void drawFrameU8g2(uint8_t mTscreen,struct tm *dt) { u8g2_ClearBuffer(&u8g2); if (getDdmm()) sprintf(strsec,"%02d-%02d-%04d %02d:%02d:%02d",dt->tm_mday,dt->tm_mon+1,dt->tm_year+1900, dt->tm_hour, dt->tm_min,dt->tm_sec); else sprintf(strsec,"%02d-%02d-%04d %02d:%02d:%02d",dt->tm_mon+1,dt->tm_mday,dt->tm_year+1900, dt->tm_hour, dt->tm_min,dt->tm_sec);
setfont8(text);
u8g2_SetDrawColor(&u8g2, 1);
y = getFontLineSpacing();
u8g2_SetFontRefHeightText(&u8g2);
{
u8g2_DrawHLine(&u8g2,0,((yy==32)?3:4*y) - (y/2)-1,x);
u8g2_DrawBox(&u8g2,0,0,x-1,y);
}
for (int i = 0;i < LINES;i++)
{
if (i == 0){
u8g2_SetDrawColor(&u8g2, 0);
}
else {
if (i >=3) z = y/2+2 ; else z = 1;
u8g2_SetDrawColor(&u8g2, 1);
}
int zz = y*i;
if (yy==32)
{
if ((i==STATION2)||(i==TITLE2)) continue;
if (i==TITLE1) zz = y*GENRE;
}
if (lline[i] != NULL)
{
//Max
eraseSlashes(lline[i]);
if (i == 0)
{
if (nameNum[0] ==0) u8g2_DrawUTF8(&u8g2,1,0,lline[i]+iline[i]);
else
{
u8g2_DrawUTF8(&u8g2,1,0,nameNum);
u8g2_DrawUTF8(&u8g2,u8g2_GetUTF8Width(&u8g2,nameNum)-1,0,lline[i]+iline[i]);
}
}
else u8g2_DrawUTF8(&u8g2,0,zz+z,lline[i]+iline[i]);
}
}
screenBottomU8g2();
}
////////////////////////// void drawTTitleU8g2(char* ttitle) { setfont8(middle); uint16_t xxx = (x/2)-(u8g2_GetUTF8Width(&u8g2,ttitle)/2); u8g2_SetDrawColor(&u8g2, 1); u8g2_DrawBox(&u8g2,0,0,x,getFontLineSpacing()+1); u8g2_SetDrawColor(&u8g2, 0); u8g2_DrawUTF8(&u8g2,xxx,1,ttitle);
u8g2_SetDrawColor(&u8g2, 1);
}
//////////////////////////
void drawNumberU8g2(uint8_t mTscreen,char irStr)
{
char ststr[] = {"Number"};
u8g2_ClearBuffer(&u8g2);
drawTTitleU8g2(ststr);
setfont8(large);
uint16_t xxx = (x/2)-(u8g2_GetUTF8Width(&u8g2,irStr)/2);
u8g2_DrawUTF8(&u8g2,xxx,yy/3, irStr);
screenBottomU8g2();
}
//////////////////////////
void drawStationU8g2(uint8_t mTscreen,char snum,char* ddot)
{
int16_t len;
char ststr[] = {"Station"};
u8g2_ClearBuffer(&u8g2);
drawTTitleU8g2(ststr);
if (ddot != NULL)
{
u8g2_DrawUTF8(&u8g2,(x/2)-(u8g2_GetUTF8Width(&u8g2,snum)/2),yy/3-2, snum);
len = (x/2)-(u8g2_GetUTF8Width(&u8g2,ddot)/2);
if (len <0) len = 0;
u8g2_DrawUTF8(&u8g2,len,yy/3+4+y, ddot);
}
screenBottomU8g2();
}
void drawVolumeU8g2(uint8_t mTscreen,char* aVolume)
{
char vlstr[] = {"Volume"};
volume = atoi(aVolume);
u8g2_ClearBuffer(&u8g2);
drawTTitleU8g2(vlstr) ;
setfont8(large);
uint16_t xxx = (x/2)-(u8g2_GetUTF8Width(&u8g2,aVolume)/2);
u8g2_DrawUTF8(&u8g2,xxx,yy/3,aVolume);
screenBottomU8g2();
}
void drawTimeU8g2(uint8_t mTscreen,struct tm *dt,unsigned timein)
{
char strdate[23];
char strtime[20];
// printf("DRAW TIME U8G2 mtscreen : %d\n",mTscreen);
u8g2_ClearBuffer(&u8g2);
if (getDdmm())
sprintf(strdate,"%02d-%02d-%04d", dt->tm_mday, dt->tm_mon+1, dt->tm_year+1900);
else
sprintf(strdate,"%02d-%02d-%04d", dt->tm_mon+1, dt->tm_mday, dt->tm_year+1900);
sprintf(strtime,"%02d:%02d:%02d", dt->tm_hour, dt->tm_min,dt->tm_sec);
drawTTitleU8g2(strdate);
setfont8(large);
u8g2_DrawUTF8(&u8g2,(x/2)-(u8g2_GetUTF8Width(&u8g2,strtime)/2),(yy/3)+4,strtime);
// draw ip
setfont8(small);
sprintf(strdate,"IP: %s", getIp());
u8g2_DrawUTF8(&u8g2,(x/2)-(u8g2_GetUTF8Width(&u8g2,strdate)/2),yy-getFontLineSpacing(),strdate);
}
//////////////////////////////////////// void separatorU8g2(char from) { char interp; while (from[strlen(from)-1] == ' ') from[strlen(from)-1] = 0; // avoid blank at end while ((from[0] == ' ') ){ strcpy( from,from+1); } interp=strstr(from," - "); if (from == nameset) {lline[0] = nameset;lline[1] = NULL;lline[2] = NULL;return;} if ((interp != NULL) && (yy != 32)) { from[interp-from]= 0; lline[(from==station)?1:3] = from; lline[(from==station)?2:4] = interp+3; } else { lline[(from==station)?1:3] = from; } }
//cli.meta
void metaU8g2(char* ici)
{
cleartitleU8g2(3);
strcpy(title,ici+7);
separatorU8g2(title);
}
//cli.icy4
void icy4U8g2(char ici)
{
strcpy(genre,ici+7);
lline[2] = genre;
}
//cli.icy0
void icy0U8g2(char ici)
{
clearAllU8g2();
if (strlen(ici+7) == 0) strcpy (station,nameset);
else strcpy(station,ici+7);
separatorU8g2(station);
}
//cli.stopped or label
void statusU8g2(char label)
{
cleartitleU8g2(3);
strcpy(title,label);
lline[TITLE1] = title;
}
//cli.nameset
void namesetU8g2(char ici)
{
strcpy(nameset,ici+8);
ici = strstr(nameset," ");
if (ici != NULL)
{
clearAllU8g2();
strncpy(nameNum,nameset,ici-nameset+1);
nameNum[ici - nameset+1] = 0;
setFuturNum(atoi(nameNum));
}
strcpy(nameset,nameset+strlen(nameNum));
lline[STATIONNAME] = nameset;
}
// cli.playing void playingU8g2() { if (strcmp(title,"STOPPED") == 0) { cleartitleU8g2(3); separatorU8g2(title); } }
void lcd_initU8g2(uint8_t lcd_type) { const u8g2_cb_t rotat; u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT; if (*lcd_type & LCD_SPI) // BW SPI { u8g2_esp32_hal.clk = PIN_NUM_CLK; u8g2_esp32_hal.mosi = PIN_NUM_MOSI; u8g2_esp32_hal.cs = PIN_LCD_CS; u8g2_esp32_hal.dc = PIN_LCD_A0; u8g2_esp32_hal.reset = PIN_LCD_RST; } else //BW I2C { u8g2_esp32_hal.sda = PIN_I2C_SDA; u8g2_esp32_hal.scl = PIN_I2C_SCL; u8g2_esp32_hal.reset = PIN_I2C_RST; } u8g2_esp32_hal_init(u8g2_esp32_hal);
if (getRotat())
rotat = U8G2_R2;
else
rotat = U8G2_R0;
switch (*lcd_type){
case LCD_I2C_SH1106:
u8g2_Setup_sh1106_i2c_128x64_noname_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_I2C_SSD1306NN:
u8g2_Setup_ssd1306_i2c_128x64_noname_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_I2C_SSD1306:
u8g2_Setup_ssd1306_i2c_128x64_vcomh0_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_I2C_SSD1309:
u8g2_Setup_ssd1309_i2c_128x64_noname2_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_I2C_SSD1325:
u8g2_Setup_ssd1325_i2c_nhd_128x64_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_I2C_SSD1309NN:
u8g2_Setup_ssd1309_i2c_128x64_noname0_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_I2C_SSD1306UN:
u8g2_Setup_ssd1306_i2c_128x32_univision_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
//B/W spi
case LCD_SPI_SSD1306NN:
u8g2_Setup_ssd1306_128x64_noname_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_SSD1306:
u8g2_Setup_ssd1306_128x32_univision_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_SSD1309:
u8g2_Setup_ssd1309_128x64_noname2_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_SSD1309NN:
u8g2_Setup_ssd1309_128x64_noname0_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_ST7565_ZOLEN:
u8g2_Setup_st7565_zolen_128x64_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_SSD1322_NHD:
u8g2_Setup_ssd1322_nhd_256x64_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_IL3820_V2: //E Paper
u8g2_Setup_il3820_v2_296x128_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_SSD1607: //E Paper
u8g2_Setup_ssd1607_200x200_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_LS013B7DH03:
u8g2_Setup_ls013b7dh03_128x128_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break;
case LCD_SPI_ST7920:
u8g2_Setup_st7920_s_128x64_f(
&u8g2,
rotat,
u8g2_esp32_spi_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
break; default:
ESP_LOGE(TAG,"Unknown lcd lcd_type %d. Fall back to type 0",lcd_type);
lcd_type = 0;
u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;
u8g2_esp32_hal.sda = PIN_I2C_SDA;
u8g2_esp32_hal.scl = PIN_I2C_SCL;
u8g2_esp32_hal_init(u8g2_esp32_hal);
u8g2_Setup_sh1106_128x64_noname_f(
&u8g2,
rotat,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
}
ESP_LOGD(TAG,"lcd init BW type: %d",*lcd_type);
if (*lcd_type < LCD_SPI) u8x8_SetI2CAddress(&u8g2.u8x8,0x78);
u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
u8g2_SetPowerSave(&u8g2, 0); // wake up display
u8g2_ClearBuffer(&u8g2);
u8g2_ClearDisplay(&u8g2);
yy = u8g2.height;
x = u8g2.width;
z = 0;
u8g2_SetFontPosTop(&u8g2);
setfont8(text);
y = getFontLineSpacing();
if (yy>= logo_height)
u8g2_DrawXBM( &u8g2,x/2-logo_width/2, yy/2-logo_height/2, logo_width, logo_height, logo_bits);
else u8g2_DrawXBM( &u8g2,x/2-logo_width/2, 0, logo_width, logo_height, logo_bits);
u8g2_SendBuffer(&u8g2);
printf("X: %d, YY: %d, Y: %d\n",x,yy,y);
vTaskDelay(100);
z = 0;
}
`
hmmm... thats too much. Let me ask differently. Can you provide a small piece of complete code, which demonstrates the problem?
I don't have an arduino installed with u8g2 but it may be something like
int main() {
char str1[100]; char str2[100];
unsigned int len1,len2;
strcpy(str1,"Супердискотека 90х"); strcpy(str2,"Virgin Radio New");
u8g2_t u8g2; u8g2_Begin(&u8g2);
u8g2_SetFont(&u8g2, u8g2_font_6x13_t_cyrillic);
len1 = u8g2_GetUTF8Width(&u8g2,str1); len2 = u8g2_GetUTF8Width(&u8g2,str2);
printf("len1: %d, str1: %s\n",len1,str1); printf("len2: %d, str2: %s\n",len2,str2);
return 0;
}
It works as expected. The output is:
len1: 107, str1: Супердискотека 90х
len2: 95, str2: Virgin Radio New
Code is here: https://github.com/olikraus/u8g2/blob/master/sys/sdl/issue693/main.c#L26
Ok thanks. I think i made a beginner bug in the logic of the code. Thanks for your help and sorry.
no problem
I made a set of fonts with latin and cyrillic all in one bult with bdfconv.exe -v -f 1 -m "$20-$ff,$a0-$ff,$a0-$17F,$0400-$045f" ...... at https://github.com/karawin/Ka-Radio32/blob/master/components/u8g2/csrc/u8g2_karadio32_fonts.c and integrated in https://github.com/karawin/Ka-Radio32/blob/master/components/u8g2/csrc/u8g2.h
Thanks for your work. Is ucglib utf8 planned ?
Hum bdfconv.exe -v -f 1 -m "$20-$7f,$a0-$17F,$0400-$045f" ......
There is a utf8 add on lib for the adafruit gfx lib for TFT displays.
May be;-) but i wrote hal for your libs. Both in one code with only one configuration parameter to choose the type of lcd. Thanks JP
It seems that the function u8g2_GetUTF8Width has a problem on utf8 cyrillic (and may be other) strings.
The string "СупердиÑкотека 90Ñ…" ie:"Супердискотека 90х" return 19
While the string "Virgin Radio New" return 80
lcd SH1106
define U8G2_16BIT