hb_blob_destroy (silf_blob);
data->face = face;
- data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_default);
+ data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll);
if (unlikely (!data->grface)) {
free (data);
free (data);
}
+gr_face *
+hb_graphite2_face_get_gr_face (hb_face_t *face)
+{
+ if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return NULL;
+ return HB_SHAPER_DATA_GET (face)->grface;
+}
+
/*
* shaper font data
gr_font_destroy (data);
}
+gr_font *
+hb_graphite2_font_get_gr_font (hb_font_t *font)
+{
+ if (unlikely (!hb_graphite2_shaper_font_data_ensure (font))) return NULL;
+ return HB_SHAPER_DATA_GET (font);
+}
+
/*
* shaper shape_plan data
gr_face *grface = HB_SHAPER_DATA_GET (face)->grface;
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_end = strchr (lang, '-');
int lang_len = lang_end ? lang_end - lang : -1;
features++;
}
- /* TODO Use scratch buffer for these. */
- hb_codepoint_t *gids = NULL, *pg;
- hb_graphite2_cluster_t *clusters = NULL;
gr_segment *seg = NULL;
- uint32_t *text = NULL;
const gr_slot *is;
unsigned int ci = 0, ic = 0;
float curradvx = 0., curradvy = 0.;
- unsigned int glyphlen = 0;
- unsigned int *p;
- text = (uint32_t *) malloc ((charlen + 1) * sizeof (uint32_t));
- if (!text) goto dieout;
+ unsigned int scratch_size;
+ char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+
+#define ALLOCATE_ARRAY(Type, name, len) \
+ Type *name = (Type *) scratch; \
+ scratch += (len) * sizeof ((name)[0]); \
+ scratch_size -= (len) * sizeof ((name)[0]);
- p = text;
- for (unsigned int i = 0; i < charlen; ++i)
- *p++ = bufferi++->codepoint;
- *p = 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_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]);
seg = gr_make_seg (grfont, grface,
script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1],
feats,
- gr_utf32, text, charlen,
+ gr_utf32, chars, buffer->len,
2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0));
- if (!seg) goto dieout;
- glyphlen = gr_seg_n_slots (seg);
- clusters = (hb_graphite2_cluster_t *) calloc (charlen, sizeof (hb_graphite2_cluster_t));
- if (!glyphlen || !clusters) goto dieout;
+ if (unlikely (!seg)) {
+ if (feats) gr_featureval_destroy (feats);
+ return false;
+ }
+
+ unsigned int glyph_count = gr_seg_n_slots (seg);
+ if (unlikely (!glyph_count)) {
+ if (feats) gr_featureval_destroy (feats);
+ gr_seg_destroy (seg);
+ return false;
+ }
+
+ 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);
- gids = (hb_codepoint_t *) malloc (glyphlen * sizeof (hb_codepoint_t));
- if (!gids) goto dieout;
+ memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
- pg = gids;
+ hb_codepoint_t *pg = gids;
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);
}
ci++;
- buffer->clear_output ();
+ //buffer->clear_output ();
for (unsigned int i = 0; i < ci; ++i)
- buffer->replace_glyphs (clusters[i].num_chars, clusters[i].num_glyphs, gids + clusters[i].base_glyph);
- buffer->swap_buffers ();
+ {
+ for (unsigned int j = 0; j < clusters[i].num_glyphs; ++j)
+ {
+ hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j];
+ info->codepoint = gids[clusters[i].base_glyph + j];
+ info->cluster = gr_cinfo_base(gr_seg_cinfo(seg, clusters[i].base_char));
+ }
+ }
+ buffer->len = glyph_count;
+ //buffer->swap_buffers ();
if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
curradvx = gr_seg_advance_X(seg);
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
hb_buffer_reverse_clusters (buffer);
- success = 1;
-
-dieout:
if (feats) gr_featureval_destroy (feats);
- if (gids) free (gids);
- if (clusters) free (clusters);
- if (seg) gr_seg_destroy (seg);
- if (text) free (text);
- return success;
+ gr_seg_destroy (seg);
+
+ return true;
}