1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
8 #include "hb-private.h"
10 //------------------------------------------------------------------------------
12 #define HB_UTF8_COMPUTE(Char, Mask, Len) \
13 if (Char < 128) { Len = 1; Mask = 0x7f; } \
14 else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
15 else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \
16 else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
20 hb_utf_next_utf8(void *text
,
22 hb_codepoint_t
*unicode
)
24 uint8_t *text_utf8
= text
;
25 uint8_t *end_utf8
= end
;
26 hb_codepoint_t c
= *text_utf8
, mask
;
29 //TODO check for overlong sequences?
31 HB_UTF8_COMPUTE (c
, mask
, len
);
32 if (!len
|| (unsigned) (end_utf8
- text_utf8
) < len
) {
36 hb_codepoint_t result
;
39 for (i
= 1; i
< len
; i
++) {
40 if ((text_utf8
[i
] & 0xc0) != 0x80) {
45 result
|= (text_utf8
[i
] & 0x3f);
48 return text_utf8
+ len
;
53 hb_utf_prev_utf8(void *text
,
55 hb_codepoint_t
*unicode
)
57 uint8_t *text_utf8
= text
;
58 uint8_t *start_utf8
= start
;
60 uint8_t *end
= text_utf8
--;
61 while (start_utf8
< text_utf8
&& (*text_utf8
& 0xc0) == 0x80
62 && end
- text_utf8
< 4)
65 hb_codepoint_t c
= *text_utf8
, mask
;
68 //TODO check for overlong sequences?
70 HB_UTF8_COMPUTE(c
, mask
, len
);
71 if (!len
|| (unsigned)(end
- text_utf8
) != len
) {
75 hb_codepoint_t result
;
78 for (i
= 1; i
< len
; i
++) {
80 result
|= (text_utf8
[i
] & 0x3f);
88 hb_utf_ptr_offset_utf8(void *text
, unsigned offset
)
90 uint8_t *text_utf8
= text
;
91 return text_utf8
+ offset
;
95 hb_utf_strlen_utf8(void *text
)
101 hb_utf_diff_utf8(void *a
, void *b
)
105 return a_utf8
- b_utf8
;
108 //------------------------------------------------------------------------------
111 hb_utf_next_utf16(void *text
,
113 hb_codepoint_t
*unicode
)
115 uint16_t *text_utf16
= text
;
116 uint16_t *end_utf16
= end
;
118 hb_codepoint_t c
= *text_utf16
++;
120 if (hb_codepoint_in_range(c
, 0xd800, 0xdbff)) {
123 if (text_utf16
< end_utf16
&& ((l
= *text_utf16
),
124 hb_codepoint_in_range(l
, 0xdc00, 0xdfff))) {
126 *unicode
= (c
<< 10) + l
- ((0xd800 << 10) - 0x10000 + 0xdc00);
136 hb_utf_prev_utf16(void *text
,
138 hb_codepoint_t
*unicode
)
140 uint16_t *text_utf16
= text
;
141 uint16_t *start_utf16
= start
;
142 hb_codepoint_t c
= *--text_utf16
;
144 if (hb_codepoint_in_range(c
, 0xdc00, 0xdfff)) {
147 if (start_utf16
< text_utf16
148 && ((h
= *(text_utf16
- 1)), hb_codepoint_in_range(h
, 0xd800, 0xdbff))) {
150 *unicode
= (h
<< 10) + c
- ((0xd800 << 10) - 0x10000 + 0xdc00);
160 hb_utf_ptr_offset_utf16(void *text
, unsigned offset
)
162 uint16_t *text_utf16
= text
;
163 return text_utf16
+ offset
;
167 hb_utf_strlen_utf16(void *text
)
169 uint16_t *text_utf16
= text
;
172 while (*text_utf16
++) l
++;
177 hb_utf_diff_utf16(void *a
, void *b
)
179 uint16_t *a_utf16
= a
;
180 uint16_t *b_utf16
= b
;
181 return a_utf16
- b_utf16
;
183 //------------------------------------------------------------------------------
186 hb_utf_next_utf32(void *text
,
188 hb_codepoint_t
*unicode
)
190 uint32_t *text_utf32
= text
;
191 *unicode
= *text_utf32
++;
196 hb_utf_prev_utf32(void *text
,
197 void *start HB_UNUSED
,
198 hb_codepoint_t
*unicode
)
200 uint32_t *text_utf32
= text
;
201 *unicode
= *--text_utf32
;
206 hb_utf_ptr_offset_utf32(void *text
, unsigned offset
)
208 uint32_t *text_utf32
= text
;
209 return text_utf32
+ offset
;
213 hb_utf_strlen_utf32(void *text
)
215 uint32_t *text_utf32
= text
;
218 while (*text_utf32
++) l
++;
223 hb_utf_diff_utf32(void *a
, void *b
)
225 uint32_t *a_utf32
= a
;
226 uint32_t *b_utf32
= b
;
227 return a_utf32
- b_utf32
;