0

我正在开发一个在显示器/LCD 上正确显示阿拉伯语单词的功能。(阿拉伯字母有四种不同的模式。)我有一组Map array不同状态的阿拉伯字母 ( )。识别阿拉伯语字母后,我需要重新对齐字母。我的问题是如何将 Unicode 字符通过表 ( Map Table)放入String variable(pBuffer)?

例如:要写单词باب,您需要从中选择字母Map table并将其放在 aString中以发送到显示器/LCD。

...
const unsigned char Map[][5] PROGMEM = {

     /* code, isolated, initial, medial, final */
    {0x0621, 0xFE80, 0x0000, 0x0000, 0x0000 },  //1 /* HAMZA ء*/
    {0x0622, 0xFE81, 0x0000, 0x0000, 0xFE82 },  //2/* ALEF_MADDA آ*/
    {0x0623, 0xFE83, 0x0000, 0x0000, 0xFE84 },  //3/* ALEF_HAMZA_ABOVE أ*/
    {0x0624, 0xFE85, 0x0000, 0x0000, 0xFE86 },  //4/* WAW_HAMZA ؤ*/
    {0x0625, 0xFE87, 0x0000, 0x0000, 0xFE88 },  //5/* ALEF_HAMZA_BELOW إ*/
    {0x0626, 0xFE89, 0xFE8B, 0xFE8C, 0xFE8A },  //6/* YEH_HAMZA ئ*/
    {0x0627, 0xFE8D, 0x0000, 0x0000, 0xFE8E },  //7/* ALEF ا*/
    {0x0628, 0xFE8F, 0xFE91, 0xFE92, 0xFE90 }   //8/* BEH ب*/
};

String pBuffer;
pBuffer += ((char)(Map[7][4]));
pBuffer += ((char)(Map[6][6]));
pBuffer += ((char)(Map[7][3]));

u8g2.setCursor(5, 20);
u8g2.print(pBuffer);
...

不幸的是,上面使用的方法不起作用。如何从上面的“地图”表中选择字符并将它们放在一个String变量中?

4

1 回答 1

0

首先,我必须建议您查找这些阿拉伯字符的 UTF-8 值。Arduino 和 u8g2 都支持 UTF-8 编码,但不支持 UTF-16。从 UTF-8 值数组开始时,解决此问题要简单得多。

对于 UTF-8 字符,编译器可以为您转换字符串文字中的代码点:

String character = u8"\u0628"; // ب

在内部,该字符串将包含两个字节,表示 UTF-8 中的“ب”。对于 UTF-8 或 UTF-16 中的任何阿拉伯字符,单个char存储空间不足,因此必须使用数组 ( ) 或.char*String

Arduino IDE 也允许您直接在代码中编写 Unicode 字符文字:

String character = "ب";

只要源代码以 UTF-8 格式保存,字符串就会与上面的u8"\u0628"值相同。

您可以重写您的字符映射以使用 a String,然后只需按字面输入阿拉伯字符或使用代码点方法:(使用重音拉丁字符,例如此处)

const String Map[][5] PROGMEM = {
  {"a", "à", "á", "A", "Á"},
  {"e", "è", "é", "E", "É"}
};

当然,String将使用超过 2 个字节来存储这些字符,因此您可以通过将字符存储为 16 位整数来节省空间,但您必须事先进行一些转换。

Unicode 代码点实际上并不是您将在字符缓冲区中看到的二进制表示。U+0628 = ب但实际的二进制表示是0xD8A8. 是您应该存储在 Map 中的值,而不是0x0628您已经拥有的代码点 ( )。

const uint16_t Map[][5] PROGMEM = {
  {0xD8A8, ..., ..., ...},
  ...
};

如果您使用String地图,您可以轻松地从中构建字符串:

String output = Map[i][2] + Map[j][3] + Map[k][4];

如果使用uint16_t,则必须将整数值拆分为两个字节以添加字符:

uint16_t v = Map[i][j];  // v = 0xD8A8 for example
char lo = v & 0xFF;   // The D8 part of 0xD8A8, lo = 0xD8
char hi = v >> 8;     // The A8 part of 0xD8A8, hi = 0xA8
String output = String(hi) + String(lo); // output = {0xA8, 0xD8}

最后,您必须将 转换Stringchar*缓冲区以使用 with U8g2::drawUTF8()。您可以通过使用output.c_str()来获取底层char*缓冲区。

于 2019-08-28T17:14:59.913 回答