将uint8_t数组转换为uint16_t数组(ASCII到Unicode)

时间:2017-12-01 13:30:41

标签: c unicode ascii

我有一个大小为n> 1的uint8_t数组,并希望将其转换为大小相同的uint16_t数组n> 1。我实际上将uint8_t数组用于ASCII字符,并希望现在使用UNICODE。

有关如何进行此转换的任何想法?

编辑: 我想在这里使用这个函数,它适用于const char * string作为参数而不适用于const uint16_t *string。所以我需要投出它。

srv_err_t gui_write_text_16bit(const uint16_t *string, Layout_type_t layout,
    Layout_field_t field, Text_inverted_t inv) {
  srv_err_t err;
  uint8_t charCount;
  uint8_t byteCount;
  uint16_t bitmapCol = 0;
  uint16_t bitmapRow = 0;
  uint8_t textLength = 0;
  uint8_t textHeight = GUI_FONT_NAME.FontHeight;

  uint16_t offset;
  uint8_t mask;

  lcd_rectangle_t position;

  if (LAYOUT_A == layout) {
    if (LAYOUT_FIELD6 == field) {
      // Position 6 is not available in Layout A
      err.bits.input_parameter = true;
      return err;
    }
  }

  GUI_CONST_STORAGE GUI_CHARINFO
  *pcharInfo;
  GUI_CONST_STORAGE
  unsigned char* pchar;
  GUI_CONST_STORAGE GUI_FONT_PROP
  *pfontProp;

  //uint8_t textBitmap [bitmapLength * textHeight];
  uint8_t textBitmap[(LCD_COLUMN_NUMBER_DISPLAY / 8) * GUI_FONT_HEIGHT] = { 0 };

  /* Calculate needed space in the array */
  //      for (charCount = 0; charCount < stringLength; charCount++)
  for (charCount = 0; string[charCount] != '\0'; charCount++) {
    pfontProp = GUI_FONT_NAME.FontProp;

    while (0 != pfontProp) {
      if (pfontProp->First <= string[charCount]
          && pfontProp->Last >= string[charCount]) {
        offset = string[charCount] - pfontProp->First;
        pcharInfo = (pfontProp->pCharInfoFirstChar) + offset; // Pointer to the right character

        textLength += pcharInfo->XSize; // Text length in Pixels
        break; // exit while loop and beginn with next character
      }

      pfontProp = pfontProp->pNext;
    }
  }

  textLength = (textLength / 8) + 1;        // Text length in Bytes

  //      for(charCount = 0; charCount < stringLength; charCount++)

  for (charCount = 0; string[charCount] != '\0'; charCount++) {
    pfontProp = GUI_FONT_NAME.FontProp;

    while (0 != pfontProp) {
      if (pfontProp->First <= string[charCount]
          && pfontProp->Last >= string[charCount]) {
        // Character in Range found
        offset = string[charCount] - pfontProp->First;
        pcharInfo = (pfontProp->pCharInfoFirstChar) + offset; // Pointer to the right character
        pchar = pcharInfo->pData;

        for (bitmapRow = 0; bitmapRow < textHeight; bitmapRow++) {
          uint16_t bitmapByte = 0;
          uint16_t charByte = 0;
          uint8_t pixelShift;
          for (byteCount = 0; byteCount < pcharInfo->BytesPerLine;
              byteCount++) {
            //bitmapByte = bitmapRow * bitmapLength + (bitmapCol / 8) + byteCount;
            bitmapByte = bitmapRow * textLength + (bitmapCol / 8) + byteCount;
            charByte = pcharInfo->BytesPerLine * bitmapRow + byteCount;
            pixelShift = bitmapCol % 8;

            if (byteCount == (pcharInfo->BytesPerLine - 1)) {
              // Last Byte in row

              switch (pcharInfo->XSize % 8) {
                case 1:
                  mask = 0x80;
                  break;
                case 2:
                  mask = 0xC0;
                  break;
                case 3:
                  mask = 0xE0;
                  break;
                case 4:
                  mask = 0xF0;
                  break;
                case 5:
                  mask = 0xF8;
                  break;
                case 6:
                  mask = 0xFC;
                  break;
                case 7:
                  mask = 0xFE;
                  break;
                case 0:
                  mask = 0xFF;
                  break;
                default:
                  break;
              }
              textBitmap[bitmapByte] |= (pchar[charByte] & mask) >> pixelShift;
              textBitmap[bitmapByte + 1] |= (pchar[charByte] & mask)
                  << (8 - pixelShift);
              //bitmapCol += pcharInfo->XSize % 8;
            } else {

              /* charByte is not aligned with the bitmapByte. A direct copy is not possible */
              textBitmap[bitmapByte] |= pchar[charByte] >> pixelShift;

              textBitmap[bitmapByte + 1] |= pchar[charByte]
                  << (8 - pixelShift);

            }

          }
        }
        bitmapCol += pcharInfo->XSize;

        break; // exit while loop and beginn with next character
      }
      pfontProp = pfontProp->pNext;
    }
  }

  if (layout == LAYOUT_A) {
    position = Layout_A_Text_Field[field];

    /* place Bitmap on the right display Position */
    if (LAYOUT_TITLE == field) {
      gui_place_text(&position, textLength, textHeight, ALIGN_CENTER);
    } else {
      gui_place_text(&position, textLength, textHeight, ALIGN_LEFT);
    }

    if (LAYOUT_FIELD2 == field) {
      lcd_draw_text(position, textBitmap, sizeof(textBitmap),
          Layout_A_Field[field], DRAW_INVERSE);
    } else {
      lcd_draw_text(position, textBitmap, sizeof(textBitmap),
          Layout_A_Field[field], DRAW_NORMAL);
    }
  }
  return err;
}

2 个答案:

答案 0 :(得分:1)

转换是没有意义的,因为char数组中的每个元素使用1个单字节,而UNICODE uint16_t数组需要2个。但如果您的初始字符串仅由ASCII或Latin1字符组成,则可以使用ASCII或Latin1字符的unicode代码点只是字符值的事实。

因此,如果生成的数组在调用者中分配,则可以使用如下的代码:

// Convert an ASCII or Latin1 string to a 16bits unicode string:
void tounicode(uint16_t *dest, const char *src, size_t nchars) {
    while(nchars-- > 0) {                    // process nchars characters
        *dest++ = (unsigned char) *src++;    // one at a time
    }
}

答案 1 :(得分:0)

如果您使用的是x86硬件,请查看在2个机器操作中将16字节向量转换为两个8元素uint16向量的SSE2例程。 _mm_unpacklo_epi8()和... unpackhi ...