阿里兄 发表于 2019-11-15 09:15:29

裸机解析并显示emwin字体代码





增加个utf-8编码支持
//返回解码utf8的字节数
uint32_t getByteNumOfDecodeUtf8(uint8_t byte){
      //byte应该是utf8的最高1字节,如果指向了utf8编码后面低字节部分则返回0
      if((byte & 0xc0)==0x80) return 0;//1000 0000
      if((byte & 0xf8)==0xf0) return 4;//1111 0000
      if((byte & 0xf0)==0xf0) return 3;//1110 0000
      if((byte & 0xe0)==0xc0) return 2;//1100 0000
      return 1;          //ASCII码
}
//解码以bytePtr为起始地址的utf8序列,其最大长度为length,若不是utf8序列就返回-1
int decodeUtf8(const uint8_t* bytePtr, uint32_t length){
      //若是1字节的ascii码: 0xxxxxxx
      if(*bytePtr <= 0x7f) return *bytePtr;
      
      int value;
      uint32_t remainingBytes;

      //先读取高1字节
      //根据高1字节的高n位判断相应字节数的utf8编码
      if((*bytePtr & 0xe0)==0xc0){
                //若是2字节的utf8
                value = *bytePtr & 0x1f; //记录后面的5位有效位
                remainingBytes = 1;
      }      
      else if((*bytePtr & 0xf0)==0xe0){
                //若是3字节的utf8
                value = *bytePtr & 0x0f; //记录后面的4位有效位
                remainingBytes = 2;
      }
      else if((*bytePtr & 0xf8)==0xf0){
                //若是4字节的utf8
                value = *bytePtr & 0x07;
                remainingBytes = 3;
      }
      else {return -1;} //非法编码
      
      //如果utf8被斩断了就不再读下去了
      if(remainingBytes > length - 1){return -1;}

      //再读取低字节中的数据
      while(remainingBytes > 0){
                bytePtr++;
                remainingBytes--;
                //高两位必须是10
                if((*bytePtr & 0xc0) != 0x80){return -1;}
                //从次高字节往低字节读
                value = value << 6 | (*bytePtr & 0x3f); //value左移6为写入6位有效位
      }
      return value;   //返回解码得到的value值
}
//显示字符串,支持中英文显示
void gui_disp_string(uint16_t x, uint16_t y, const uint8_t *str)
{
    while(*str)
    {   
      //GBK格式
      // if(*str < 0xA0)
      // {
            // gui_disp_char(&x, &y, *str++);
      // }
      // else
      // {
            // uint16_t ch = (uint16_t)*str++ << 8;
            // gui_disp_char(&x, &y, (ch | (uint16_t)*str++));
      // }
      //UTF-8格式
      int data = decodeUtf8(str, strlen(str));
      if(data==-1){
            return;
      }
      else{
            gui_disp_char(&x, &y, data);
            int pos = getByteNumOfDecodeUtf8(*str);
            if(pos==0){
                return;
            }
            str += pos;
      }
    }
}


页: [1]
查看完整版本: 裸机解析并显示emwin字体代码