1 
2 //          Copyright Ahmet Sait Koçak 2020.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          https://www.boost.org/LICENSE_1_0.txt)
6 
7 module bindbc.hb.bind.common;
8 
9 extern(C) @nogc nothrow:
10 
11 /* !__cplusplus */
12 /* !__cplusplus */
13 
14 /* VS 2010 (_MSC_VER 1600) has stdint.h */
15 
16 alias hb_bool_t = int;
17 
18 alias hb_codepoint_t = uint;
19 alias hb_position_t = int;
20 alias hb_mask_t = uint;
21 
22 union _hb_var_int_t
23 {
24     uint u32;
25     int i32;
26     ushort[2] u16;
27     short[2] i16;
28     ubyte[4] u8;
29     byte[4] i8;
30 }
31 
32 alias hb_var_int_t = _hb_var_int_t;
33 
34 /* hb_tag_t */
35 
36 alias hb_tag_t = uint;
37 
38 extern (D) hb_tag_t HB_TAG(char c1, char c2, char c3, char c4)
39 {
40     return cast(hb_tag_t) ((cast(uint) c1 & 0xFF) << 24) | ((cast(uint) c2 & 0xFF) << 16) | ((cast(uint) c3 & 0xFF) << 8) | (cast(uint) c4 & 0xFF);
41 }
42 
43 enum HB_TAG_NONE = HB_TAG(0, 0, 0, 0);
44 enum HB_TAG_MAX = HB_TAG(0xff, 0xff, 0xff, 0xff);
45 enum HB_TAG_MAX_SIGNED = HB_TAG(0x7f, 0xff, 0xff, 0xff);
46 
47 /* len=-1 means str is NUL-terminated. */
48 version(BindHB_Static)
49     hb_tag_t hb_tag_from_string (const(char)* str, int len);
50 else
51 {
52     private alias fp_hb_tag_from_string = hb_tag_t function (const(char)* str, int len);
53     __gshared fp_hb_tag_from_string hb_tag_from_string;
54 }
55 
56 /* buf should have 4 bytes. */
57 version(BindHB_Static)
58     void hb_tag_to_string (hb_tag_t tag, char* buf);
59 else
60 {
61     private alias fp_hb_tag_to_string = void function (hb_tag_t tag, char* buf);
62     __gshared fp_hb_tag_to_string hb_tag_to_string;
63 }
64 
65 /**
66  * hb_direction_t:
67  * @HB_DIRECTION_INVALID: Initial, unset direction.
68  * @HB_DIRECTION_LTR: Text is set horizontally from left to right.
69  * @HB_DIRECTION_RTL: Text is set horizontally from right to left.
70  * @HB_DIRECTION_TTB: Text is set vertically from top to bottom.
71  * @HB_DIRECTION_BTT: Text is set vertically from bottom to top.
72  */
73 enum : int
74 {
75     HB_DIRECTION_INVALID = 0,
76     HB_DIRECTION_LTR = 4,
77     HB_DIRECTION_RTL = 5,
78     HB_DIRECTION_TTB = 6,
79     HB_DIRECTION_BTT = 7
80 }
81 alias hb_direction_t = int;
82 
83 /* len=-1 means str is NUL-terminated */
84 version(BindHB_Static)
85     hb_direction_t hb_direction_from_string (const(char)* str, int len);
86 else
87 {
88     private alias fp_hb_direction_from_string = hb_direction_t function (const(char)* str, int len);
89     __gshared fp_hb_direction_from_string hb_direction_from_string;
90 }
91 
92 version(BindHB_Static)
93     const(char)* hb_direction_to_string (hb_direction_t direction);
94 else
95 {
96     private alias fp_hb_direction_to_string = const(char)* function (hb_direction_t direction);
97     __gshared fp_hb_direction_to_string hb_direction_to_string;
98 }
99 
100 extern (D) hb_bool_t HB_DIRECTION_IS_VALID(uint dir)
101 {
102     return (dir & ~3U) == 4;
103 }
104 
105 /* Direction must be valid for the following */
106 extern (D) hb_bool_t HB_DIRECTION_IS_HORIZONTAL(uint dir)
107 {
108     return (dir & ~1U) == 4;
109 }
110 
111 extern (D) hb_bool_t HB_DIRECTION_IS_VERTICAL(uint dir)
112 {
113     return (dir & ~1U) == 6;
114 }
115 
116 extern (D) hb_bool_t HB_DIRECTION_IS_FORWARD(uint dir)
117 {
118     return (dir & ~2U) == 4;
119 }
120 
121 extern (D) hb_bool_t HB_DIRECTION_IS_BACKWARD(uint dir)
122 {
123     return (dir & ~2U) == 5;
124 }
125 
126 extern (D) hb_direction_t HB_DIRECTION_REVERSE(uint dir)
127 {
128     return cast(hb_direction_t) (dir ^ 1);
129 }
130 
131 /* hb_language_t */
132 
133 struct hb_language_impl_t;
134 alias hb_language_t = const(hb_language_impl_t)*;
135 
136 version(BindHB_Static)
137     hb_language_t hb_language_from_string (const(char)* str, int len);
138 else
139 {
140     private alias fp_hb_language_from_string = hb_language_t function (const(char)* str, int len);
141     __gshared fp_hb_language_from_string hb_language_from_string;
142 }
143 
144 version(BindHB_Static)
145     const(char)* hb_language_to_string (hb_language_t language);
146 else
147 {
148     private alias fp_hb_language_to_string = const(char)* function (hb_language_t language);
149     __gshared fp_hb_language_to_string hb_language_to_string;
150 }
151 
152 enum HB_LANGUAGE_INVALID = cast(hb_language_t) 0;
153 
154 version(BindHB_Static)
155     hb_language_t hb_language_get_default ();
156 else
157 {
158     private alias fp_hb_language_get_default = hb_language_t function ();
159     __gshared fp_hb_language_get_default hb_language_get_default;
160 }
161 
162 /* hb_script_t */
163 
164 /* https://unicode.org/iso15924/ */
165 /* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */
166 /* Unicode Character Database property: Script (sc) */
167 enum : hb_tag_t
168 {
169     /*1.1*/
170     HB_SCRIPT_COMMON = HB_TAG('Z', 'y', 'y', 'y'),
171     /*1.1*/
172     HB_SCRIPT_INHERITED = HB_TAG('Z', 'i', 'n', 'h'),
173     /*5.0*/
174     HB_SCRIPT_UNKNOWN = HB_TAG('Z', 'z', 'z', 'z'),
175 
176     /*1.1*/
177     HB_SCRIPT_ARABIC = HB_TAG('A', 'r', 'a', 'b'),
178     /*1.1*/
179     HB_SCRIPT_ARMENIAN = HB_TAG('A', 'r', 'm', 'n'),
180     /*1.1*/
181     HB_SCRIPT_BENGALI = HB_TAG('B', 'e', 'n', 'g'),
182     /*1.1*/
183     HB_SCRIPT_CYRILLIC = HB_TAG('C', 'y', 'r', 'l'),
184     /*1.1*/
185     HB_SCRIPT_DEVANAGARI = HB_TAG('D', 'e', 'v', 'a'),
186     /*1.1*/
187     HB_SCRIPT_GEORGIAN = HB_TAG('G', 'e', 'o', 'r'),
188     /*1.1*/
189     HB_SCRIPT_GREEK = HB_TAG('G', 'r', 'e', 'k'),
190     /*1.1*/
191     HB_SCRIPT_GUJARATI = HB_TAG('G', 'u', 'j', 'r'),
192     /*1.1*/
193     HB_SCRIPT_GURMUKHI = HB_TAG('G', 'u', 'r', 'u'),
194     /*1.1*/
195     HB_SCRIPT_HANGUL = HB_TAG('H', 'a', 'n', 'g'),
196     /*1.1*/
197     HB_SCRIPT_HAN = HB_TAG('H', 'a', 'n', 'i'),
198     /*1.1*/
199     HB_SCRIPT_HEBREW = HB_TAG('H', 'e', 'b', 'r'),
200     /*1.1*/
201     HB_SCRIPT_HIRAGANA = HB_TAG('H', 'i', 'r', 'a'),
202     /*1.1*/
203     HB_SCRIPT_KANNADA = HB_TAG('K', 'n', 'd', 'a'),
204     /*1.1*/
205     HB_SCRIPT_KATAKANA = HB_TAG('K', 'a', 'n', 'a'),
206     /*1.1*/
207     HB_SCRIPT_LAO = HB_TAG('L', 'a', 'o', 'o'),
208     /*1.1*/
209     HB_SCRIPT_LATIN = HB_TAG('L', 'a', 't', 'n'),
210     /*1.1*/
211     HB_SCRIPT_MALAYALAM = HB_TAG('M', 'l', 'y', 'm'),
212     /*1.1*/
213     HB_SCRIPT_ORIYA = HB_TAG('O', 'r', 'y', 'a'),
214     /*1.1*/
215     HB_SCRIPT_TAMIL = HB_TAG('T', 'a', 'm', 'l'),
216     /*1.1*/
217     HB_SCRIPT_TELUGU = HB_TAG('T', 'e', 'l', 'u'),
218     /*1.1*/
219     HB_SCRIPT_THAI = HB_TAG('T', 'h', 'a', 'i'),
220 
221     /*2.0*/
222     HB_SCRIPT_TIBETAN = HB_TAG('T', 'i', 'b', 't'),
223 
224     /*3.0*/
225     HB_SCRIPT_BOPOMOFO = HB_TAG('B', 'o', 'p', 'o'),
226     /*3.0*/
227     HB_SCRIPT_BRAILLE = HB_TAG('B', 'r', 'a', 'i'),
228     /*3.0*/
229     HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG('C', 'a', 'n', 's'),
230     /*3.0*/
231     HB_SCRIPT_CHEROKEE = HB_TAG('C', 'h', 'e', 'r'),
232     /*3.0*/
233     HB_SCRIPT_ETHIOPIC = HB_TAG('E', 't', 'h', 'i'),
234     /*3.0*/
235     HB_SCRIPT_KHMER = HB_TAG('K', 'h', 'm', 'r'),
236     /*3.0*/
237     HB_SCRIPT_MONGOLIAN = HB_TAG('M', 'o', 'n', 'g'),
238     /*3.0*/
239     HB_SCRIPT_MYANMAR = HB_TAG('M', 'y', 'm', 'r'),
240     /*3.0*/
241     HB_SCRIPT_OGHAM = HB_TAG('O', 'g', 'a', 'm'),
242     /*3.0*/
243     HB_SCRIPT_RUNIC = HB_TAG('R', 'u', 'n', 'r'),
244     /*3.0*/
245     HB_SCRIPT_SINHALA = HB_TAG('S', 'i', 'n', 'h'),
246     /*3.0*/
247     HB_SCRIPT_SYRIAC = HB_TAG('S', 'y', 'r', 'c'),
248     /*3.0*/
249     HB_SCRIPT_THAANA = HB_TAG('T', 'h', 'a', 'a'),
250     /*3.0*/
251     HB_SCRIPT_YI = HB_TAG('Y', 'i', 'i', 'i'),
252 
253     /*3.1*/
254     HB_SCRIPT_DESERET = HB_TAG('D', 's', 'r', 't'),
255     /*3.1*/
256     HB_SCRIPT_GOTHIC = HB_TAG('G', 'o', 't', 'h'),
257     /*3.1*/
258     HB_SCRIPT_OLD_ITALIC = HB_TAG('I', 't', 'a', 'l'),
259 
260     /*3.2*/
261     HB_SCRIPT_BUHID = HB_TAG('B', 'u', 'h', 'd'),
262     /*3.2*/
263     HB_SCRIPT_HANUNOO = HB_TAG('H', 'a', 'n', 'o'),
264     /*3.2*/
265     HB_SCRIPT_TAGALOG = HB_TAG('T', 'g', 'l', 'g'),
266     /*3.2*/
267     HB_SCRIPT_TAGBANWA = HB_TAG('T', 'a', 'g', 'b'),
268 
269     /*4.0*/
270     HB_SCRIPT_CYPRIOT = HB_TAG('C', 'p', 'r', 't'),
271     /*4.0*/
272     HB_SCRIPT_LIMBU = HB_TAG('L', 'i', 'm', 'b'),
273     /*4.0*/
274     HB_SCRIPT_LINEAR_B = HB_TAG('L', 'i', 'n', 'b'),
275     /*4.0*/
276     HB_SCRIPT_OSMANYA = HB_TAG('O', 's', 'm', 'a'),
277     /*4.0*/
278     HB_SCRIPT_SHAVIAN = HB_TAG('S', 'h', 'a', 'w'),
279     /*4.0*/
280     HB_SCRIPT_TAI_LE = HB_TAG('T', 'a', 'l', 'e'),
281     /*4.0*/
282     HB_SCRIPT_UGARITIC = HB_TAG('U', 'g', 'a', 'r'),
283 
284     /*4.1*/
285     HB_SCRIPT_BUGINESE = HB_TAG('B', 'u', 'g', 'i'),
286     /*4.1*/
287     HB_SCRIPT_COPTIC = HB_TAG('C', 'o', 'p', 't'),
288     /*4.1*/
289     HB_SCRIPT_GLAGOLITIC = HB_TAG('G', 'l', 'a', 'g'),
290     /*4.1*/
291     HB_SCRIPT_KHAROSHTHI = HB_TAG('K', 'h', 'a', 'r'),
292     /*4.1*/
293     HB_SCRIPT_NEW_TAI_LUE = HB_TAG('T', 'a', 'l', 'u'),
294     /*4.1*/
295     HB_SCRIPT_OLD_PERSIAN = HB_TAG('X', 'p', 'e', 'o'),
296     /*4.1*/
297     HB_SCRIPT_SYLOTI_NAGRI = HB_TAG('S', 'y', 'l', 'o'),
298     /*4.1*/
299     HB_SCRIPT_TIFINAGH = HB_TAG('T', 'f', 'n', 'g'),
300 
301     /*5.0*/
302     HB_SCRIPT_BALINESE = HB_TAG('B', 'a', 'l', 'i'),
303     /*5.0*/
304     HB_SCRIPT_CUNEIFORM = HB_TAG('X', 's', 'u', 'x'),
305     /*5.0*/
306     HB_SCRIPT_NKO = HB_TAG('N', 'k', 'o', 'o'),
307     /*5.0*/
308     HB_SCRIPT_PHAGS_PA = HB_TAG('P', 'h', 'a', 'g'),
309     /*5.0*/
310     HB_SCRIPT_PHOENICIAN = HB_TAG('P', 'h', 'n', 'x'),
311 
312     /*5.1*/
313     HB_SCRIPT_CARIAN = HB_TAG('C', 'a', 'r', 'i'),
314     /*5.1*/
315     HB_SCRIPT_CHAM = HB_TAG('C', 'h', 'a', 'm'),
316     /*5.1*/
317     HB_SCRIPT_KAYAH_LI = HB_TAG('K', 'a', 'l', 'i'),
318     /*5.1*/
319     HB_SCRIPT_LEPCHA = HB_TAG('L', 'e', 'p', 'c'),
320     /*5.1*/
321     HB_SCRIPT_LYCIAN = HB_TAG('L', 'y', 'c', 'i'),
322     /*5.1*/
323     HB_SCRIPT_LYDIAN = HB_TAG('L', 'y', 'd', 'i'),
324     /*5.1*/
325     HB_SCRIPT_OL_CHIKI = HB_TAG('O', 'l', 'c', 'k'),
326     /*5.1*/
327     HB_SCRIPT_REJANG = HB_TAG('R', 'j', 'n', 'g'),
328     /*5.1*/
329     HB_SCRIPT_SAURASHTRA = HB_TAG('S', 'a', 'u', 'r'),
330     /*5.1*/
331     HB_SCRIPT_SUNDANESE = HB_TAG('S', 'u', 'n', 'd'),
332     /*5.1*/
333     HB_SCRIPT_VAI = HB_TAG('V', 'a', 'i', 'i'),
334 
335     /*5.2*/
336     HB_SCRIPT_AVESTAN = HB_TAG('A', 'v', 's', 't'),
337     /*5.2*/
338     HB_SCRIPT_BAMUM = HB_TAG('B', 'a', 'm', 'u'),
339     /*5.2*/
340     HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG('E', 'g', 'y', 'p'),
341     /*5.2*/
342     HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG('A', 'r', 'm', 'i'),
343     /*5.2*/
344     HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG('P', 'h', 'l', 'i'),
345     /*5.2*/
346     HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG('P', 'r', 't', 'i'),
347     /*5.2*/
348     HB_SCRIPT_JAVANESE = HB_TAG('J', 'a', 'v', 'a'),
349     /*5.2*/
350     HB_SCRIPT_KAITHI = HB_TAG('K', 't', 'h', 'i'),
351     /*5.2*/
352     HB_SCRIPT_LISU = HB_TAG('L', 'i', 's', 'u'),
353     /*5.2*/
354     HB_SCRIPT_MEETEI_MAYEK = HB_TAG('M', 't', 'e', 'i'),
355     /*5.2*/
356     HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG('S', 'a', 'r', 'b'),
357     /*5.2*/
358     HB_SCRIPT_OLD_TURKIC = HB_TAG('O', 'r', 'k', 'h'),
359     /*5.2*/
360     HB_SCRIPT_SAMARITAN = HB_TAG('S', 'a', 'm', 'r'),
361     /*5.2*/
362     HB_SCRIPT_TAI_THAM = HB_TAG('L', 'a', 'n', 'a'),
363     /*5.2*/
364     HB_SCRIPT_TAI_VIET = HB_TAG('T', 'a', 'v', 't'),
365 
366     /*6.0*/
367     HB_SCRIPT_BATAK = HB_TAG('B', 'a', 't', 'k'),
368     /*6.0*/
369     HB_SCRIPT_BRAHMI = HB_TAG('B', 'r', 'a', 'h'),
370     /*6.0*/
371     HB_SCRIPT_MANDAIC = HB_TAG('M', 'a', 'n', 'd'),
372 
373     /*6.1*/
374     HB_SCRIPT_CHAKMA = HB_TAG('C', 'a', 'k', 'm'),
375     /*6.1*/
376     HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG('M', 'e', 'r', 'c'),
377     /*6.1*/
378     HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG('M', 'e', 'r', 'o'),
379     /*6.1*/
380     HB_SCRIPT_MIAO = HB_TAG('P', 'l', 'r', 'd'),
381     /*6.1*/
382     HB_SCRIPT_SHARADA = HB_TAG('S', 'h', 'r', 'd'),
383     /*6.1*/
384     HB_SCRIPT_SORA_SOMPENG = HB_TAG('S', 'o', 'r', 'a'),
385     /*6.1*/
386     HB_SCRIPT_TAKRI = HB_TAG('T', 'a', 'k', 'r'),
387 
388     /*
389      * Since: 0.9.30
390      */
391     /*7.0*/
392     HB_SCRIPT_BASSA_VAH = HB_TAG('B', 'a', 's', 's'),
393     /*7.0*/
394     HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG('A', 'g', 'h', 'b'),
395     /*7.0*/
396     HB_SCRIPT_DUPLOYAN = HB_TAG('D', 'u', 'p', 'l'),
397     /*7.0*/
398     HB_SCRIPT_ELBASAN = HB_TAG('E', 'l', 'b', 'a'),
399     /*7.0*/
400     HB_SCRIPT_GRANTHA = HB_TAG('G', 'r', 'a', 'n'),
401     /*7.0*/
402     HB_SCRIPT_KHOJKI = HB_TAG('K', 'h', 'o', 'j'),
403     /*7.0*/
404     HB_SCRIPT_KHUDAWADI = HB_TAG('S', 'i', 'n', 'd'),
405     /*7.0*/
406     HB_SCRIPT_LINEAR_A = HB_TAG('L', 'i', 'n', 'a'),
407     /*7.0*/
408     HB_SCRIPT_MAHAJANI = HB_TAG('M', 'a', 'h', 'j'),
409     /*7.0*/
410     HB_SCRIPT_MANICHAEAN = HB_TAG('M', 'a', 'n', 'i'),
411     /*7.0*/
412     HB_SCRIPT_MENDE_KIKAKUI = HB_TAG('M', 'e', 'n', 'd'),
413     /*7.0*/
414     HB_SCRIPT_MODI = HB_TAG('M', 'o', 'd', 'i'),
415     /*7.0*/
416     HB_SCRIPT_MRO = HB_TAG('M', 'r', 'o', 'o'),
417     /*7.0*/
418     HB_SCRIPT_NABATAEAN = HB_TAG('N', 'b', 'a', 't'),
419     /*7.0*/
420     HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG('N', 'a', 'r', 'b'),
421     /*7.0*/
422     HB_SCRIPT_OLD_PERMIC = HB_TAG('P', 'e', 'r', 'm'),
423     /*7.0*/
424     HB_SCRIPT_PAHAWH_HMONG = HB_TAG('H', 'm', 'n', 'g'),
425     /*7.0*/
426     HB_SCRIPT_PALMYRENE = HB_TAG('P', 'a', 'l', 'm'),
427     /*7.0*/
428     HB_SCRIPT_PAU_CIN_HAU = HB_TAG('P', 'a', 'u', 'c'),
429     /*7.0*/
430     HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG('P', 'h', 'l', 'p'),
431     /*7.0*/
432     HB_SCRIPT_SIDDHAM = HB_TAG('S', 'i', 'd', 'd'),
433     /*7.0*/
434     HB_SCRIPT_TIRHUTA = HB_TAG('T', 'i', 'r', 'h'),
435     /*7.0*/
436     HB_SCRIPT_WARANG_CITI = HB_TAG('W', 'a', 'r', 'a'),
437 
438     /*8.0*/
439     HB_SCRIPT_AHOM = HB_TAG('A', 'h', 'o', 'm'),
440     /*8.0*/
441     HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG('H', 'l', 'u', 'w'),
442     /*8.0*/
443     HB_SCRIPT_HATRAN = HB_TAG('H', 'a', 't', 'r'),
444     /*8.0*/
445     HB_SCRIPT_MULTANI = HB_TAG('M', 'u', 'l', 't'),
446     /*8.0*/
447     HB_SCRIPT_OLD_HUNGARIAN = HB_TAG('H', 'u', 'n', 'g'),
448     /*8.0*/
449     HB_SCRIPT_SIGNWRITING = HB_TAG('S', 'g', 'n', 'w'),
450 
451     /*
452      * Since 1.3.0
453      */
454     /*9.0*/
455     HB_SCRIPT_ADLAM = HB_TAG('A', 'd', 'l', 'm'),
456     /*9.0*/
457     HB_SCRIPT_BHAIKSUKI = HB_TAG('B', 'h', 'k', 's'),
458     /*9.0*/
459     HB_SCRIPT_MARCHEN = HB_TAG('M', 'a', 'r', 'c'),
460     /*9.0*/
461     HB_SCRIPT_OSAGE = HB_TAG('O', 's', 'g', 'e'),
462     /*9.0*/
463     HB_SCRIPT_TANGUT = HB_TAG('T', 'a', 'n', 'g'),
464     /*9.0*/
465     HB_SCRIPT_NEWA = HB_TAG('N', 'e', 'w', 'a'),
466 
467     /*
468      * Since 1.6.0
469      */
470     /*10.0*/
471     HB_SCRIPT_MASARAM_GONDI = HB_TAG('G', 'o', 'n', 'm'),
472     /*10.0*/
473     HB_SCRIPT_NUSHU = HB_TAG('N', 's', 'h', 'u'),
474     /*10.0*/
475     HB_SCRIPT_SOYOMBO = HB_TAG('S', 'o', 'y', 'o'),
476     /*10.0*/
477     HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG('Z', 'a', 'n', 'b'),
478 
479     /*
480      * Since 1.8.0
481      */
482     /*11.0*/
483     HB_SCRIPT_DOGRA = HB_TAG('D', 'o', 'g', 'r'),
484     /*11.0*/
485     HB_SCRIPT_GUNJALA_GONDI = HB_TAG('G', 'o', 'n', 'g'),
486     /*11.0*/
487     HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG('R', 'o', 'h', 'g'),
488     /*11.0*/
489     HB_SCRIPT_MAKASAR = HB_TAG('M', 'a', 'k', 'a'),
490     /*11.0*/
491     HB_SCRIPT_MEDEFAIDRIN = HB_TAG('M', 'e', 'd', 'f'),
492     /*11.0*/
493     HB_SCRIPT_OLD_SOGDIAN = HB_TAG('S', 'o', 'g', 'o'),
494     /*11.0*/
495     HB_SCRIPT_SOGDIAN = HB_TAG('S', 'o', 'g', 'd'),
496 
497     /*
498      * Since 2.4.0
499      */
500     /*12.0*/
501     HB_SCRIPT_ELYMAIC = HB_TAG('E', 'l', 'y', 'm'),
502     /*12.0*/
503     HB_SCRIPT_NANDINAGARI = HB_TAG('N', 'a', 'n', 'd'),
504     /*12.0*/
505     HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG('H', 'm', 'n', 'p'),
506     /*12.0*/
507     HB_SCRIPT_WANCHO = HB_TAG('W', 'c', 'h', 'o'),
508 
509     /* No script set. */
510     HB_SCRIPT_INVALID = HB_TAG_NONE,
511 
512     /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
513      * without risking undefined behavior.  We have two, for historical reasons.
514      * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed
515      * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well.
516      *
517      * See this thread for technicalities:
518      *
519      *   https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
520      */
521     _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/
522     _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/
523 }
524 alias hb_script_t = hb_tag_t;
525 
526 /* Script functions */
527 
528 version(BindHB_Static)
529     hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag);
530 else
531 {
532     private alias fp_hb_script_from_iso15924_tag = hb_script_t function (hb_tag_t tag);
533     __gshared fp_hb_script_from_iso15924_tag hb_script_from_iso15924_tag;
534 }
535 
536 version(BindHB_Static)
537     hb_script_t hb_script_from_string (const(char)* str, int len);
538 else
539 {
540     private alias fp_hb_script_from_string = hb_script_t function (const(char)* str, int len);
541     __gshared fp_hb_script_from_string hb_script_from_string;
542 }
543 
544 version(BindHB_Static)
545     hb_tag_t hb_script_to_iso15924_tag (hb_script_t script);
546 else
547 {
548     private alias fp_hb_script_to_iso15924_tag = hb_tag_t function (hb_script_t script);
549     __gshared fp_hb_script_to_iso15924_tag hb_script_to_iso15924_tag;
550 }
551 
552 version(BindHB_Static)
553     hb_direction_t hb_script_get_horizontal_direction (hb_script_t script);
554 else
555 {
556     private alias fp_hb_script_get_horizontal_direction = hb_direction_t function (hb_script_t script);
557     __gshared fp_hb_script_get_horizontal_direction hb_script_get_horizontal_direction;
558 }
559 
560 /* User data */
561 
562 struct hb_user_data_key_t
563 {
564     /*< private >*/
565     char unused;
566 }
567 
568 alias hb_destroy_func_t = void function (void* user_data);
569 
570 /* Font features and variations. */
571 
572 /**
573  * HB_FEATURE_GLOBAL_START
574  *
575  * Since: 2.0.0
576  */
577 enum HB_FEATURE_GLOBAL_START = 0;
578 /**
579  * HB_FEATURE_GLOBAL_END
580  *
581  * Since: 2.0.0
582  */
583 enum HB_FEATURE_GLOBAL_END = cast(uint) -1;
584 
585 /**
586  * hb_feature_t:
587  * @tag: a feature tag
588  * @value: 0 disables the feature, non-zero (usually 1) enables the feature.
589  * For features implemented as lookup type 3 (like 'salt') the @value is a one
590  * based index into the alternates.
591  * @start: the cluster to start applying this feature setting (inclusive).
592  * @end: the cluster to end applying this feature setting (exclusive).
593  *
594  * The #hb_feature_t is the structure that holds information about requested
595  * feature application. The feature will be applied with the given value to all
596  * glyphs which are in clusters between @start (inclusive) and @end (exclusive).
597  * Setting start to @HB_FEATURE_GLOBAL_START and end to @HB_FEATURE_GLOBAL_END
598  * specifies that the feature always applies to the entire buffer.
599  */
600 struct hb_feature_t
601 {
602     hb_tag_t tag;
603     uint value;
604     uint start;
605     uint end;
606 }
607 
608 version(BindHB_Static)
609     hb_bool_t hb_feature_from_string (
610         const(char)* str,
611         int len,
612         hb_feature_t* feature);
613 else
614 {
615     private alias fp_hb_feature_from_string = hb_bool_t function (
616         const(char)* str,
617         int len,
618         hb_feature_t* feature);
619     __gshared fp_hb_feature_from_string hb_feature_from_string;
620 }
621 
622 version(BindHB_Static)
623     void hb_feature_to_string (hb_feature_t* feature, char* buf, uint size);
624 else
625 {
626     private alias fp_hb_feature_to_string = void function (hb_feature_t* feature, char* buf, uint size);
627     __gshared fp_hb_feature_to_string hb_feature_to_string;
628 }
629 
630 /**
631  * hb_variation_t:
632  *
633  * Since: 1.4.2
634  */
635 struct hb_variation_t
636 {
637     hb_tag_t tag;
638     float value;
639 }
640 
641 version(BindHB_Static)
642     hb_bool_t hb_variation_from_string (
643         const(char)* str,
644         int len,
645         hb_variation_t* variation);
646 else
647 {
648     private alias fp_hb_variation_from_string = hb_bool_t function (
649         const(char)* str,
650         int len,
651         hb_variation_t* variation);
652     __gshared fp_hb_variation_from_string hb_variation_from_string;
653 }
654 
655 version(BindHB_Static)
656     void hb_variation_to_string (hb_variation_t* variation, char* buf, uint size);
657 else
658 {
659     private alias fp_hb_variation_to_string = void function (hb_variation_t* variation, char* buf, uint size);
660     __gshared fp_hb_variation_to_string hb_variation_to_string;
661 }
662 
663 /**
664  * hb_color_t:
665  *
666  * Data type for holding color values.
667  *
668  * Since: 2.1.0
669  */
670 alias hb_color_t = uint;
671 
672 extern (D) hb_color_t HB_COLOR(ubyte b, ubyte g, ubyte r, ubyte a)
673 {
674     return cast(hb_color_t) HB_TAG(b, g, r, a);
675 }
676 
677 extern (D) ubyte hb_color_get_alpha(hb_color_t color)
678 {
679     return color & 0xFF;
680 }
681 
682 extern (D) ubyte hb_color_get_red(hb_color_t color)
683 {
684     return (color >> 8) & 0xFF;
685 }
686 
687 extern (D) ubyte hb_color_get_green(hb_color_t color)
688 {
689     return (color >> 16) & 0xFF;
690 }
691 
692 extern (D) ubyte hb_color_get_blue(hb_color_t color)
693 {
694     return (color >> 24) & 0xFF;
695 }