unicode.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2010 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #ifndef GRUB_BIDI_HEADER
  19. #define GRUB_BIDI_HEADER 1
  20. #include <grub/types.h>
  21. #include <grub/mm.h>
  22. #include <grub/misc.h>
  23. struct grub_unicode_bidi_pair
  24. {
  25. grub_uint32_t key;
  26. grub_uint32_t replace;
  27. };
  28. struct grub_unicode_compact_range
  29. {
  30. unsigned start:21;
  31. unsigned len:9;
  32. unsigned bidi_type:5;
  33. unsigned comb_type:8;
  34. unsigned bidi_mirror:1;
  35. unsigned join_type:3;
  36. } GRUB_PACKED;
  37. /* Old-style Arabic shaping. Used for "visual UTF-8" and
  38. in grub-mkfont to find variant glyphs in absence of GPOS tables. */
  39. struct grub_unicode_arabic_shape
  40. {
  41. grub_uint32_t code;
  42. grub_uint32_t isolated;
  43. grub_uint32_t right_linked;
  44. grub_uint32_t both_linked;
  45. grub_uint32_t left_linked;
  46. };
  47. extern struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[];
  48. enum grub_bidi_type
  49. {
  50. GRUB_BIDI_TYPE_L = 0,
  51. GRUB_BIDI_TYPE_LRE,
  52. GRUB_BIDI_TYPE_LRO,
  53. GRUB_BIDI_TYPE_R,
  54. GRUB_BIDI_TYPE_AL,
  55. GRUB_BIDI_TYPE_RLE,
  56. GRUB_BIDI_TYPE_RLO,
  57. GRUB_BIDI_TYPE_PDF,
  58. GRUB_BIDI_TYPE_EN,
  59. GRUB_BIDI_TYPE_ES,
  60. GRUB_BIDI_TYPE_ET,
  61. GRUB_BIDI_TYPE_AN,
  62. GRUB_BIDI_TYPE_CS,
  63. GRUB_BIDI_TYPE_NSM,
  64. GRUB_BIDI_TYPE_BN,
  65. GRUB_BIDI_TYPE_B,
  66. GRUB_BIDI_TYPE_S,
  67. GRUB_BIDI_TYPE_WS,
  68. GRUB_BIDI_TYPE_ON
  69. };
  70. enum grub_join_type
  71. {
  72. GRUB_JOIN_TYPE_NONJOINING = 0,
  73. GRUB_JOIN_TYPE_LEFT = 1,
  74. GRUB_JOIN_TYPE_RIGHT = 2,
  75. GRUB_JOIN_TYPE_DUAL = 3,
  76. GRUB_JOIN_TYPE_CAUSING = 4,
  77. GRUB_JOIN_TYPE_TRANSPARENT = 5
  78. };
  79. enum grub_comb_type
  80. {
  81. GRUB_UNICODE_COMB_NONE = 0,
  82. GRUB_UNICODE_COMB_OVERLAY = 1,
  83. GRUB_UNICODE_COMB_HEBREW_SHEVA = 10,
  84. GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL = 11,
  85. GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH = 12,
  86. GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS = 13,
  87. GRUB_UNICODE_COMB_HEBREW_HIRIQ = 14,
  88. GRUB_UNICODE_COMB_HEBREW_TSERE = 15,
  89. GRUB_UNICODE_COMB_HEBREW_SEGOL = 16,
  90. GRUB_UNICODE_COMB_HEBREW_PATAH = 17,
  91. GRUB_UNICODE_COMB_HEBREW_QAMATS = 18,
  92. GRUB_UNICODE_COMB_HEBREW_HOLAM = 19,
  93. GRUB_UNICODE_COMB_HEBREW_QUBUTS = 20,
  94. GRUB_UNICODE_COMB_HEBREW_DAGESH = 21,
  95. GRUB_UNICODE_COMB_HEBREW_METEG = 22,
  96. GRUB_UNICODE_COMB_HEBREW_RAFE = 23,
  97. GRUB_UNICODE_COMB_HEBREW_SHIN_DOT = 24,
  98. GRUB_UNICODE_COMB_HEBREW_SIN_DOT = 25,
  99. GRUB_UNICODE_COMB_HEBREW_VARIKA = 26,
  100. GRUB_UNICODE_COMB_ARABIC_FATHATAN = 27,
  101. GRUB_UNICODE_COMB_ARABIC_DAMMATAN = 28,
  102. GRUB_UNICODE_COMB_ARABIC_KASRATAN = 29,
  103. GRUB_UNICODE_COMB_ARABIC_FATHAH = 30,
  104. GRUB_UNICODE_COMB_ARABIC_DAMMAH = 31,
  105. GRUB_UNICODE_COMB_ARABIC_KASRA = 32,
  106. GRUB_UNICODE_COMB_ARABIC_SHADDA = 33,
  107. GRUB_UNICODE_COMB_ARABIC_SUKUN = 34,
  108. GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF = 35,
  109. GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH = 36,
  110. GRUB_UNICODE_STACK_ATTACHED_BELOW = 202,
  111. GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214,
  112. GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216,
  113. GRUB_UNICODE_STACK_BELOW = 220,
  114. GRUB_UNICODE_COMB_BELOW_RIGHT = 222,
  115. GRUB_UNICODE_COMB_ABOVE_LEFT = 228,
  116. GRUB_UNICODE_STACK_ABOVE = 230,
  117. GRUB_UNICODE_COMB_ABOVE_RIGHT = 232,
  118. GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240,
  119. /* If combining nature is indicated only by class and
  120. not "combining type". */
  121. GRUB_UNICODE_COMB_ME = 253,
  122. GRUB_UNICODE_COMB_MC = 254,
  123. GRUB_UNICODE_COMB_MN = 255,
  124. };
  125. struct grub_unicode_combining
  126. {
  127. grub_uint32_t code:21;
  128. enum grub_comb_type type:8;
  129. };
  130. /* This structure describes a glyph as opposed to character. */
  131. struct grub_unicode_glyph
  132. {
  133. grub_uint32_t base:23; /* minimum: 21 */
  134. grub_uint16_t variant:9; /* minimum: 9 */
  135. grub_uint8_t attributes:5; /* minimum: 5 */
  136. grub_uint8_t bidi_level:6; /* minimum: 6 */
  137. enum grub_bidi_type bidi_type:5; /* minimum: :5 */
  138. unsigned ncomb:8;
  139. /* Hint by unicode subsystem how wide this character usually is.
  140. Real width is determined by font. Set only in UTF-8 stream. */
  141. int estimated_width:8;
  142. grub_size_t orig_pos;
  143. union
  144. {
  145. struct grub_unicode_combining combining_inline[sizeof (void *)
  146. / sizeof (struct grub_unicode_combining)];
  147. struct grub_unicode_combining *combining_ptr;
  148. };
  149. };
  150. #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1
  151. #define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT 1
  152. #define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED 0x2
  153. #define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \
  154. (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \
  155. << GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT)
  156. /* Set iff the corresponding joining flags come from ZWJ or ZWNJ. */
  157. #define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT 0x8
  158. #define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT \
  159. (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \
  160. << GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT)
  161. #define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN \
  162. (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \
  163. | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \
  164. | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \
  165. | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT)
  166. enum
  167. {
  168. GRUB_UNICODE_DOTLESS_LOWERCASE_I = 0x0131,
  169. GRUB_UNICODE_DOTLESS_LOWERCASE_J = 0x0237,
  170. GRUB_UNICODE_COMBINING_GRAPHEME_JOINER = 0x034f,
  171. GRUB_UNICODE_HEBREW_WAW = 0x05d5,
  172. GRUB_UNICODE_ARABIC_START = 0x0600,
  173. GRUB_UNICODE_ARABIC_END = 0x0700,
  174. GRUB_UNICODE_THAANA_ABAFILI = 0x07a6,
  175. GRUB_UNICODE_THAANA_AABAAFILI = 0x07a7,
  176. GRUB_UNICODE_THAANA_IBIFILI = 0x07a8,
  177. GRUB_UNICODE_THAANA_EEBEEFILI = 0x07a9,
  178. GRUB_UNICODE_THAANA_UBUFILI = 0x07aa,
  179. GRUB_UNICODE_THAANA_OOBOOFILI = 0x07ab,
  180. GRUB_UNICODE_THAANA_EBEFILI = 0x07ac,
  181. GRUB_UNICODE_THAANA_EYBEYFILI = 0x07ad,
  182. GRUB_UNICODE_THAANA_OBOFILI = 0x07ae,
  183. GRUB_UNICODE_THAANA_OABOAFILI = 0x07af,
  184. GRUB_UNICODE_THAANA_SUKUN = 0x07b0,
  185. GRUB_UNICODE_ZWNJ = 0x200c,
  186. GRUB_UNICODE_ZWJ = 0x200d,
  187. GRUB_UNICODE_LRM = 0x200e,
  188. GRUB_UNICODE_RLM = 0x200f,
  189. GRUB_UNICODE_LRE = 0x202a,
  190. GRUB_UNICODE_RLE = 0x202b,
  191. GRUB_UNICODE_PDF = 0x202c,
  192. GRUB_UNICODE_LRO = 0x202d,
  193. GRUB_UNICODE_RLO = 0x202e,
  194. GRUB_UNICODE_LEFTARROW = 0x2190,
  195. GRUB_UNICODE_UPARROW = 0x2191,
  196. GRUB_UNICODE_RIGHTARROW = 0x2192,
  197. GRUB_UNICODE_DOWNARROW = 0x2193,
  198. GRUB_UNICODE_UPDOWNARROW = 0x2195,
  199. GRUB_UNICODE_LIGHT_HLINE = 0x2500,
  200. GRUB_UNICODE_HLINE = 0x2501,
  201. GRUB_UNICODE_LIGHT_VLINE = 0x2502,
  202. GRUB_UNICODE_VLINE = 0x2503,
  203. GRUB_UNICODE_LIGHT_CORNER_UL = 0x250c,
  204. GRUB_UNICODE_CORNER_UL = 0x250f,
  205. GRUB_UNICODE_LIGHT_CORNER_UR = 0x2510,
  206. GRUB_UNICODE_CORNER_UR = 0x2513,
  207. GRUB_UNICODE_LIGHT_CORNER_LL = 0x2514,
  208. GRUB_UNICODE_CORNER_LL = 0x2517,
  209. GRUB_UNICODE_LIGHT_CORNER_LR = 0x2518,
  210. GRUB_UNICODE_CORNER_LR = 0x251b,
  211. GRUB_UNICODE_BLACK_UP_TRIANGLE = 0x25b2,
  212. GRUB_UNICODE_BLACK_RIGHT_TRIANGLE = 0x25ba,
  213. GRUB_UNICODE_BLACK_DOWN_TRIANGLE = 0x25bc,
  214. GRUB_UNICODE_BLACK_LEFT_TRIANGLE = 0x25c4,
  215. GRUB_UNICODE_VARIATION_SELECTOR_1 = 0xfe00,
  216. GRUB_UNICODE_VARIATION_SELECTOR_16 = 0xfe0f,
  217. GRUB_UNICODE_TAG_START = 0xe0000,
  218. GRUB_UNICODE_TAG_END = 0xe007f,
  219. GRUB_UNICODE_VARIATION_SELECTOR_17 = 0xe0100,
  220. GRUB_UNICODE_VARIATION_SELECTOR_256 = 0xe01ef,
  221. GRUB_UNICODE_LAST_VALID = 0x10ffff
  222. };
  223. extern struct grub_unicode_compact_range grub_unicode_compact[];
  224. extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[];
  225. #define GRUB_UNICODE_MAX_CACHED_CHAR 0x20000
  226. /* Unicode mandates an arbitrary limit. */
  227. #define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61
  228. struct grub_term_pos
  229. {
  230. unsigned valid:1;
  231. unsigned x:15, y:16;
  232. };
  233. grub_ssize_t
  234. grub_bidi_logical_to_visual (const grub_uint32_t *logical,
  235. grub_size_t logical_len,
  236. struct grub_unicode_glyph **visual_out,
  237. grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg),
  238. void *getcharwidth_arg,
  239. grub_size_t max_width,
  240. grub_size_t start_width, grub_uint32_t codechar,
  241. struct grub_term_pos *pos,
  242. int primitive_wrap);
  243. enum grub_comb_type
  244. grub_unicode_get_comb_type (grub_uint32_t c);
  245. grub_size_t
  246. grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
  247. struct grub_unicode_glyph *out);
  248. static inline const struct grub_unicode_combining *
  249. grub_unicode_get_comb (const struct grub_unicode_glyph *in)
  250. {
  251. if (in->ncomb == 0)
  252. return NULL;
  253. if (in->ncomb > ARRAY_SIZE (in->combining_inline))
  254. return in->combining_ptr;
  255. return in->combining_inline;
  256. }
  257. static inline void
  258. grub_unicode_destroy_glyph (struct grub_unicode_glyph *glyph)
  259. {
  260. if (glyph->ncomb > ARRAY_SIZE (glyph->combining_inline))
  261. grub_free (glyph->combining_ptr);
  262. glyph->ncomb = 0;
  263. }
  264. static inline struct grub_unicode_glyph *
  265. grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
  266. {
  267. struct grub_unicode_glyph *out = grub_malloc (sizeof (*out));
  268. if (!out)
  269. return NULL;
  270. grub_memcpy (out, in, sizeof (*in));
  271. if (in->ncomb > ARRAY_SIZE (out->combining_inline))
  272. {
  273. out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
  274. if (!out->combining_ptr)
  275. {
  276. grub_free (out);
  277. return NULL;
  278. }
  279. grub_memcpy (out->combining_ptr, in->combining_ptr,
  280. in->ncomb * sizeof (out->combining_ptr[0]));
  281. }
  282. else
  283. grub_memcpy (&out->combining_inline, &in->combining_inline,
  284. sizeof (out->combining_inline));
  285. return out;
  286. }
  287. static inline void
  288. grub_unicode_set_glyph (struct grub_unicode_glyph *out,
  289. const struct grub_unicode_glyph *in)
  290. {
  291. grub_memcpy (out, in, sizeof (*in));
  292. if (in->ncomb > ARRAY_SIZE (out->combining_inline))
  293. {
  294. out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
  295. if (!out->combining_ptr)
  296. return;
  297. grub_memcpy (out->combining_ptr, in->combining_ptr,
  298. in->ncomb * sizeof (out->combining_ptr[0]));
  299. }
  300. else
  301. grub_memcpy (&out->combining_inline, &in->combining_inline,
  302. sizeof (out->combining_inline));
  303. }
  304. static inline struct grub_unicode_glyph *
  305. grub_unicode_glyph_from_code (grub_uint32_t code)
  306. {
  307. struct grub_unicode_glyph *ret;
  308. ret = grub_zalloc (sizeof (*ret));
  309. if (!ret)
  310. return NULL;
  311. ret->base = code;
  312. return ret;
  313. }
  314. static inline void
  315. grub_unicode_set_glyph_from_code (struct grub_unicode_glyph *glyph,
  316. grub_uint32_t code)
  317. {
  318. grub_memset (glyph, 0, sizeof (*glyph));
  319. glyph->base = code;
  320. }
  321. grub_uint32_t
  322. grub_unicode_mirror_code (grub_uint32_t in);
  323. grub_uint32_t
  324. grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr);
  325. const grub_uint32_t *
  326. grub_unicode_get_comb_end (const grub_uint32_t *end,
  327. const grub_uint32_t *cur);
  328. #endif