[graphite2] Cleanup scratch buffer allocation

This commit is contained in:
Behdad Esfahbod 2012-08-24 00:41:51 -04:00
parent 2f7586c622
commit 56e878ab87

View File

@ -211,11 +211,6 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
gr_face *grface = HB_SHAPER_DATA_GET (face)->grface; gr_face *grface = HB_SHAPER_DATA_GET (face)->grface;
gr_font *grfont = HB_SHAPER_DATA_GET (font); gr_font *grfont = HB_SHAPER_DATA_GET (font);
unsigned int charlen;
hb_glyph_info_t *bufferi = hb_buffer_get_glyph_infos (buffer, &charlen);
int success = 0;
const char *lang = hb_language_to_string (hb_buffer_get_language (buffer)); const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
const char *lang_end = strchr (lang, '-'); const char *lang_end = strchr (lang, '-');
int lang_len = lang_end ? lang_end - lang : -1; int lang_len = lang_end ? lang_end - lang : -1;
@ -229,24 +224,23 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
features++; features++;
} }
/* TODO Use scratch buffer for these. */
hb_codepoint_t *gids = NULL, *pg;
hb_graphite2_cluster_t *clusters = NULL;
gr_segment *seg = NULL; gr_segment *seg = NULL;
uint32_t *text = NULL;
const gr_slot *is; const gr_slot *is;
unsigned int ci = 0, ic = 0; unsigned int ci = 0, ic = 0;
float curradvx = 0., curradvy = 0.; float curradvx = 0., curradvy = 0.;
unsigned int glyphlen = 0;
unsigned int *p;
text = (uint32_t *) malloc ((charlen + 1) * sizeof (uint32_t)); unsigned int scratch_size;
if (!text) goto dieout; char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
p = text; #define ALLOCATE_ARRAY(Type, name, len) \
for (unsigned int i = 0; i < charlen; ++i) Type *name = (Type *) scratch; \
*p++ = bufferi++->codepoint; scratch += (len) * sizeof ((name)[0]); \
*p = 0; scratch_size -= (len) * sizeof ((name)[0]);
ALLOCATE_ARRAY (uint32_t, chars, buffer->len);
for (unsigned int i = 0; i < buffer->len; ++i)
chars[i] = buffer->info[i].codepoint;
hb_tag_t script_tag[2]; hb_tag_t script_tag[2];
hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]); hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]);
@ -254,18 +248,40 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
seg = gr_make_seg (grfont, grface, seg = gr_make_seg (grfont, grface,
script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1], script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1],
feats, feats,
gr_utf32, text, charlen, gr_utf32, chars, buffer->len,
2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0)); 2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0));
if (!seg) goto dieout;
glyphlen = gr_seg_n_slots (seg); if (unlikely (!seg)) {
clusters = (hb_graphite2_cluster_t *) calloc (charlen, sizeof (hb_graphite2_cluster_t)); if (feats) gr_featureval_destroy (feats);
if (!glyphlen || !clusters) goto dieout; return false;
}
gids = (hb_codepoint_t *) malloc (glyphlen * sizeof (hb_codepoint_t)); unsigned int glyph_count = gr_seg_n_slots (seg);
if (!gids) goto dieout; if (unlikely (!glyph_count)) {
if (feats) gr_featureval_destroy (feats);
gr_seg_destroy (seg);
return false;
}
pg = gids; scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
while ((sizeof (hb_graphite2_cluster_t) * buffer->len +
sizeof (hb_codepoint_t) * glyph_count) > scratch_size)
{
buffer->ensure (buffer->allocated * 2);
if (unlikely (buffer->in_error)) {
if (feats) gr_featureval_destroy (feats);
gr_seg_destroy (seg);
return false;
}
scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
}
ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);
memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
hb_codepoint_t *pg = gids;
for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++) for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
{ {
unsigned int before = gr_slot_before (is); unsigned int before = gr_slot_before (is);
@ -325,13 +341,8 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
hb_buffer_reverse_clusters (buffer); hb_buffer_reverse_clusters (buffer);
success = 1;
dieout:
if (feats) gr_featureval_destroy (feats); if (feats) gr_featureval_destroy (feats);
if (gids) free (gids); gr_seg_destroy (seg);
if (clusters) free (clusters);
if (seg) gr_seg_destroy (seg); return true;
if (text) free (text);
return success;
} }