Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: third_party/harfbuzz-ng/src/hb-buffer.cc

Issue 10915172: harfbuzz-ng roll (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-buffer.h ('k') | third_party/harfbuzz-ng/src/hb-buffer-private.hh » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/harfbuzz-ng/src/hb-buffer.cc
diff --git a/third_party/harfbuzz-ng/src/hb-buffer.cc b/third_party/harfbuzz-ng/src/hb-buffer.cc
index 9c9b32e3adaccfc1d4a81f0be09747c3e72b64d7..fec9225b483afbefc2878ddbced12b1a0f79ebf6 100644
--- a/third_party/harfbuzz-ng/src/hb-buffer.cc
+++ b/third_party/harfbuzz-ng/src/hb-buffer.cc
@@ -37,9 +37,6 @@
#define HB_DEBUG_BUFFER (HB_DEBUG+0)
#endif
-#define _HB_BUFFER_UNICODE_FUNCS_DEFAULT (const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_default))
-#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
-
/* Here is how the buffer works internally:
*
* There are two info pointers: info and out_info. They always have
@@ -126,12 +123,16 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
{
have_output = false;
have_positions = false;
+
out_len = 0;
+ out_info = info;
+
*size = allocated * sizeof (pos[0]);
return pos;
}
+
/* HarfBuzz-Internal API */
void
@@ -141,11 +142,12 @@ hb_buffer_t::reset (void)
return;
hb_unicode_funcs_destroy (unicode);
- unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
+ unicode = hb_unicode_funcs_get_default ();
hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
props = default_props;
+ content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
in_error = false;
have_output = false;
have_positions = false;
@@ -153,12 +155,11 @@ hb_buffer_t::reset (void)
idx = 0;
len = 0;
out_len = 0;
+ out_info = info;
serial = 0;
memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
memset (allocated_var_owner, 0, sizeof allocated_var_owner);
-
- out_info = info;
}
void
@@ -202,6 +203,9 @@ hb_buffer_t::clear_positions (void)
have_output = false;
have_positions = true;
+ out_len = 0;
+ out_info = info;
+
memset (pos, 0, sizeof (pos[0]) * len);
}
@@ -230,47 +234,17 @@ hb_buffer_t::swap_buffers (void)
idx = 0;
}
-void
-hb_buffer_t::replace_glyphs_be16 (unsigned int num_in,
- unsigned int num_out,
- const char *glyph_data_be)
-{
- if (!make_room_for (num_in, num_out)) return;
-
- hb_glyph_info_t orig_info = info[idx];
- for (unsigned int i = 1; i < num_in; i++)
- {
- hb_glyph_info_t *inf = &info[idx + i];
- orig_info.cluster = MIN (orig_info.cluster, inf->cluster);
- }
-
- hb_glyph_info_t *pinfo = &out_info[out_len];
- const unsigned char *data = (const unsigned char *) glyph_data_be;
- for (unsigned int i = 0; i < num_out; i++)
- {
- *pinfo = orig_info;
- pinfo->codepoint = (data[2*i] << 8) | data[2*i+1];
- pinfo++;
- }
-
- idx += num_in;
- out_len += num_out;
-}
void
hb_buffer_t::replace_glyphs (unsigned int num_in,
unsigned int num_out,
const uint32_t *glyph_data)
{
- if (!make_room_for (num_in, num_out)) return;
+ if (unlikely (!make_room_for (num_in, num_out))) return;
- hb_glyph_info_t orig_info = info[idx];
- for (unsigned int i = 1; i < num_in; i++)
- {
- hb_glyph_info_t *inf = &info[idx + i];
- orig_info.cluster = MIN (orig_info.cluster, inf->cluster);
- }
+ merge_clusters (idx, idx + num_in);
+ hb_glyph_info_t orig_info = info[idx];
hb_glyph_info_t *pinfo = &out_info[out_len];
for (unsigned int i = 0; i < num_out; i++)
{
@@ -286,7 +260,7 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
void
hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
{
- if (!make_room_for (0, 1)) return;
+ if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = info[idx];
out_info[out_len].codepoint = glyph_index;
@@ -295,46 +269,39 @@ hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
}
void
-hb_buffer_t::copy_glyph (void)
+hb_buffer_t::output_info (hb_glyph_info_t &glyph_info)
{
- if (!make_room_for (0, 1)) return;
+ if (unlikely (!make_room_for (0, 1))) return;
- out_info[out_len] = info[idx];
+ out_info[out_len] = glyph_info;
out_len++;
}
void
-hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
+hb_buffer_t::copy_glyph (void)
{
- if (!make_room_for (1, 1)) return;
+ if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = info[idx];
- out_info[out_len].codepoint = glyph_index;
- idx++;
out_len++;
}
void
-hb_buffer_t::next_glyph (void)
+hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
{
- if (have_output)
- {
- if (out_info != info)
- {
- if (unlikely (!ensure (out_len + 1))) return;
- out_info[out_len] = info[idx];
- }
- else if (out_len != idx)
- out_info[out_len] = info[idx];
-
- out_len++;
+ if (unlikely (out_info != info || out_len != idx)) {
+ if (unlikely (!make_room_for (1, 1))) return;
+ out_info[out_len] = info[idx];
}
+ out_info[out_len].codepoint = glyph_index;
idx++;
+ out_len++;
}
+
void
hb_buffer_t::set_masks (hb_mask_t value,
hb_mask_t mask,
@@ -424,32 +391,69 @@ void
hb_buffer_t::merge_clusters (unsigned int start,
unsigned int end)
{
- unsigned int cluster = this->info[start].cluster;
+ if (unlikely (end - start < 2))
+ return;
+
+ unsigned int cluster = info[start].cluster;
for (unsigned int i = start + 1; i < end; i++)
- cluster = MIN (cluster, this->info[i].cluster);
+ cluster = MIN (cluster, info[i].cluster);
+
+ /* Extend end */
+ while (end < len && info[end - 1].cluster == info[end].cluster)
+ end++;
+
+ /* Extend start */
+ while (idx < start && info[start - 1].cluster == info[start].cluster)
+ 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--)
+ out_info[i - 1].cluster = cluster;
+
for (unsigned int i = start; i < end; i++)
- this->info[i].cluster = cluster;
+ info[i].cluster = cluster;
}
void
hb_buffer_t::merge_out_clusters (unsigned int start,
unsigned int end)
{
- unsigned int cluster = this->out_info[start].cluster;
+ if (unlikely (end - start < 2))
+ return;
+
+ unsigned int cluster = out_info[start].cluster;
for (unsigned int i = start + 1; i < end; i++)
- cluster = MIN (cluster, this->out_info[i].cluster);
+ cluster = MIN (cluster, out_info[i].cluster);
+
+ /* Extend start */
+ while (start && out_info[start - 1].cluster == out_info[start].cluster)
+ start--;
+
+ /* Extend end */
+ while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
+ end++;
+
+ /* 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++)
+ info[i].cluster = cluster;
+
for (unsigned int i = start; i < end; i++)
- this->out_info[i].cluster = cluster;
+ out_info[i].cluster = cluster;
}
void
hb_buffer_t::guess_properties (void)
{
+ if (unlikely (!len)) return;
+ assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
+
/* If script is set to INVALID, guess from buffer contents */
if (props.script == HB_SCRIPT_INVALID) {
for (unsigned int i = 0; i < len; i++) {
- hb_script_t script = hb_unicode_script (unicode, info[i].codepoint);
+ hb_script_t script = unicode->script (info[i].codepoint);
if (likely (script != HB_SCRIPT_COMMON &&
script != HB_SCRIPT_INHERITED &&
script != HB_SCRIPT_UNKNOWN)) {
@@ -518,6 +522,22 @@ void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const
}
}
+void hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+ if (DEBUG (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));
@@ -545,9 +565,10 @@ hb_buffer_get_empty (void)
static const hb_buffer_t _hb_buffer_nil = {
HB_OBJECT_HEADER_STATIC,
- _HB_BUFFER_UNICODE_FUNCS_DEFAULT,
+ const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
_HB_BUFFER_PROPS_DEFAULT,
+ HB_BUFFER_CONTENT_TYPE_INVALID,
true, /* in_error */
true, /* have_output */
true /* have_positions */
@@ -594,6 +615,20 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
void
+hb_buffer_set_content_type (hb_buffer_t *buffer,
+ hb_buffer_content_type_t content_type)
+{
+ buffer->content_type = content_type;
+}
+
+hb_buffer_content_type_t
+hb_buffer_get_content_type (hb_buffer_t *buffer)
+{
+ return buffer->content_type;
+}
+
+
+void
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
hb_unicode_funcs_t *unicode)
{
@@ -601,7 +636,8 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
return;
if (!unicode)
- unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
+ unicode = hb_unicode_funcs_get_default ();
+
hb_unicode_funcs_reference (unicode);
hb_unicode_funcs_destroy (buffer->unicode);
@@ -832,6 +868,11 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
unsigned int item_offset,
int item_length)
{
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
#define UTF_NEXT(S, E, U) hb_utf8_next (S, E, &(U))
ADD_UTF (uint8_t);
#undef UTF_NEXT
@@ -866,6 +907,11 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
unsigned int item_offset,
int item_length)
{
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
#define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U))
ADD_UTF (uint16_t);
#undef UTF_NEXT
@@ -878,9 +924,90 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
unsigned int item_offset,
int item_length)
{
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
#define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1)
ADD_UTF (uint32_t);
#undef UTF_NEXT
}
+static int
+compare_info_codepoint (const hb_glyph_info_t *pa,
+ const hb_glyph_info_t *pb)
+{
+ return (int) pb->codepoint - (int) pa->codepoint;
+}
+
+static inline void
+normalize_glyphs_cluster (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ bool backward)
+{
+ hb_glyph_position_t *pos = buffer->pos;
+
+ /* Total cluster advance */
+ hb_position_t total_x_advance = 0, total_y_advance = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ total_x_advance += pos[i].x_advance;
+ total_y_advance += pos[i].y_advance;
+ }
+
+ hb_position_t x_advance = 0, y_advance = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ pos[i].x_offset += x_advance;
+ pos[i].y_offset += y_advance;
+
+ x_advance += pos[i].x_advance;
+ y_advance += pos[i].y_advance;
+
+ pos[i].x_advance = 0;
+ pos[i].y_advance = 0;
+ }
+
+ if (backward)
+ {
+ /* Transfer all cluster advance to the last glyph. */
+ 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);
+ } else {
+ /* Transfer all cluster advance to the first glyph. */
+ pos[start].x_advance += total_x_advance;
+ pos[start].y_advance += total_y_advance;
+ for (unsigned int i = start + 1; i < end; i++) {
+ 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);
+ }
+}
+
+void
+hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
+{
+ assert (buffer->have_positions);
+ /* XXX assert (buffer->have_glyphs); */
+
+ bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+ hb_glyph_info_t *info = buffer->info;
+
+ unsigned int start = 0;
+ unsigned int end;
+ for (end = start + 1; end < count; end++)
+ if (info[start].cluster != info[end].cluster) {
+ normalize_glyphs_cluster (buffer, start, end, backward);
+ start = end;
+ }
+ normalize_glyphs_cluster (buffer, start, end, backward);
+}
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-buffer.h ('k') | third_party/harfbuzz-ng/src/hb-buffer-private.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698