|
|
|
@ -86,7 +86,46 @@ hb_segment_properties_hash (const hb_segment_properties_t *p) |
|
|
|
|
(intptr_t) (p->language); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* hb_segment_properties_overlay: |
|
|
|
|
* @p: #hb_segment_properties_t to fill in. |
|
|
|
|
* @src: #hb_segment_properties_t to fill in from. |
|
|
|
|
* |
|
|
|
|
* Fills in missing fields of @p from @src in a considered manner. |
|
|
|
|
* |
|
|
|
|
* First, if @p does not have direction set, direction is copied from @src. |
|
|
|
|
* |
|
|
|
|
* Next, if @p and @src have the same direction (which can be unset), if @p |
|
|
|
|
* does not have script set, script is copied from @src. |
|
|
|
|
* |
|
|
|
|
* Finally, if @p and @src have the same direction and script (which either |
|
|
|
|
* can be unset), if @p does not have language set, language is copied from |
|
|
|
|
* @src. |
|
|
|
|
* |
|
|
|
|
* Since: REPLACEME |
|
|
|
|
**/ |
|
|
|
|
void |
|
|
|
|
hb_segment_properties_overlay (hb_segment_properties_t *p, |
|
|
|
|
const hb_segment_properties_t *src) |
|
|
|
|
{ |
|
|
|
|
if (unlikely (!p || !src)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (!p->direction) |
|
|
|
|
p->direction = src->direction; |
|
|
|
|
|
|
|
|
|
if (p->direction != src->direction) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (!p->script) |
|
|
|
|
p->script = src->script; |
|
|
|
|
|
|
|
|
|
if (p->script != src->script) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (!p->language) |
|
|
|
|
p->language = src->language; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Here is how the buffer works internally:
|
|
|
|
|
* |
|
|
|
@ -216,12 +255,25 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size) |
|
|
|
|
|
|
|
|
|
/* HarfBuzz-Internal API */ |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
hb_buffer_t::similar (const hb_buffer_t &src) |
|
|
|
|
{ |
|
|
|
|
hb_unicode_funcs_destroy (unicode); |
|
|
|
|
unicode = hb_unicode_funcs_reference (src.unicode); |
|
|
|
|
flags = src.flags; |
|
|
|
|
cluster_level = src.cluster_level; |
|
|
|
|
replacement = src.invisible; |
|
|
|
|
invisible = src.invisible; |
|
|
|
|
not_found = src.not_found; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
hb_buffer_t::reset () |
|
|
|
|
{ |
|
|
|
|
hb_unicode_funcs_destroy (unicode); |
|
|
|
|
unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ()); |
|
|
|
|
flags = HB_BUFFER_FLAG_DEFAULT; |
|
|
|
|
cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT; |
|
|
|
|
replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; |
|
|
|
|
invisible = 0; |
|
|
|
|
not_found = 0; |
|
|
|
@ -232,11 +284,10 @@ hb_buffer_t::reset () |
|
|
|
|
void |
|
|
|
|
hb_buffer_t::clear () |
|
|
|
|
{ |
|
|
|
|
content_type = HB_BUFFER_CONTENT_TYPE_INVALID; |
|
|
|
|
hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; |
|
|
|
|
props = default_props; |
|
|
|
|
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; |
|
|
|
|
|
|
|
|
|
content_type = HB_BUFFER_CONTENT_TYPE_INVALID; |
|
|
|
|
successful = true; |
|
|
|
|
have_output = false; |
|
|
|
|
have_positions = false; |
|
|
|
@ -244,16 +295,44 @@ hb_buffer_t::clear () |
|
|
|
|
idx = 0; |
|
|
|
|
len = 0; |
|
|
|
|
out_len = 0; |
|
|
|
|
out_info = info; |
|
|
|
|
|
|
|
|
|
serial = 0; |
|
|
|
|
out_info = info; |
|
|
|
|
|
|
|
|
|
memset (context, 0, sizeof context); |
|
|
|
|
memset (context_len, 0, sizeof context_len); |
|
|
|
|
|
|
|
|
|
deallocate_var_all (); |
|
|
|
|
serial = 0; |
|
|
|
|
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
hb_buffer_t::enter () |
|
|
|
|
{ |
|
|
|
|
deallocate_var_all (); |
|
|
|
|
serial = 0; |
|
|
|
|
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; |
|
|
|
|
if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR))) |
|
|
|
|
{ |
|
|
|
|
max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR, |
|
|
|
|
(unsigned) HB_BUFFER_MAX_LEN_MIN); |
|
|
|
|
} |
|
|
|
|
if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR))) |
|
|
|
|
{ |
|
|
|
|
max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR, |
|
|
|
|
(unsigned) HB_BUFFER_MAX_OPS_MIN); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void |
|
|
|
|
hb_buffer_t::leave () |
|
|
|
|
{ |
|
|
|
|
max_len = HB_BUFFER_MAX_LEN_DEFAULT; |
|
|
|
|
max_ops = HB_BUFFER_MAX_OPS_DEFAULT; |
|
|
|
|
deallocate_var_all (); |
|
|
|
|
serial = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
hb_buffer_t::add (hb_codepoint_t codepoint, |
|
|
|
|
unsigned int cluster) |
|
|
|
@ -565,12 +644,11 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = |
|
|
|
|
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, |
|
|
|
|
0, /* invisible */ |
|
|
|
|
0, /* not_found */ |
|
|
|
|
HB_BUFFER_SCRATCH_FLAG_DEFAULT, |
|
|
|
|
HB_BUFFER_MAX_LEN_DEFAULT, |
|
|
|
|
HB_BUFFER_MAX_OPS_DEFAULT, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HB_BUFFER_CONTENT_TYPE_INVALID, |
|
|
|
|
HB_SEGMENT_PROPERTIES_DEFAULT, |
|
|
|
|
|
|
|
|
|
false, /* successful */ |
|
|
|
|
false, /* have_output */ |
|
|
|
|
true /* have_positions */ |
|
|
|
@ -609,6 +687,47 @@ hb_buffer_create () |
|
|
|
|
return buffer; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* hb_buffer_create_similar: |
|
|
|
|
* @src: An #hb_buffer_t |
|
|
|
|
* |
|
|
|
|
* Resets the buffer to its initial status, as if it was just newly created |
|
|
|
|
* with hb_buffer_create(). |
|
|
|
|
* |
|
|
|
|
* Return value: (transfer full): |
|
|
|
|
* A newly allocated #hb_buffer_t, similar to hb_buffer_create(). The only |
|
|
|
|
* difference is that the buffer is configured similarly to @src. |
|
|
|
|
* |
|
|
|
|
* Since: REPLACEME |
|
|
|
|
**/ |
|
|
|
|
hb_buffer_t * |
|
|
|
|
hb_buffer_create_similar (const hb_buffer_t *src) |
|
|
|
|
{ |
|
|
|
|
hb_buffer_t *buffer = hb_buffer_create (); |
|
|
|
|
|
|
|
|
|
buffer->similar (*src); |
|
|
|
|
|
|
|
|
|
return buffer; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* hb_buffer_reset: |
|
|
|
|
* @buffer: An #hb_buffer_t |
|
|
|
|
* |
|
|
|
|
* Resets the buffer to its initial status, as if it was just newly created |
|
|
|
|
* with hb_buffer_create(). |
|
|
|
|
* |
|
|
|
|
* Since: 0.9.2 |
|
|
|
|
**/ |
|
|
|
|
void |
|
|
|
|
hb_buffer_reset (hb_buffer_t *buffer) |
|
|
|
|
{ |
|
|
|
|
if (unlikely (hb_object_is_immutable (buffer))) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
buffer->reset (); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* hb_buffer_get_empty: |
|
|
|
|
* |
|
|
|
@ -1156,24 +1275,6 @@ hb_buffer_get_not_found_glyph (hb_buffer_t *buffer) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* hb_buffer_reset: |
|
|
|
|
* @buffer: An #hb_buffer_t |
|
|
|
|
* |
|
|
|
|
* Resets the buffer to its initial status, as if it was just newly created |
|
|
|
|
* with hb_buffer_create(). |
|
|
|
|
* |
|
|
|
|
* Since: 0.9.2 |
|
|
|
|
**/ |
|
|
|
|
void |
|
|
|
|
hb_buffer_reset (hb_buffer_t *buffer) |
|
|
|
|
{ |
|
|
|
|
if (unlikely (hb_object_is_immutable (buffer))) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
buffer->reset (); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* hb_buffer_clear_contents: |
|
|
|
|
* @buffer: An #hb_buffer_t |
|
|
|
@ -1749,6 +1850,8 @@ hb_buffer_append (hb_buffer_t *buffer, |
|
|
|
|
if (!buffer->have_positions && source->have_positions) |
|
|
|
|
buffer->clear_positions (); |
|
|
|
|
|
|
|
|
|
hb_segment_properties_overlay (&buffer->props, &source->props); |
|
|
|
|
|
|
|
|
|
memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); |
|
|
|
|
if (buffer->have_positions) |
|
|
|
|
memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); |
|
|
|
|