SayoriOS  0.3.3
utf_conversion.c
1 //
2 // Created by maractus on 27.12.23. (I thought it decides from my GitHub username, but not hahaahahah)
3 //
4 
5 #include "lib/utf_conversion.h"
6 
8 void utf16_to_utf8(const unsigned short *utf16, int utf16_length, char *utf8) {
9  int i = 0;
10  int j = 0;
11 
12  while (i < utf16_length) {
13  unsigned int codepoint;
14 
15  if (utf16[i] < 0xD800 || utf16[i] > 0xDFFF) {
16  // Простой BMP символ (не суррогатная пара)
17  codepoint = utf16[i];
18  i++;
19  } else {
20  // Суррогатная пара
21  unsigned short high = utf16[i];
22  unsigned short low = utf16[i + 1];
23  codepoint = 0x10000 + ((high - 0xD800) << 10) + (low - 0xDC00);
24  i += 2;
25  }
26 
27  // Преобразование кодовой точки в UTF-8
28  if (codepoint < 0x80) {
29  utf8[j++] = (unsigned char)codepoint;
30  } else if (codepoint < 0x800) {
31  utf8[j++] = 0xC0 | ((codepoint >> 6) & 0x1F);
32  utf8[j++] = 0x80 | (codepoint & 0x3F);
33  } else if (codepoint < 0x10000) {
34  utf8[j++] = 0xE0 | ((codepoint >> 12) & 0x0F);
35  utf8[j++] = 0x80 | ((codepoint >> 6) & 0x3F);
36  utf8[j++] = 0x80 | (codepoint & 0x3F);
37  } else {
38  utf8[j++] = 0xF0 | ((codepoint >> 18) & 0x07);
39  utf8[j++] = 0x80 | ((codepoint >> 12) & 0x3F);
40  utf8[j++] = 0x80 | ((codepoint >> 6) & 0x3F);
41  utf8[j++] = 0x80 | (codepoint & 0x3F);
42  }
43  }
44 }