[pango/harfbuzz-ng: 20/57] [HB] Port buffert to new object API



commit b522838694c10d2f4055ff0a22167c0ace546e04
Author: Behdad Esfahbod <behdad behdad org>
Date:   Sat Aug 1 22:19:06 2009 -0400

    [HB] Port buffert to new object API

 pango/opentype/hb-buffer-private.h |   24 +++++++++++--
 pango/opentype/hb-buffer.c         |   65 +++++++++++++++++++++++++++--------
 pango/opentype/hb-buffer.h         |   53 ++++++++++++++++++-----------
 pango/pango-ot-buffer.c            |   33 +++++++++++-------
 pango/pango-ot-info.c              |   10 +++---
 5 files changed, 129 insertions(+), 56 deletions(-)
---
diff --git a/pango/opentype/hb-buffer-private.h b/pango/opentype/hb-buffer-private.h
index 5f64bc1..a648a0e 100644
--- a/pango/opentype/hb-buffer-private.h
+++ b/pango/opentype/hb-buffer-private.h
@@ -35,6 +35,27 @@ HB_BEGIN_DECLS
 
 #define HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
 
+
+struct _hb_buffer_t {
+  hb_reference_count_t ref_count;
+
+  unsigned int allocated;
+
+  unsigned int in_length;
+  unsigned int out_length;
+  unsigned int in_pos;
+  unsigned int out_pos;
+
+  hb_glyph_info_t     *in_string;
+  hb_glyph_info_t     *out_string;
+  hb_glyph_info_t     *alt_string;
+  hb_glyph_position_t *positions;
+
+  hb_direction_t       direction;
+  unsigned int         max_lig_id;
+};
+
+
 HB_INTERNAL void
 _hb_buffer_swap (hb_buffer_t *buffer);
 
@@ -42,9 +63,6 @@ HB_INTERNAL void
 _hb_buffer_clear_output (hb_buffer_t *buffer);
 
 HB_INTERNAL void
-_hb_buffer_clear_positions (hb_buffer_t *buffer);
-
-HB_INTERNAL void
 _hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
 			      unsigned int num_in,
 			      unsigned int num_out,
diff --git a/pango/opentype/hb-buffer.c b/pango/opentype/hb-buffer.c
index 89887fc..a4b92d7 100644
--- a/pango/opentype/hb-buffer.c
+++ b/pango/opentype/hb-buffer.c
@@ -29,6 +29,10 @@
 
 #include <string.h>
 
+static hb_buffer_t _hb_buffer_nil = {
+  HB_REFERENCE_COUNT_INVALID /* ref_count */
+};
+
 /* Here is how the buffer works internally:
  *
  * There are two string pointers: in_string and out_string.  They
@@ -69,33 +73,40 @@ hb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size)
 /* Public API */
 
 hb_buffer_t *
-hb_buffer_new (unsigned int allocation_size)
+hb_buffer_create (unsigned int pre_alloc_size)
 {
   hb_buffer_t *buffer;
 
-  buffer = calloc (1, sizeof (hb_buffer_t));
-  if (HB_UNLIKELY (!buffer))
-    return NULL;
+  if (!HB_OBJECT_DO_CREATE (buffer))
+    return &_hb_buffer_nil;
 
-  buffer->allocated = 0;
-  buffer->in_string = NULL;
-  buffer->alt_string = NULL;
-  buffer->positions = NULL;
+  if (pre_alloc_size)
+    hb_buffer_ensure(buffer, pre_alloc_size);
 
-  hb_buffer_clear (buffer);
+  return buffer;
+}
 
-  if (allocation_size)
-    hb_buffer_ensure(buffer, allocation_size);
+hb_buffer_t *
+hb_buffer_reference (hb_buffer_t *buffer)
+{
+  HB_OBJECT_DO_REFERENCE (buffer);
+}
 
-  return buffer;
+unsigned int
+hb_buffer_get_reference_count (hb_buffer_t *buffer)
+{
+  HB_OBJECT_DO_GET_REFERENCE_COUNT (buffer);
 }
 
 void
-hb_buffer_free (hb_buffer_t *buffer)
+hb_buffer_destroy (hb_buffer_t *buffer)
 {
+  HB_OBJECT_DO_DESTROY (buffer);
+
   free (buffer->in_string);
   free (buffer->alt_string);
   free (buffer->positions);
+
   free (buffer);
 }
 
@@ -185,8 +196,8 @@ _hb_buffer_clear_output (hb_buffer_t *buffer)
   buffer->out_string = buffer->in_string;
 }
 
-HB_INTERNAL void
-_hb_buffer_clear_positions (hb_buffer_t *buffer)
+void
+hb_buffer_clear_positions (hb_buffer_t *buffer)
 {
   _hb_buffer_clear_output (buffer);
 
@@ -340,3 +351,27 @@ _hb_buffer_allocate_lig_id (hb_buffer_t *buffer)
 {
   return ++buffer->max_lig_id;
 }
+
+
+unsigned int
+hb_buffer_get_len (hb_buffer_t *buffer)
+{
+  return buffer->in_length;
+}
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_info_t *
+hb_buffer_get_glyph_infos (hb_buffer_t *buffer)
+{
+  return buffer->in_string;
+}
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_position_t *
+hb_buffer_get_glyph_positions (hb_buffer_t *buffer)
+{
+  if (buffer->in_length && !buffer->positions)
+    hb_buffer_clear_positions (buffer);
+
+  return buffer->positions;
+}
diff --git a/pango/opentype/hb-buffer.h b/pango/opentype/hb-buffer.h
index 1376ad4..26879bf 100644
--- a/pango/opentype/hb-buffer.h
+++ b/pango/opentype/hb-buffer.h
@@ -32,6 +32,8 @@
 
 HB_BEGIN_DECLS
 
+typedef struct _hb_buffer_t hb_buffer_t;
+
 typedef enum _hb_direction_t {
   HB_DIRECTION_LTR,
   HB_DIRECTION_RTL,
@@ -39,7 +41,7 @@ typedef enum _hb_direction_t {
   HB_DIRECTION_BTT
 } hb_direction_t;
 
-/* XXX  Hide structs? */
+/* XXX these structs need review before we can commit to them */
 
 typedef struct _hb_glyph_info_t {
   hb_codepoint_t gindex;
@@ -67,45 +69,56 @@ typedef struct _hb_glyph_position_t {
 } hb_glyph_position_t;
 
 
-typedef struct _hb_buffer_t {
-  unsigned int allocated;
+hb_buffer_t *
+hb_buffer_create (unsigned int pre_alloc_size);
 
-  unsigned int in_length;
-  unsigned int out_length;
-  unsigned int in_pos;
-  unsigned int out_pos;
+hb_buffer_t *
+hb_buffer_reference (hb_buffer_t *buffer);
 
-  hb_glyph_info_t     *in_string;
-  hb_glyph_info_t     *out_string;
-  hb_glyph_info_t     *alt_string;
-  hb_glyph_position_t *positions;
+unsigned int
+hb_buffer_get_reference_count (hb_buffer_t *buffer);
 
-  hb_direction_t       direction;
-  unsigned int         max_lig_id;
-} hb_buffer_t;
+void
+hb_buffer_destroy (hb_buffer_t *buffer);
 
-hb_buffer_t *
-hb_buffer_new (unsigned int allocation_size);
 
 void
-hb_buffer_free (hb_buffer_t *buffer);
+hb_buffer_set_direction (hb_buffer_t    *buffer,
+			 hb_direction_t  direction);
+
+hb_direction_t
+hb_buffer_get_direction (hb_buffer_t *buffer);
+
 
 void
 hb_buffer_clear (hb_buffer_t *buffer);
 
 void
+hb_buffer_clear_positions (hb_buffer_t *buffer);
+
+void
 hb_buffer_ensure (hb_buffer_t  *buffer,
 		  unsigned int  size);
 
+
 void
 hb_buffer_add_glyph (hb_buffer_t    *buffer,
 		     hb_codepoint_t  glyph_index,
 		     unsigned int    properties,
 		     unsigned int    cluster);
 
-void
-hb_buffer_set_direction (hb_buffer_t    *buffer,
-			 hb_direction_t  direction);
+
+/* Return value valid as long as buffer not modified */
+unsigned int
+hb_buffer_get_len (hb_buffer_t *buffer);
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_info_t *
+hb_buffer_get_glyph_infos (hb_buffer_t *buffer);
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_position_t *
+hb_buffer_get_glyph_positions (hb_buffer_t *buffer);
 
 
 HB_END_DECLS
diff --git a/pango/pango-ot-buffer.c b/pango/pango-ot-buffer.c
index cd65453..f42dc3e 100644
--- a/pango/pango-ot-buffer.c
+++ b/pango/pango-ot-buffer.c
@@ -36,14 +36,14 @@ acquire_buffer (gboolean *free_buffer)
   if (G_LIKELY (G_TRYLOCK (cached_buffer)))
     {
       if (G_UNLIKELY (!cached_buffer))
-	cached_buffer = hb_buffer_new (64);
+	cached_buffer = hb_buffer_create (64);
 
       buffer = cached_buffer;
       *free_buffer = FALSE;
     }
   else
     {
-      buffer = hb_buffer_new (32);
+      buffer = hb_buffer_create (32);
       *free_buffer = TRUE;
     }
 
@@ -53,13 +53,13 @@ acquire_buffer (gboolean *free_buffer)
 static void
 release_buffer (hb_buffer_t *buffer, gboolean free_buffer)
 {
-  if (G_LIKELY (!free_buffer))
+  if (G_LIKELY (!free_buffer) && hb_buffer_get_reference_count (buffer) == 1)
     {
       hb_buffer_clear (buffer);
       G_UNLOCK (cached_buffer);
     }
   else
-    hb_buffer_free (buffer);
+    hb_buffer_destroy (buffer);
 }
 
 /**
@@ -197,10 +197,10 @@ pango_ot_buffer_get_glyphs (const PangoOTBuffer  *buffer,
 			    int                  *n_glyphs)
 {
   if (glyphs)
-    *glyphs = (PangoOTGlyph *)buffer->buffer->in_string;
+    *glyphs = (PangoOTGlyph *) hb_buffer_get_glyph_infos (buffer->buffer);
 
   if (n_glyphs)
-    *n_glyphs = buffer->buffer->in_length;
+    *n_glyphs = hb_buffer_get_len (buffer->buffer);
 }
 
 static void
@@ -331,20 +331,26 @@ pango_ot_buffer_output (const PangoOTBuffer *buffer,
   unsigned int i;
   int last_cluster;
 
+  unsigned int len;
+  PangoOTGlyph *otglyphs;
+  hb_glyph_position_t *positions;
+
   face = pango_fc_font_lock_face (buffer->font);
   g_assert (face);
 
+  pango_ot_buffer_get_glyphs (buffer, &otglyphs, (int *) &len);
+
   /* Copy glyphs into output glyph string */
-  pango_glyph_string_set_size (glyphs, buffer->buffer->in_length);
+  pango_glyph_string_set_size (glyphs, len);
 
   last_cluster = -1;
-  for (i = 0; i < buffer->buffer->in_length; i++)
+  for (i = 0; i < len; i++)
     {
-      hb_glyph_info_t *ginfo = &buffer->buffer->in_string[i];
+      PangoOTGlyph *otglyph = &otglyphs[i];
 
-      glyphs->glyphs[i].glyph = ginfo->gindex;
+      glyphs->glyphs[i].glyph = otglyph->glyph;
 
-      glyphs->log_clusters[i] = ginfo->cluster;
+      glyphs->log_clusters[i] = otglyph->cluster;
       if (glyphs->log_clusters[i] != last_cluster)
 	glyphs->glyphs[i].attr.is_cluster_start = 1;
       else
@@ -386,12 +392,13 @@ pango_ot_buffer_output (const PangoOTBuffer *buffer,
       swap_range (glyphs, 0, glyphs->num_glyphs);
     }
 
+  positions = hb_buffer_get_glyph_positions (buffer->buffer);
   if (buffer->applied_gpos)
     {
       if (buffer->rtl)
-	apply_gpos_rtl (glyphs, buffer->buffer->positions, buffer->font->is_hinted);
+	apply_gpos_rtl (glyphs, positions, buffer->font->is_hinted);
       else
-	apply_gpos_ltr (glyphs, buffer->buffer->positions, buffer->font->is_hinted);
+	apply_gpos_ltr (glyphs, positions, buffer->font->is_hinted);
     }
   else
     {
diff --git a/pango/pango-ot-info.c b/pango/pango-ot-info.c
index 6b3a9be..f3c2fc3 100644
--- a/pango/pango-ot-info.c
+++ b/pango/pango-ot-info.c
@@ -555,8 +555,7 @@ _pango_ot_info_position    (const PangoOTInfo    *info,
 {
   unsigned int i;
 
-  /* XXX */
-  _hb_buffer_clear_positions (buffer->buffer);
+  hb_buffer_clear_positions (buffer->buffer);
 
   hb_ot_layout_set_scale (info->layout,
 			  info->face->size->metrics.x_scale,
@@ -603,17 +602,18 @@ _pango_ot_info_position    (const PangoOTInfo    *info,
     if (buffer->applied_gpos)
     {
       unsigned int i, j;
-      hb_glyph_position_t *positions = buffer->buffer->positions;
+      unsigned int len = hb_buffer_get_len (buffer->buffer);
+      hb_glyph_position_t *positions = hb_buffer_get_glyph_positions (buffer->buffer);
 
       /* First handle all left-to-right connections */
-      for (j = 0; j < buffer->buffer->in_length; j++)
+      for (j = 0; j < len; j++)
       {
 	if (positions[j].cursive_chain > 0)
 	  positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos;
       }
 
       /* Then handle all right-to-left connections */
-      for (i = buffer->buffer->in_length; i > 0; i--)
+      for (i = len; i > 0; i--)
       {
 	j = i - 1;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]