48
48
* As soon as out_string gets longer than in_string, out_string is moved over
49
* to an alternate buffer (alt_string), and its current contents (out_length
50
* entries) are copied to the alt buffer. This should all remain transparent
51
* to the user. swap() then switches in_string and alt_string. alt_string is
52
* not allocated until its needed, but after that it's grown with in_string
49
* to an alternate buffer (which we reuse the positions buffer for!), and its
50
* current contents (out_length entries) are copied to the alt buffer.
51
* This should all remain transparent to the user. swap() then switches
52
* in_string and out_string.
56
55
/* XXX err handling */
63
62
hb_buffer_ensure (buffer, size);
64
63
if (buffer->out_string == buffer->in_string)
66
if (!buffer->alt_string)
67
buffer->alt_string = calloc (buffer->allocated, sizeof (buffer->alt_string[0]));
65
if (!buffer->positions)
66
buffer->positions = calloc (buffer->allocated, sizeof (buffer->positions[0]));
69
buffer->out_string = buffer->alt_string;
68
buffer->out_string = (hb_internal_glyph_info_t *) buffer->positions;
70
69
memcpy (buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]));
138
136
if (buffer->out_string != buffer->in_string)
140
138
buffer->in_string = realloc (buffer->in_string, new_allocated * sizeof (buffer->in_string[0]));
141
buffer->alt_string = realloc (buffer->alt_string, new_allocated * sizeof (buffer->alt_string[0]));
142
buffer->out_string = buffer->alt_string;
139
buffer->out_string = (hb_internal_glyph_info_t *) buffer->positions;
146
143
buffer->in_string = realloc (buffer->in_string, new_allocated * sizeof (buffer->in_string[0]));
147
144
buffer->out_string = buffer->in_string;
149
if (buffer->alt_string)
151
free (buffer->alt_string);
152
buffer->alt_string = NULL;
156
147
buffer->allocated = new_allocated;
377
368
return (hb_glyph_position_t *) buffer->positions;
373
hb_buffer_reverse (hb_buffer_t *buffer)
377
for (i = 0, j = buffer->in_length - 1; i < buffer->in_length / 2; i++, j--) {
378
hb_internal_glyph_info_t t;
380
t = buffer->in_string[i];
381
buffer->in_string[i] = buffer->in_string[j];
382
buffer->in_string[j] = t;
385
if (buffer->positions) {
386
for (i = 0, j = buffer->in_length - 1; i < buffer->in_length / 2; i++, j--) {
387
hb_internal_glyph_position_t t;
389
t = buffer->positions[i];
390
buffer->positions[i] = buffer->positions[j];
391
buffer->positions[j] = t;
399
const T *next = (const T *) text + item_offset; \
400
const T *end = next + item_length; \
401
while (next < end) { \
403
const T *old_next = next; \
404
next = UTF_NEXT (next, end, u); \
405
hb_buffer_add_glyph (buffer, u, 0, old_next - (const T *) text); \
410
#define UTF8_COMPUTE(Char, Mask, Len) \
411
if (Char < 128) { Len = 1; Mask = 0x7f; } \
412
else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
413
else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \
414
else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
417
static inline const uint8_t *
418
hb_utf8_next (const uint8_t *text,
420
hb_codepoint_t *unicode)
423
unsigned int mask, len;
425
UTF8_COMPUTE (c, mask, len);
426
if (HB_UNLIKELY (!len || end - text < len)) {
430
hb_codepoint_t result;
433
for (i = 1; i < len; i++)
435
if (HB_UNLIKELY ((text[i] & 0xc0) != 0x80))
441
result |= (text[i] & 0x3f);
449
hb_buffer_add_utf8 (hb_buffer_t *buffer,
451
unsigned int text_length,
452
unsigned int item_offset,
453
unsigned int item_length)
455
#define UTF_NEXT(S, E, U) hb_utf8_next (S, E, &(U))
460
static inline const uint16_t *
461
hb_utf16_next (const uint16_t *text,
463
hb_codepoint_t *unicode)
465
uint16_t c = *text++;
467
if (HB_UNLIKELY (c >= 0xd800 && c < 0xdc00)) {
470
if (text < end && ((l = *text), HB_UNLIKELY (l >= 0xdc00 && l < 0xe000))) {
472
*unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000);
483
hb_buffer_add_utf16 (hb_buffer_t *buffer,
484
const uint16_t *text,
485
unsigned int text_length,
486
unsigned int item_offset,
487
unsigned int item_length)
489
#define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U))
495
hb_buffer_add_utf32 (hb_buffer_t *buffer,
496
const uint32_t *text,
497
unsigned int text_length,
498
unsigned int item_offset,
499
unsigned int item_length)
501
#define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1)