summaryrefslogtreecommitdiff
path: root/src/hb-buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/hb-buffer.cc')
-rw-r--r--src/hb-buffer.cc698
1 files changed, 457 insertions, 241 deletions
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index b9fe263..406db9c 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -35,7 +35,28 @@
#define HB_DEBUG_BUFFER (HB_DEBUG+0)
#endif
+/**
+ * SECTION: hb-buffer
+ * @title: Buffers
+ * @short_description: Input and output buffers
+ * @include: hb.h
+ *
+ * Buffers serve dual role in HarfBuzz; they hold the input characters that are
+ * passed hb_shape(), and after shaping they hold the output glyphs.
+ **/
+/**
+ * hb_segment_properties_equal:
+ * @a: first #hb_segment_properties_t to compare.
+ * @b: second #hb_segment_properties_t to compare.
+ *
+ * Checks the equality of two #hb_segment_properties_t's.
+ *
+ * Return value: (transfer full):
+ * %true if all properties of @a equal those of @b, false otherwise.
+ *
+ * Since: 0.9.7
+ **/
hb_bool_t
hb_segment_properties_equal (const hb_segment_properties_t *a,
const hb_segment_properties_t *b)
@@ -48,6 +69,17 @@ hb_segment_properties_equal (const hb_segment_properties_t *a,
}
+/**
+ * hb_segment_properties_hash:
+ * @p: #hb_segment_properties_t to hash.
+ *
+ * Creates a hash representing @p.
+ *
+ * Return value:
+ * A hash of @p.
+ *
+ * Since: 0.9.7
+ **/
unsigned int
hb_segment_properties_hash (const hb_segment_properties_t *p)
{
@@ -85,6 +117,11 @@ hb_buffer_t::enlarge (unsigned int size)
{
if (unlikely (in_error))
return false;
+ if (unlikely (size > max_len))
+ {
+ in_error = true;
+ return false;
+ }
unsigned int new_allocated = allocated;
hb_glyph_position_t *new_pos = NULL;
@@ -192,6 +229,7 @@ hb_buffer_t::clear (void)
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;
in_error = false;
@@ -204,11 +242,11 @@ hb_buffer_t::clear (void)
out_info = info;
serial = 0;
- memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
- memset (allocated_var_owner, 0, sizeof allocated_var_owner);
memset (context, 0, sizeof context);
memset (context_len, 0, sizeof context_len);
+
+ deallocate_var_all ();
}
void
@@ -369,6 +407,8 @@ hb_buffer_t::move_to (unsigned int i)
idx = i;
return true;
}
+ if (unlikely (in_error))
+ return false;
assert (i <= out_len + (len - idx));
@@ -498,14 +538,10 @@ hb_buffer_t::reverse_clusters (void)
}
void
-hb_buffer_t::merge_clusters (unsigned int start,
- unsigned int end)
+hb_buffer_t::merge_clusters_impl (unsigned int start,
+ unsigned int end)
{
-#ifdef HB_NO_MERGE_CLUSTERS
- return;
-#endif
-
- if (unlikely (end - start < 2))
+ if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
return;
unsigned int cluster = info[start].cluster;
@@ -523,7 +559,7 @@ hb_buffer_t::merge_clusters (unsigned int start,
/* If we hit the start of buffer, continue in out-buffer. */
if (idx == start)
- for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
+ for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
out_info[i - 1].cluster = cluster;
for (unsigned int i = start; i < end; i++)
@@ -533,9 +569,8 @@ void
hb_buffer_t::merge_out_clusters (unsigned int start,
unsigned int end)
{
-#ifdef HB_NO_MERGE_CLUSTERS
- return;
-#endif
+ if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+ return;
if (unlikely (end - start < 2))
return;
@@ -555,12 +590,44 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
/* If we hit the end of out-buffer, continue in buffer. */
if (end == out_len)
- for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
+ for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
info[i].cluster = cluster;
for (unsigned int i = start; i < end; i++)
out_info[i].cluster = cluster;
}
+void
+hb_buffer_t::delete_glyph ()
+{
+ unsigned int cluster = info[idx].cluster;
+ if (idx + 1 < len && cluster == info[idx + 1].cluster)
+ {
+ /* Cluster survives; do nothing. */
+ goto done;
+ }
+
+ if (out_len)
+ {
+ /* Merge cluster backward. */
+ if (cluster < out_info[out_len - 1].cluster)
+ {
+ unsigned int old_cluster = out_info[out_len - 1].cluster;
+ for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--)
+ out_info[i - 1].cluster = cluster;
+ }
+ goto done;
+ }
+
+ if (idx + 1 < len)
+ {
+ /* Merge cluster forward. */
+ merge_clusters (idx, idx + 2);
+ goto done;
+ }
+
+done:
+ skip_glyph ();
+}
void
hb_buffer_t::guess_segment_properties (void)
@@ -594,84 +661,21 @@ hb_buffer_t::guess_segment_properties (void)
}
-static inline void
-dump_var_allocation (const hb_buffer_t *buffer)
-{
- char buf[80];
- for (unsigned int i = 0; i < 8; i++)
- buf[i] = '0' + buffer->allocated_var_bytes[7 - i];
- buf[8] = '\0';
- DEBUG_MSG (BUFFER, buffer,
- "Current var allocation: %s",
- buf);
-}
-
-void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner)
-{
- assert (byte_i < 8 && byte_i + count <= 8);
-
- if (DEBUG_ENABLED (BUFFER))
- dump_var_allocation (this);
- DEBUG_MSG (BUFFER, this,
- "Allocating var bytes %d..%d for %s",
- byte_i, byte_i + count - 1, owner);
-
- for (unsigned int i = byte_i; i < byte_i + count; i++) {
- assert (!allocated_var_bytes[i]);
- allocated_var_bytes[i]++;
- allocated_var_owner[i] = owner;
- }
-}
-
-void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner)
-{
- if (DEBUG_ENABLED (BUFFER))
- dump_var_allocation (this);
-
- DEBUG_MSG (BUFFER, this,
- "Deallocating var bytes %d..%d for %s",
- byte_i, byte_i + count - 1, owner);
-
- assert (byte_i < 8 && byte_i + count <= 8);
- for (unsigned int i = byte_i; i < byte_i + count; i++) {
- assert (allocated_var_bytes[i]);
- assert (0 == strcmp (allocated_var_owner[i], owner));
- allocated_var_bytes[i]--;
- }
-}
-
-void hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner)
-{
- if (DEBUG_ENABLED (BUFFER))
- dump_var_allocation (this);
-
- DEBUG_MSG (BUFFER, this,
- "Asserting var bytes %d..%d for %s",
- byte_i, byte_i + count - 1, owner);
-
- assert (byte_i < 8 && byte_i + count <= 8);
- for (unsigned int i = byte_i; i < byte_i + count; i++) {
- assert (allocated_var_bytes[i]);
- assert (0 == strcmp (allocated_var_owner[i], owner));
- }
-}
-
-void hb_buffer_t::deallocate_var_all (void)
-{
- memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes));
- memset (allocated_var_owner, 0, sizeof (allocated_var_owner));
-}
-
/* Public API */
/**
* hb_buffer_create: (Xconstructor)
*
- *
+ * Creates a new #hb_buffer_t with all properties to defaults.
*
- * Return value: (transfer full)
+ * Return value: (transfer full):
+ * A newly allocated #hb_buffer_t with a reference count of 1. The initial
+ * reference count should be released with hb_buffer_destroy() when you are done
+ * using the #hb_buffer_t. This function never returns %NULL. If memory cannot
+ * be allocated, a special #hb_buffer_t object will be returned on which
+ * hb_buffer_allocation_successful() returns %false.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_buffer_t *
hb_buffer_create (void)
@@ -681,6 +685,8 @@ hb_buffer_create (void)
if (!(buffer = hb_object_create<hb_buffer_t> ()))
return hb_buffer_get_empty ();
+ buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
+
buffer->reset ();
return buffer;
@@ -693,7 +699,7 @@ hb_buffer_create (void)
*
* Return value: (transfer full):
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_buffer_t *
hb_buffer_get_empty (void)
@@ -703,7 +709,10 @@ hb_buffer_get_empty (void)
const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
HB_BUFFER_FLAG_DEFAULT,
+ HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
+ HB_BUFFER_SCRATCH_FLAG_DEFAULT,
+ HB_BUFFER_MAX_LEN_DEFAULT,
HB_BUFFER_CONTENT_TYPE_INVALID,
HB_SEGMENT_PROPERTIES_DEFAULT,
@@ -719,13 +728,15 @@ hb_buffer_get_empty (void)
/**
* hb_buffer_reference: (skip)
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * Increases the reference count on @buffer by one. This prevents @buffer from
+ * being destroyed until a matching call to hb_buffer_destroy() is made.
*
* Return value: (transfer full):
+ * The referenced #hb_buffer_t.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_buffer_t *
hb_buffer_reference (hb_buffer_t *buffer)
@@ -735,11 +746,13 @@ hb_buffer_reference (hb_buffer_t *buffer)
/**
* hb_buffer_destroy: (skip)
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * Deallocate the @buffer.
+ * Decreases the reference count on @buffer by one. If the result is zero, then
+ * @buffer and all associated resources are freed. See hb_buffer_reference().
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_destroy (hb_buffer_t *buffer)
@@ -750,13 +763,15 @@ hb_buffer_destroy (hb_buffer_t *buffer)
free (buffer->info);
free (buffer->pos);
+ if (buffer->message_destroy)
+ buffer->message_destroy (buffer->message_data);
free (buffer);
}
/**
* hb_buffer_set_user_data: (skip)
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
* @key:
* @data:
* @destroy:
@@ -766,7 +781,7 @@ hb_buffer_destroy (hb_buffer_t *buffer)
*
* Return value:
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_bool_t
hb_buffer_set_user_data (hb_buffer_t *buffer,
@@ -780,14 +795,14 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_get_user_data: (skip)
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
* @key:
*
*
*
* Return value:
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void *
hb_buffer_get_user_data (hb_buffer_t *buffer,
@@ -799,12 +814,13 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_set_content_type:
- * @buffer: a buffer.
- * @content_type:
+ * @buffer: an #hb_buffer_t.
+ * @content_type: the type of buffer contents to set
*
- *
+ * Sets the type of @buffer contents, buffers are either empty, contain
+ * characters (before shaping) or glyphs (the result of shaping).
*
- * Since: 1.0
+ * Since: 0.9.5
**/
void
hb_buffer_set_content_type (hb_buffer_t *buffer,
@@ -815,13 +831,14 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
/**
* hb_buffer_get_content_type:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * see hb_buffer_set_content_type().
*
- * Return value:
+ * Return value:
+ * The type of @buffer contents.
*
- * Since: 1.0
+ * Since: 0.9.5
**/
hb_buffer_content_type_t
hb_buffer_get_content_type (hb_buffer_t *buffer)
@@ -832,12 +849,12 @@ hb_buffer_get_content_type (hb_buffer_t *buffer)
/**
* hb_buffer_set_unicode_funcs:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
* @unicode_funcs:
*
*
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
@@ -857,13 +874,13 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
/**
* hb_buffer_get_unicode_funcs:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
*
*
* Return value:
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_unicode_funcs_t *
hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
@@ -873,12 +890,18 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
/**
* hb_buffer_set_direction:
- * @buffer: a buffer.
- * @direction:
- *
- *
- *
- * Since: 1.0
+ * @buffer: an #hb_buffer_t.
+ * @direction: the #hb_direction_t of the @buffer
+ *
+ * Set the text flow direction of the buffer. No shaping can happen without
+ * setting @buffer direction, and it controls the visual direction for the
+ * output glyphs; for RTL direction the glyphs will be reversed. Many layout
+ * features depend on the proper setting of the direction, for example,
+ * reversing RTL text before shaping, then shaping with LTR direction is not
+ * the same as keeping the text in logical order and shaping with RTL
+ * direction.
+ *
+ * Since: 0.9.2
**/
void
hb_buffer_set_direction (hb_buffer_t *buffer,
@@ -893,13 +916,14 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
/**
* hb_buffer_get_direction:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * See hb_buffer_set_direction()
*
- * Return value:
+ * Return value:
+ * The direction of the @buffer.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_direction_t
hb_buffer_get_direction (hb_buffer_t *buffer)
@@ -909,12 +933,20 @@ hb_buffer_get_direction (hb_buffer_t *buffer)
/**
* hb_buffer_set_script:
- * @buffer: a buffer.
- * @script:
+ * @buffer: an #hb_buffer_t.
+ * @script: an #hb_script_t to set.
*
- *
+ * Sets the script of @buffer to @script.
+ *
+ * Script is crucial for choosing the proper shaping behaviour for scripts that
+ * require it (e.g. Arabic) and the which OpenType features defined in the font
+ * to be applied.
+ *
+ * You can pass one of the predefined #hb_script_t values, or use
+ * hb_script_from_string() or hb_script_from_iso15924_tag() to get the
+ * corresponding script from an ISO 15924 script tag.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_set_script (hb_buffer_t *buffer,
@@ -928,13 +960,14 @@ hb_buffer_set_script (hb_buffer_t *buffer,
/**
* hb_buffer_get_script:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * See hb_buffer_set_script().
*
- * Return value:
+ * Return value:
+ * The #hb_script_t of the @buffer.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_script_t
hb_buffer_get_script (hb_buffer_t *buffer)
@@ -944,12 +977,20 @@ hb_buffer_get_script (hb_buffer_t *buffer)
/**
* hb_buffer_set_language:
- * @buffer: a buffer.
- * @language:
+ * @buffer: an #hb_buffer_t.
+ * @language: an hb_language_t to set.
*
- *
+ * Sets the language of @buffer to @language.
+ *
+ * Languages are crucial for selecting which OpenType feature to apply to the
+ * buffer which can result in applying language-specific behaviour. Languages
+ * are orthogonal to the scripts, and though they are related, they are
+ * different concepts and should not be confused with each other.
+ *
+ * Use hb_language_from_string() to convert from ISO 639 language codes to
+ * #hb_language_t.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_set_language (hb_buffer_t *buffer,
@@ -963,13 +1004,14 @@ hb_buffer_set_language (hb_buffer_t *buffer,
/**
* hb_buffer_get_language:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * See hb_buffer_set_language().
*
- * Return value:
+ * Return value: (transfer none):
+ * The #hb_language_t of the buffer. Must not be freed by the caller.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_language_t
hb_buffer_get_language (hb_buffer_t *buffer)
@@ -979,12 +1021,14 @@ hb_buffer_get_language (hb_buffer_t *buffer)
/**
* hb_buffer_set_segment_properties:
- * @buffer: a buffer.
- * @props:
+ * @buffer: an #hb_buffer_t.
+ * @props: an #hb_segment_properties_t to use.
*
- *
+ * Sets the segment properties of the buffer, a shortcut for calling
+ * hb_buffer_set_direction(), hb_buffer_set_script() and
+ * hb_buffer_set_language() individually.
*
- * Since: 1.0
+ * Since: 0.9.7
**/
void
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
@@ -998,12 +1042,12 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_get_segment_properties:
- * @buffer: a buffer.
- * @props:
+ * @buffer: an #hb_buffer_t.
+ * @props: (out): the output #hb_segment_properties_t.
*
- *
+ * Sets @props to the #hb_segment_properties_t of @buffer.
*
- * Since: 1.0
+ * Since: 0.9.7
**/
void
hb_buffer_get_segment_properties (hb_buffer_t *buffer,
@@ -1015,12 +1059,12 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_set_flags:
- * @buffer: a buffer.
- * @flags:
+ * @buffer: an #hb_buffer_t.
+ * @flags: the buffer flags to set.
*
- *
+ * Sets @buffer flags to @flags. See #hb_buffer_flags_t.
*
- * Since: 1.0
+ * Since: 0.9.7
**/
void
hb_buffer_set_flags (hb_buffer_t *buffer,
@@ -1034,13 +1078,14 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
/**
* hb_buffer_get_flags:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * See hb_buffer_set_flags().
*
* Return value:
+ * The @buffer flags.
*
- * Since: 1.0
+ * Since: 0.9.7
**/
hb_buffer_flags_t
hb_buffer_get_flags (hb_buffer_t *buffer)
@@ -1048,15 +1093,53 @@ hb_buffer_get_flags (hb_buffer_t *buffer)
return buffer->flags;
}
+/**
+ * hb_buffer_set_cluster_level:
+ * @buffer: an #hb_buffer_t.
+ * @cluster_level:
+ *
+ *
+ *
+ * Since: 0.9.42
+ **/
+void
+hb_buffer_set_cluster_level (hb_buffer_t *buffer,
+ hb_buffer_cluster_level_t cluster_level)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->cluster_level = cluster_level;
+}
/**
- * hb_buffer_set_replacement_codepoint:
- * @buffer: a buffer.
- * @replacement:
+ * hb_buffer_get_cluster_level:
+ * @buffer: an #hb_buffer_t.
*
*
*
- * Since: 1.0
+ * Return value:
+ *
+ * Since: 0.9.42
+ **/
+hb_buffer_cluster_level_t
+hb_buffer_get_cluster_level (hb_buffer_t *buffer)
+{
+ return buffer->cluster_level;
+}
+
+
+/**
+ * hb_buffer_set_replacement_codepoint:
+ * @buffer: an #hb_buffer_t.
+ * @replacement: the replacement #hb_codepoint_t
+ *
+ * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
+ * when adding text to @buffer.
+ *
+ * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
+ *
+ * Since: 0.9.31
**/
void
hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
@@ -1070,13 +1153,14 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
/**
* hb_buffer_get_replacement_codepoint:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * See hb_buffer_set_replacement_codepoint().
*
* Return value:
+ * The @buffer replacement #hb_codepoint_t.
*
- * Since: 1.0
+ * Since: 0.9.31
**/
hb_codepoint_t
hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
@@ -1087,11 +1171,12 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
/**
* hb_buffer_reset:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * Resets the buffer to its initial status, as if it was just newly created
+ * with hb_buffer_create().
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_reset (hb_buffer_t *buffer)
@@ -1101,11 +1186,12 @@ hb_buffer_reset (hb_buffer_t *buffer)
/**
* hb_buffer_clear_contents:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * Similar to hb_buffer_reset(), but does not clear the Unicode functions and
+ * the replacement code point.
*
- * Since: 1.0
+ * Since: 0.9.11
**/
void
hb_buffer_clear_contents (hb_buffer_t *buffer)
@@ -1115,14 +1201,15 @@ hb_buffer_clear_contents (hb_buffer_t *buffer)
/**
* hb_buffer_pre_allocate:
- * @buffer: a buffer.
- * @size:
+ * @buffer: an #hb_buffer_t.
+ * @size: number of items to pre allocate.
*
- *
+ * Pre allocates memory for @buffer to fit at least @size number of items.
*
- * Return value:
+ * Return value:
+ * %true if @buffer memory allocation succeeded, %false otherwise.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
@@ -1132,13 +1219,14 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
/**
* hb_buffer_allocation_successful:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * Check if allocating memory for the buffer succeeded.
*
- * Return value:
+ * Return value:
+ * %true if @buffer memory allocation succeeded, %false otherwise.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_bool_t
hb_buffer_allocation_successful (hb_buffer_t *buffer)
@@ -1148,13 +1236,20 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer)
/**
* hb_buffer_add:
- * @buffer: a buffer.
- * @codepoint:
- * @cluster:
+ * @buffer: an #hb_buffer_t.
+ * @codepoint: a Unicode code point.
+ * @cluster: the cluster value of @codepoint.
*
- *
+ * Appends a character with the Unicode value of @codepoint to @buffer, and
+ * gives it the initial cluster value of @cluster. Clusters can be any thing
+ * the client wants, they are usually used to refer to the index of the
+ * character in the input text stream and are output in
+ * #hb_glyph_info_t.cluster field.
+ *
+ * This function does not check the validity of @codepoint, it is up to the
+ * caller to ensure it is a valid Unicode code point.
*
- * Since: 1.0
+ * Since: 0.9.7
**/
void
hb_buffer_add (hb_buffer_t *buffer,
@@ -1167,14 +1262,16 @@ hb_buffer_add (hb_buffer_t *buffer,
/**
* hb_buffer_set_length:
- * @buffer: a buffer.
- * @length:
+ * @buffer: an #hb_buffer_t.
+ * @length: the new length of @buffer.
*
- *
+ * Similar to hb_buffer_pre_allocate(), but clears any new items added at the
+ * end.
*
* Return value:
+ * %true if @buffer memory allocation succeeded, %false otherwise.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_bool_t
hb_buffer_set_length (hb_buffer_t *buffer,
@@ -1207,13 +1304,15 @@ hb_buffer_set_length (hb_buffer_t *buffer,
/**
* hb_buffer_get_length:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
* Returns the number of items in the buffer.
*
- * Return value: buffer length.
+ * Return value:
+ * The @buffer length.
+ * The value valid as long as buffer has not been modified.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
unsigned int
hb_buffer_get_length (hb_buffer_t *buffer)
@@ -1223,15 +1322,17 @@ hb_buffer_get_length (hb_buffer_t *buffer)
/**
* hb_buffer_get_glyph_infos:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
* @length: (out): output array length.
*
- * Returns buffer glyph information array. Returned pointer
- * is valid as long as buffer contents are not modified.
+ * Returns @buffer glyph information array. Returned pointer
+ * is valid as long as @buffer contents are not modified.
*
- * Return value: (transfer none) (array length=length): buffer glyph information array.
+ * Return value: (transfer none) (array length=length):
+ * The @buffer glyph information array.
+ * The value valid as long as buffer has not been modified.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
@@ -1245,15 +1346,17 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
/**
* hb_buffer_get_glyph_positions:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
* @length: (out): output length.
*
- * Returns buffer glyph position array. Returned pointer
- * is valid as long as buffer contents are not modified.
+ * Returns @buffer glyph position array. Returned pointer
+ * is valid as long as @buffer contents are not modified.
*
- * Return value: (transfer none) (array length=length): buffer glyph position array.
+ * Return value: (transfer none) (array length=length):
+ * The @buffer glyph position array.
+ * The value valid as long as buffer has not been modified.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
@@ -1270,11 +1373,11 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
/**
* hb_buffer_reverse:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
* Reverses buffer contents.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_reverse (hb_buffer_t *buffer)
@@ -1283,14 +1386,31 @@ hb_buffer_reverse (hb_buffer_t *buffer)
}
/**
+ * hb_buffer_reverse_range:
+ * @buffer: an #hb_buffer_t.
+ * @start: start index.
+ * @end: end index.
+ *
+ * Reverses buffer contents between start to end.
+ *
+ * Since: 0.9.41
+ **/
+void
+hb_buffer_reverse_range (hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ buffer->reverse_range (start, end);
+}
+
+/**
* hb_buffer_reverse_clusters:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
* Reverses buffer clusters. That is, the buffer contents are
* reversed, then each cluster (consecutive items having the
* same cluster number) are reversed again.
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_reverse_clusters (hb_buffer_t *buffer)
@@ -1300,7 +1420,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
/**
* hb_buffer_guess_segment_properties:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
* Sets unset buffer segment properties based on buffer Unicode
* contents. If buffer is not empty, it must have content type
@@ -1320,7 +1440,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
* hb_language_get_default(). This may change in the future by
* taking buffer script into consideration when choosing a language.
*
- * Since: 1.0
+ * Since: 0.9.7
**/
void
hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
@@ -1399,15 +1519,20 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf8:
- * @buffer: a buffer.
- * @text: (array length=text_length) (element-type uint8_t):
- * @text_length:
- * @item_offset:
- * @item_length:
+ * @buffer: an #hb_buffer_t.
+ * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
+ * characters to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
+ * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
*
- *
+ * See hb_buffer_add_codepoints().
+ *
+ * Replaces invalid UTF-8 characters with the @buffer replacement code point,
+ * see hb_buffer_set_replacement_codepoint().
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_add_utf8 (hb_buffer_t *buffer,
@@ -1421,15 +1546,19 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf16:
- * @buffer: a buffer.
- * @text: (array length=text_length):
- * @text_length:
- * @item_offset:
- * @item_length:
+ * @buffer: an #hb_buffer_t.
+ * @text: (array length=text_length): an array of UTF-16 characters to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
+ * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
*
- *
+ * See hb_buffer_add_codepoints().
*
- * Since: 1.0
+ * Replaces invalid UTF-16 characters with the @buffer replacement code point,
+ * see hb_buffer_set_replacement_codepoint().
+ *
+ * Since: 0.9.2
**/
void
hb_buffer_add_utf16 (hb_buffer_t *buffer,
@@ -1443,15 +1572,19 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf32:
- * @buffer: a buffer.
- * @text: (array length=text_length):
- * @text_length:
- * @item_offset:
- * @item_length:
+ * @buffer: an #hb_buffer_t.
+ * @text: (array length=text_length): an array of UTF-32 characters to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
+ * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
*
- *
+ * See hb_buffer_add_codepoints().
+ *
+ * Replaces invalid UTF-32 characters with the @buffer replacement code point,
+ * see hb_buffer_set_replacement_codepoint().
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_add_utf32 (hb_buffer_t *buffer,
@@ -1465,15 +1598,20 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
/**
* hb_buffer_add_latin1:
- * @buffer: a buffer.
- * @text: (array length=text_length) (element-type uint8_t):
- * @text_length:
- * @item_offset:
- * @item_length:
+ * @buffer: an #hb_buffer_t.
+ * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
+ * characters to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
+ * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
*
- *
+ * Similar to hb_buffer_add_codepoints(), but allows only access to first 256
+ * Unicode code points that can fit in 8-bit strings.
+ *
+ * <note>Has nothing to do with non-Unicode Latin-1 encoding.</note>
*
- * Since: 1.0
+ * Since: 0.9.39
**/
void
hb_buffer_add_latin1 (hb_buffer_t *buffer,
@@ -1487,15 +1625,27 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer,
/**
* hb_buffer_add_codepoints:
- * @buffer: a buffer.
- * @text: (array length=text_length):
- * @text_length:
- * @item_offset:
- * @item_length:
- *
- *
- *
- * Since: 1.0
+ * @buffer: a #hb_buffer_t to append characters to.
+ * @text: (array length=text_length): an array of Unicode code points to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first code point to add to the @buffer.
+ * @item_length: the number of code points to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
+ *
+ * Appends characters from @text array to @buffer. The @item_offset is the
+ * position of the first character from @text that will be appended, and
+ * @item_length is the number of character. When shaping part of a larger text
+ * (e.g. a run of text from a paragraph), instead of passing just the substring
+ * corresponding to the run, it is preferable to pass the whole
+ * paragraph and specify the run start and length as @item_offset and
+ * @item_length, respectively, to give HarfBuzz the full context to be able,
+ * for example, to do cross-run Arabic shaping or properly handle combining
+ * marks at stat of run.
+ *
+ * This function does not check the validity of @text, it is up to the caller
+ * to ensure it contains a valid Unicode code points.
+ *
+ * Since: 0.9.31
**/
void
hb_buffer_add_codepoints (hb_buffer_t *buffer,
@@ -1550,7 +1700,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
pos[end - 1].x_advance = total_x_advance;
pos[end - 1].y_advance = total_y_advance;
- hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
+ hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
} else {
/* Transfer all cluster advance to the first glyph. */
pos[start].x_advance += total_x_advance;
@@ -1559,17 +1709,20 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
pos[i].x_offset -= total_x_advance;
pos[i].y_offset -= total_y_advance;
}
- hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
+ hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
}
}
/**
* hb_buffer_normalize_glyphs:
- * @buffer: a buffer.
+ * @buffer: an #hb_buffer_t.
*
- *
+ * Reorders a glyph buffer to have canonical in-cluster glyph order / position.
+ * The resulting clusters should behave identical to pre-reordering clusters.
+ *
+ * <note>This has nothing to do with Unicode normalization.</note>
*
- * Since: 1.0
+ * Since: 0.9.2
**/
void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
@@ -1592,3 +1745,66 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
}
normalize_glyphs_cluster (buffer, start, end, backward);
}
+
+void
+hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *))
+{
+ assert (!have_positions);
+ for (unsigned int i = start + 1; i < end; i++)
+ {
+ unsigned int j = i;
+ while (j > start && compar (&info[j - 1], &info[i]) > 0)
+ j--;
+ if (i == j)
+ continue;
+ /* Move item i to occupy place for item j, shift what's in between. */
+ merge_clusters (j, i + 1);
+ {
+ hb_glyph_info_t t = info[i];
+ memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t));
+ info[j] = t;
+ }
+ }
+}
+
+/*
+ * Debugging.
+ */
+
+/**
+ * hb_buffer_set_message_func:
+ * @buffer: an #hb_buffer_t.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.1.3
+ **/
+void
+hb_buffer_set_message_func (hb_buffer_t *buffer,
+ hb_buffer_message_func_t func,
+ void *user_data, hb_destroy_func_t destroy)
+{
+ if (buffer->message_destroy)
+ buffer->message_destroy (buffer->message_data);
+
+ if (func) {
+ buffer->message_func = func;
+ buffer->message_data = user_data;
+ buffer->message_destroy = destroy;
+ } else {
+ buffer->message_func = NULL;
+ buffer->message_data = NULL;
+ buffer->message_destroy = NULL;
+ }
+}
+
+bool
+hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
+{
+ char buf[100];
+ vsnprintf (buf, sizeof (buf), fmt, ap);
+ return (bool) this->message_func (this, font, buf, this->message_data);
+}