From 05207a79e0ae1769c5feaebe3fd99bdf9cfcf834 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 25 Sep 2012 17:44:53 -0400 Subject: [PATCH] [buffer] Save pre/post textual context To be used for a variety of purposes. We save up to five characters in each direction. No public API changes, everything is taken care of already. All clients need to do is to call hb_buffer_add_utf* with the full text + segment info (or at least some context) instead of just passing in the segment. Various operations (hb_buffer_reset, hb_buffer_set_length, hb_buffer_add*) automatically reset the relevant contexts. --- src/hb-buffer-private.hh | 13 +++++++++++- src/hb-buffer.cc | 44 ++++++++++++++++++++++++++++++++++++---- src/hb-buffer.h | 2 +- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index f5d64f3f8..67a2752c0 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -1,7 +1,7 @@ /* * Copyright © 1998-2004 David Turner and Werner Lemberg * Copyright © 2004,2007,2009,2010 Red Hat, Inc. - * Copyright © 2011 Google, Inc. + * Copyright © 2011,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -117,9 +117,18 @@ struct hb_buffer_t { inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; } unsigned int serial; + + /* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */ uint8_t allocated_var_bytes[8]; const char *allocated_var_owner[8]; + /* Text before / after the main buffer contents. + * Always in Unicode, and ordered outward. + * Index 0 is for "pre-context", 1 for "post-context". */ + static const unsigned int CONTEXT_LENGTH = 5; + hb_codepoint_t context[2][CONTEXT_LENGTH]; + unsigned int context_len[2]; + /* Methods */ @@ -206,6 +215,8 @@ struct hb_buffer_t { HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); HB_INTERNAL void *get_scratch_buffer (unsigned int *size); + + inline void clear_context (unsigned int side) { context_len[side] = 0; } }; diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 6da196fe3..2f8f511b0 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -1,7 +1,7 @@ /* * Copyright © 1998-2004 David Turner and Werner Lemberg * Copyright © 2004,2007,2009,2010 Red Hat, Inc. - * Copyright © 2011 Google, Inc. + * Copyright © 2011,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -158,6 +158,9 @@ hb_buffer_t::reset (void) 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); } void @@ -570,6 +573,8 @@ hb_buffer_get_empty (void) true, /* in_error */ true, /* have_output */ true /* have_positions */ + + /* Zero is good enough for everything else. */ }; return const_cast (&_hb_buffer_nil); @@ -723,6 +728,7 @@ hb_buffer_add (hb_buffer_t *buffer, unsigned int cluster) { buffer->add (codepoint, mask, cluster); + buffer->clear_context (1); } hb_bool_t @@ -743,6 +749,11 @@ hb_buffer_set_length (hb_buffer_t *buffer, } buffer->len = length; + + if (!length) + buffer->clear_context (0); + buffer->clear_context (1); + return true; } @@ -817,13 +828,38 @@ hb_buffer_add_utf (hb_buffer_t *buffer, buffer->ensure (buffer->len + item_length * sizeof (T) / 4); - const T *next = (const T *) text + item_offset; + if (!buffer->len) + { + /* Add pre-context */ + buffer->clear_context (0); + const T *prev = text + item_offset; + const T *start = text; + while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH) + { + hb_codepoint_t u; + prev = hb_utf_prev (prev, start, &u); + buffer->context[0][buffer->context_len[0]++] = u; + } + } + + const T *next = text + item_offset; const T *end = next + item_length; - while (next < end) { + while (next < end) + { hb_codepoint_t u; const T *old_next = next; next = hb_utf_next (next, end, &u); - hb_buffer_add (buffer, u, 1, old_next - (const T *) text); + buffer->add (u, 1, old_next - (const T *) text); + } + + /* Add post-context */ + buffer->clear_context (1); + end = text + text_length; + while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH) + { + hb_codepoint_t u; + next = hb_utf_next (next, end, &u); + buffer->context[1][buffer->context_len[1]++] = u; } buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE; diff --git a/src/hb-buffer.h b/src/hb-buffer.h index d89dce3c1..dc63d1bf6 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -1,7 +1,7 @@ /* * Copyright © 1998-2004 David Turner and Werner Lemberg * Copyright © 2004,2007,2009 Red Hat, Inc. - * Copyright © 2011 Google, Inc. + * Copyright © 2011,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. *