olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
4.95k stars 1.04k forks source link

If char is 16bit type ~ drawstr () is also effective? #728

Closed fengxkd closed 5 years ago

fengxkd commented 5 years ago

I want use u8g2 on TI c28x series , and it worked- but the drawstr () has been garbled ~ I know TI minimum storage unit is 16bit, this means char is 16bit, and whether with this relationship?

olikraus commented 5 years ago

Can you post a piece of code for this? Which u8g2 constructor did you use?

fengxkd commented 5 years ago

this is my code , it worked well but the u8g2_DrawStr()

u8g2_Setup_ssd1306_128x64_noname_1(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, 
u8x8_tm320f28035_gpio_and_delay);
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
u8g2_FirstPage(&u8g2);
    do
    {
        WDReset();
    u8g2_SetFontMode(&u8g2, 1); // Transparent
    u8g2_SetFontDirection(&u8g2, 0);
    u8g2_SetFont(&u8g2, u8g2_font_6x12_mf);

    u8g2_SetDrawColor(&u8g2,1);
    u8g2_DrawFrame(&u8g2,0,0,128,64);

    u8g2_SetDrawColor(&u8g2,1);
    u8g2_DrawBox(&u8g2,31,30,22,21);
    u8g2_DrawFrame(&u8g2,28,32,24,22);
    u8g2_DrawCircle(&u8g2,40,50,20,U8G2_DRAW_ALL);
    u8g2_DrawStr(&u8g2, 20, 20, "hello world!");

    } while( u8g2_NextPage(&u8g2) );
//*************************************************************************************************
//font. the uint8_t is 16bit.
const uint8_t u8g2_font_6x12_mf[2509] U8G2_FONT_SECTION("u8g2_font_6x12_mf") =
  "\277\2\3\2\3\4\1\2\4\6\14\0\376\7\376\10\377\1|\3\27\11\260 \7\346\370\371O\0!\12"...

it display like this:

olikraus commented 5 years ago

I changed the font format in the last u8g2 release. Did you copied the font data into your code? And if so, did you copy the data during the last release and updated to the latest u8g2 version? If yes, then there might be a mismatch between the u8g2 code and the font format. In such a case, please takeover the font data from the lasted u8g2 code again.

fengxkd commented 5 years ago

I am sure I am using the latest version, I downloaded it yesterday. The fonts I use are all provided by u8g2, which means that the display is garbled~ but I can see it~ Is it related to the big and small? Because your package is too deep~ I can't find a way to come~ Thank you for your answer~

olikraus commented 5 years ago

ok, if you are sure, that code and font are from the same source, date and time, that indeed it might be an issue with the 16 bit.

can you attach/insert limits.h system include header of your stm32 compiler? It should include precise bit size information of your system.

fengxkd commented 5 years ago

Thanks, I will try it the next few days, and I use ti-complier not stm 32, maybe some other font can work well.

fengxkd commented 5 years ago

I think I find the answer.thanks..

u8g2_font.c line-237

/* optimized */
uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t cnt) 
{
  uint8_t val;
  uint8_t bit_pos = f->decode_bit_pos;
  uint8_t bit_pos_plus_cnt;

  //val = *(f->decode_ptr);
  val = u8x8_pgm_read( f->decode_ptr );//@fl will back some data over 0xff

  val >>= bit_pos;
  bit_pos_plus_cnt = bit_pos;
  bit_pos_plus_cnt += cnt;
  if ( bit_pos_plus_cnt >= 8 )
  {
    uint8_t s = 8;
    s -= bit_pos;
    f->decode_ptr++;
    //val |= *(f->decode_ptr) << (8-bit_pos);
    val |= u8x8_pgm_read( f->decode_ptr ) << (s);
    //bit_pos -= 8;
    bit_pos_plus_cnt -= 8;
  }
  val &= (1U<<cnt)-1;
  //bit_pos += cnt;

  f->decode_bit_pos = bit_pos_plus_cnt;

  return val;
}

so i take some change : u8x8.h line 170

#ifndef u8x8_pgm_read
#  define u8x8_pgm_read(adr) ((*(const uint8_t *)(adr))&0x00ff) //add &0x00ff
#endif

and it work well! but the another things comes, I wasted high 8-bit flash?

//uint8_t is 16bit
const uint8_t u8g2_font_wqy12_t_chinese1[9503] U8G2_FONT_SECTION("u8g2_font_wqy12_t_chinese1") =
  "\233\0\3\2\4\4\3\4\5\14\15\0\376\10\376\12\377\1a\2\317\4\30 \5\0L\13!\7\221F"
  "\213S\0\42\7\64}\213\310\24#\16\226\304\233\250eX\242^\206%j\1$\17\245<\253l\251(" 
  ...

olikraus commented 5 years ago

hmmm... I see the problem. uint8_t is 16 bit on your system and also the byte array is stored accordingly. So the problem here is, that the chars in the string are signed extended to 16 bit, which leads to the problem. The fact that 16 bits are stored for each byte in the font is indeed a waste of memory, but i guess there is nothing what I can do here.

olikraus commented 5 years ago

Actually I would like to implement a more clever solution.

#ifndef u8x8_pgm_read
#  ifndef CHAR_BIT
#   define u8x8_pgm_read(adr) (*(const uint8_t *)(adr)) 
#  else
#   if CHAR_BIT > 8 
#     define u8x8_pgm_read(adr) ((*(const uint8_t *)(adr)) & 0x0ff)
#     else
#     define u8x8_pgm_read(adr) (*(const uint8_t *)(adr)) 
#     endif 
#  endif
#endif

Is CHAR_BIT defined in the limits.h of your compiler? If yes, which value is defined for CHAR_BIT (it should be 16).

fengxkd commented 5 years ago

It's a very good way, Thanks for this great project!