~ubuntu-branches/ubuntu/maverick/pango1.0/maverick-proposed

« back to all changes in this revision

Viewing changes to pango/opentype/hb-buffer.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2009-08-11 17:30:40 UTC
  • mfrom: (1.5.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090811173040-zozfegyjkb39sep2
Tags: 1.25.2-0ubuntu1
New upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
 * in-place.
47
47
 *
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
53
 
 * unconditionally.
 
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.
54
53
 */
55
54
 
56
55
/* XXX err handling */
63
62
  hb_buffer_ensure (buffer, size);
64
63
  if (buffer->out_string == buffer->in_string)
65
64
  {
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]));
68
67
 
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]));
71
70
  }
72
71
}
105
104
  HB_OBJECT_DO_DESTROY (buffer);
106
105
 
107
106
  free (buffer->in_string);
108
 
  free (buffer->alt_string);
109
107
  free (buffer->positions);
110
108
 
111
109
  free (buffer);
138
136
    if (buffer->out_string != buffer->in_string)
139
137
    {
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;
143
140
    }
144
141
    else
145
142
    {
146
143
      buffer->in_string = realloc (buffer->in_string, new_allocated * sizeof (buffer->in_string[0]));
147
144
      buffer->out_string = buffer->in_string;
148
 
 
149
 
      if (buffer->alt_string)
150
 
      {
151
 
        free (buffer->alt_string);
152
 
        buffer->alt_string = NULL;
153
 
      }
154
145
    }
155
146
 
156
147
    buffer->allocated = new_allocated;
189
180
 
190
181
/* HarfBuzz-Internal API */
191
182
 
192
 
HB_INTERNAL void
 
183
void
193
184
_hb_buffer_clear_output (hb_buffer_t *buffer)
194
185
{
195
186
  buffer->out_length = 0;
211
202
  memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length);
212
203
}
213
204
 
214
 
HB_INTERNAL void
 
205
void
215
206
_hb_buffer_swap (hb_buffer_t *buffer)
216
207
{
217
208
  unsigned int tmp;
222
213
    tmp_string = buffer->in_string;
223
214
    buffer->in_string = buffer->out_string;
224
215
    buffer->out_string = tmp_string;
225
 
    buffer->alt_string = buffer->out_string;
 
216
    buffer->positions = (hb_internal_glyph_position_t *) buffer->out_string;
226
217
  }
227
218
 
228
219
  tmp = buffer->in_length;
253
244
 
254
245
   The cluster value for the glyph at position buffer->in_pos is used
255
246
   for all replacement glyphs */
256
 
HB_INTERNAL void
 
247
void
257
248
_hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
258
249
                              unsigned int num_in,
259
250
                              unsigned int num_out,
295
286
}
296
287
 
297
288
 
298
 
HB_INTERNAL void
 
289
void
299
290
_hb_buffer_add_output_glyph (hb_buffer_t *buffer,
300
291
                             hb_codepoint_t glyph_index,
301
292
                             unsigned short component,
324
315
  buffer->out_length = buffer->out_pos;
325
316
}
326
317
 
327
 
HB_INTERNAL void
 
318
void
328
319
_hb_buffer_next_glyph (hb_buffer_t *buffer)
329
320
{
330
321
  if (buffer->out_string != buffer->in_string)
340
331
  buffer->out_length = buffer->out_pos;
341
332
}
342
333
 
343
 
HB_INTERNAL void
 
334
void
344
335
_hb_buffer_replace_glyph (hb_buffer_t *buffer,
345
336
                          hb_codepoint_t glyph_index)
346
337
{
347
338
  _hb_buffer_add_output_glyph (buffer, glyph_index, 0xFFFF, 0xFFFF);
348
339
}
349
340
 
350
 
HB_INTERNAL unsigned short
 
341
unsigned short
351
342
_hb_buffer_allocate_lig_id (hb_buffer_t *buffer)
352
343
{
353
344
  return ++buffer->max_lig_id;
376
367
 
377
368
  return (hb_glyph_position_t *) buffer->positions;
378
369
}
 
370
 
 
371
 
 
372
void
 
373
hb_buffer_reverse (hb_buffer_t *buffer)
 
374
{
 
375
  unsigned int i, j;
 
376
 
 
377
  for (i = 0, j = buffer->in_length - 1; i < buffer->in_length / 2; i++, j--) {
 
378
    hb_internal_glyph_info_t t;
 
379
 
 
380
    t = buffer->in_string[i];
 
381
    buffer->in_string[i] = buffer->in_string[j];
 
382
    buffer->in_string[j] = t;
 
383
  }
 
384
 
 
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;
 
388
 
 
389
      t = buffer->positions[i];
 
390
      buffer->positions[i] = buffer->positions[j];
 
391
      buffer->positions[j] = t;
 
392
    }
 
393
  }
 
394
}
 
395
 
 
396
 
 
397
#define ADD_UTF(T) \
 
398
        HB_STMT_START { \
 
399
          const T *next = (const T *) text + item_offset; \
 
400
          const T *end = next + item_length; \
 
401
          while (next < end) { \
 
402
            hb_codepoint_t u; \
 
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); \
 
406
          } \
 
407
        } HB_STMT_END
 
408
 
 
409
 
 
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; } \
 
415
  else Len = 0;
 
416
 
 
417
static inline const uint8_t *
 
418
hb_utf8_next (const uint8_t *text,
 
419
              const uint8_t *end,
 
420
              hb_codepoint_t *unicode)
 
421
{
 
422
  uint8_t c = *text;
 
423
  unsigned int mask, len;
 
424
 
 
425
  UTF8_COMPUTE (c, mask, len);
 
426
  if (HB_UNLIKELY (!len || end - text < len)) {
 
427
    *unicode = -1;
 
428
    return text + 1;
 
429
  } else {
 
430
    hb_codepoint_t result;
 
431
    unsigned int i;
 
432
    result = c & mask;
 
433
    for (i = 1; i < len; i++)
 
434
      {
 
435
        if (HB_UNLIKELY ((text[i] & 0xc0) != 0x80))
 
436
          {
 
437
            *unicode = -1;
 
438
            return text + 1;
 
439
          }
 
440
        result <<= 6;
 
441
        result |= (text[i] & 0x3f);
 
442
      }
 
443
    *unicode = result;
 
444
    return text + len;
 
445
  }
 
446
}
 
447
 
 
448
void
 
449
hb_buffer_add_utf8 (hb_buffer_t  *buffer,
 
450
                    const char   *text,
 
451
                    unsigned int  text_length,
 
452
                    unsigned int  item_offset,
 
453
                    unsigned int  item_length)
 
454
{
 
455
#define UTF_NEXT(S, E, U)       hb_utf8_next (S, E, &(U))
 
456
  ADD_UTF (uint8_t);
 
457
#undef UTF_NEXT
 
458
}
 
459
 
 
460
static inline const uint16_t *
 
461
hb_utf16_next (const uint16_t *text,
 
462
               const uint16_t *end,
 
463
               hb_codepoint_t *unicode)
 
464
{
 
465
  uint16_t c = *text++;
 
466
 
 
467
  if (HB_UNLIKELY (c >= 0xd800 && c < 0xdc00)) {
 
468
    /* high surrogate */
 
469
    uint16_t l;
 
470
    if (text < end && ((l = *text), HB_UNLIKELY (l >= 0xdc00 && l < 0xe000))) {
 
471
      /* low surrogate */
 
472
      *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000);
 
473
       text++;
 
474
    } else
 
475
      *unicode = -1;
 
476
  } else
 
477
    *unicode = c;
 
478
 
 
479
  return text;
 
480
}
 
481
 
 
482
void
 
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)
 
488
{
 
489
#define UTF_NEXT(S, E, U)       hb_utf16_next (S, E, &(U))
 
490
  ADD_UTF (uint16_t);
 
491
#undef UTF_NEXT
 
492
}
 
493
 
 
494
void
 
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)
 
500
{
 
501
#define UTF_NEXT(S, E, U)       ((U) = *(S), (S)+1)
 
502
  ADD_UTF (uint32_t);
 
503
#undef UTF_NEXT
 
504
}