【问题标题】:Convert array of uint8_t into array of uint16_t (ASCII to Unicode)将 uint8_t 数组转换为 uint16_t 数组(ASCII 到 Unicode)
【发布时间】:2018-05-15 15:01:20
【问题描述】:

我有一个大小为 n>1 的 uint8_t 数组,并希望将其转换为大小相同的 n>1 的 uint16_t 数组。我实际上将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;
}

【问题讨论】:

  • 你有一段现有的代码要展示吗?
  • 如果你想要一个 16 位字符的字符串,仅仅转换数组变量是不够的。您需要在编码之间进行转换,在最简单的情况下,用零填充高字节,或者只使用专门用于此目的的函数,例如 Windows 上的 MultiByteToWideChar(),或者您的平台/框架提供的任何内容。
  • 您确实必须生成一个长度相等的新数组(长度以元素数量计)并在转换时将每个元素复制到其中。因为当前数组的每个元素都是 8 位宽,如果您将其转换为 16 位元素的数组,则 16 位数组中的每个元素都使用 8 位元素数组中的两个元素。一个 for 循环就可以了。

标签: c unicode ascii


【解决方案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
    }
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-23
      • 1970-01-01
      • 2019-10-14
      • 1970-01-01
      • 2021-11-16
      • 2011-09-19
      相关资源
      最近更新 更多