hb-graphite2.cc revision e4992e13e19877a73ea05fc1d31005a262c685ad
11f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod/* 2a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod * Copyright © 2011 Martin Hosken 3a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod * Copyright © 2011 SIL International 4e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * Copyright © 2011,2012 Google, Inc. 51f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * 61f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 71f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * 81f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * Permission is hereby granted, without written agreement and without 91f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 101f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * software and its documentation for any purpose, provided that the 111f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 121f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * all copies of this software. 131f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * 141f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 151f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 161f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 171f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 181f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * DAMAGE. 191f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * 201f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 211f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 221f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 231f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 241f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod * 26a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod * Google Author(s): Behdad Esfahbod 271f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod */ 281f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 29e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod#define HB_SHAPER graphite2 30e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod#define hb_graphite2_shaper_font_data_t gr_font 31e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod#include "hb-shaper-impl-private.hh" 32e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 33e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod#include <graphite2/Font.h> 34e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod#include <graphite2/Segment.h> 35cd2b901027bd154e31aa509c0cb2d86633e36398Behdad Esfahbod 36cd2b901027bd154e31aa509c0cb2d86633e36398Behdad Esfahbod#include "hb-graphite2.h" 37cd2b901027bd154e31aa509c0cb2d86633e36398Behdad Esfahbod 381f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod#include "hb-ot-tag.h" 39cd2b901027bd154e31aa509c0cb2d86633e36398Behdad Esfahbod 401f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 41e4992e13e19877a73ea05fc1d31005a262c685adBehdad EsfahbodHB_SHAPER_DATA_ENSURE_DECLARE(graphite2, face) 42e4992e13e19877a73ea05fc1d31005a262c685adBehdad EsfahbodHB_SHAPER_DATA_ENSURE_DECLARE(graphite2, font) 431f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 441f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 45e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod/* 46e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * shaper face data 47e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod */ 481f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 49e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodtypedef struct hb_graphite2_tablelist_t { 50e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_blob_t *blob; 51e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod struct hb_graphite2_tablelist_t *next; 52a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int tag; 53e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} hb_graphite2_tablelist_t; 541f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 55e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodstruct hb_graphite2_shaper_face_data_t { 56e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_face_t *face; 57a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod gr_face *grface; 58e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_tablelist_t *tlist; 59e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod}; 601f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 61a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbodstatic const void *hb_gr_get_table (const void *data, unsigned int tag, size_t *len) 621f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 63e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_tablelist_t *pl = NULL, *p; 64e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_shaper_face_data_t *face = (hb_graphite2_shaper_face_data_t *) data; 65e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_tablelist_t *tlist = face->tlist; 66a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 67a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod for (p = tlist; p; p = p->next) 68a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (p->tag == tag ) { 69a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int tlen; 70a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod const char *d = hb_blob_get_data (p->blob, &tlen); 71a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod *len = tlen; 72a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod return d; 73a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } else 74a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pl = p; 75a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 76a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_blob_t *blob = hb_face_reference_table (face->face, tag); 77a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 78e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod /* TODO Not thread-safe. */ 79a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (!pl || pl->blob) 80a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 81e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod p = (hb_graphite2_tablelist_t *) calloc (1, sizeof (hb_graphite2_tablelist_t)); 82a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (!p) { 8381ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod hb_blob_destroy (blob); 84a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod return NULL; 85a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 86a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod p->next = NULL; 87a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (pl) 88a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pl->next = p; 89a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod else 90a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod face->tlist = p; 91a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pl = p; 92a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 93a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pl->blob = blob; 94a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pl->tag = tag; 95a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 96a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int tlen; 97a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod const char *d = hb_blob_get_data (blob, &tlen); 98a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod *len = tlen; 99a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod return d; 1001f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 1011f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 102e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodhb_graphite2_shaper_face_data_t * 103e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_face_data_create (hb_face_t *face) 1041f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 105e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_shaper_face_data_t *data = (hb_graphite2_shaper_face_data_t *) calloc (1, sizeof (hb_graphite2_shaper_face_data_t)); 106e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod if (unlikely (!data)) 107e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return NULL; 108e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 109e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_blob_t *silf_blob = hb_face_reference_table (face, HB_GRAPHITE2_TAG_SILF); 110e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod if (!hb_blob_get_length (silf_blob)) 111e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod { 112e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_blob_destroy (silf_blob); 113e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return NULL; 114e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod } 115e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 116e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod data->face = face; 117e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod data->grface = gr_make_face (data, &hb_gr_get_table, gr_face_default); 118e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 119e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return data; 1201f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 1211f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 122e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodvoid 123e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_face_data_destroy (hb_graphite2_shaper_face_data_t *data) 1241f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 125e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_tablelist_t *tlist = data->tlist; 126e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 127a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod while (tlist) 128a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 129e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_tablelist_t *old = tlist; 130a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_blob_destroy (tlist->blob); 131a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod tlist = tlist->next; 13281ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod free (old); 133a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 1341f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 135e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_face_destroy (data->grface); 1361f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 137e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod free (data); 1381f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 1391f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 140a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 141e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod/* 142e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * shaper font data 143e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod */ 144a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 145e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodstatic float hb_gr_get_advance (const void *hb_font, unsigned short gid) 146e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 147e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return ((hb_font_t *) hb_font)->get_glyph_h_advance (gid); 148e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 149a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 150e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodhb_graphite2_shaper_font_data_t * 151e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_font_data_create (hb_font_t *font) 152e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 153e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod if (unlikely (!hb_graphite2_shaper_face_data_ensure (font->face))) return NULL; 154a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 155e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_face_t *face = font->face; 156e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); 157a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 158e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return gr_make_font_with_advance_fn (font->x_scale, font, &hb_gr_get_advance, face_data->grface); 1591f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 1601f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 161e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodvoid 162e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_font_data_destroy (hb_graphite2_shaper_font_data_t *data) 1631f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 164e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_font_destroy (data); 165e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 166a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 167a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 168e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod/* 169e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * shaper shape_plan data 170e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod */ 171a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 172e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodstruct hb_graphite2_shaper_shape_plan_data_t {}; 173a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 174e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodhb_graphite2_shaper_shape_plan_data_t * 175e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, 176e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod const hb_feature_t *user_features, 177e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int num_user_features) 178e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 179e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return (hb_graphite2_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; 180e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 181a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 182e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodvoid 183e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shaper_shape_plan_data_t *data) 184e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 185e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 186a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 187a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 188e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod/* 189e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * shaper 190e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod */ 1911f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 192e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodstruct hb_graphite2_cluster_t { 193e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int base_char; 194e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int num_chars; 195e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int base_glyph; 196e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int num_glyphs; 197e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod}; 1981f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 199a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbodhb_bool_t 200e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shape (hb_shape_plan_t *shape_plan, 201e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_font_t *font, 202e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_buffer_t *buffer, 203e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod const hb_feature_t *features, 204e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int num_features) 2051f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 206e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_face_t *face = font->face; 207e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_face *grface = HB_SHAPER_DATA_GET (face)->grface; 208e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_font *grfont = HB_SHAPER_DATA_GET (font); 209a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 210a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int charlen; 211a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_glyph_info_t *bufferi = hb_buffer_get_glyph_infos (buffer, &charlen); 212a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 213a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod int success = 0; 214a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 215a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod const char *lang = hb_language_to_string (hb_buffer_get_language (buffer)); 216290e3ee51727df75d136ccfff79831b94d1583b6Behdad Esfahbod const char *lang_end = strchr (lang, '-'); 217290e3ee51727df75d136ccfff79831b94d1583b6Behdad Esfahbod int lang_len = lang_end ? lang_end - lang : -1; 218e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_feature_val *feats = gr_face_featureval_for_lang (grface, lang ? hb_tag_from_string (lang, lang_len) : 0); 219a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 220a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod while (num_features--) 221a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 222e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod const gr_feature_ref *fref = gr_face_find_fref (grface, features->tag); 223a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (fref) 224a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod gr_fref_set_feature_value (fref, features->value, feats); 225a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod features++; 226a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 227a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 2288e3715f8a16b315c1c7dd4b256e7f68a36c53e7cBehdad Esfahbod hb_codepoint_t *gids = NULL, *pg; 229e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_cluster_t *clusters = NULL; 230a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod gr_segment *seg = NULL; 231a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod uint32_t *text = NULL; 232a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod const gr_slot *is; 233a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int ci = 0, ic = 0; 234a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod float curradvx = 0., curradvy = 0.; 235a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int glyphlen = 0; 236a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int *p; 237a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 238a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod text = (uint32_t *) malloc ((charlen + 1) * sizeof (uint32_t)); 239a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (!text) goto dieout; 240a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 241a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod p = text; 242a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod for (unsigned int i = 0; i < charlen; ++i) 243a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod *p++ = bufferi++->codepoint; 244a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod *p = 0; 245a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 246a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_tag_t script_tag[2]; 24781ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]); 248a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 249e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod seg = gr_make_seg (grfont, grface, 250a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1], 251a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod feats, 252a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod gr_utf32, text, charlen, 25381ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod 2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0)); 254a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (!seg) goto dieout; 255a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 256a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod glyphlen = gr_seg_n_slots (seg); 257e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod clusters = (hb_graphite2_cluster_t *) calloc (charlen, sizeof (hb_graphite2_cluster_t)); 258a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (!glyphlen || !clusters) goto dieout; 259a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 2608e3715f8a16b315c1c7dd4b256e7f68a36c53e7cBehdad Esfahbod gids = (hb_codepoint_t *) malloc (glyphlen * sizeof (hb_codepoint_t)); 261a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (!gids) goto dieout; 262a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 263a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pg = gids; 264a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++) 265a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 266a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int before = gr_slot_before (is); 267a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int after = gr_slot_after (is); 268a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod *pg = gr_slot_gid (is); 269a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pg++; 270a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod while (clusters[ci].base_char > before && ci) 2711f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod { 272a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod clusters[ci-1].num_chars += clusters[ci].num_chars; 273a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod clusters[ci-1].num_glyphs += clusters[ci].num_glyphs; 274a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod ci--; 2751f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod } 2761f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 277a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (gr_slot_can_insert_before (is) && clusters[ci].num_chars && before >= clusters[ci].base_char + clusters[ci].num_chars) 2781f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod { 279e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_cluster_t *c = clusters + ci + 1; 280a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->base_char = clusters[ci].base_char + clusters[ci].num_chars; 281a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->num_chars = before - c->base_char; 282a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->base_glyph = ic; 283a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->num_glyphs = 0; 284a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod ci++; 2851f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod } 286a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod clusters[ci].num_glyphs++; 287a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 288a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (clusters[ci].base_char + clusters[ci].num_chars < after + 1) 289a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod clusters[ci].num_chars = after + 1 - clusters[ci].base_char; 290a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 291a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod ci++; 292a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 29381ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod buffer->clear_output (); 294a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod for (unsigned int i = 0; i < ci; ++i) 2953380de5abbaff535e1cf57ea7e5c2a7c4fdcfe66Behdad Esfahbod buffer->replace_glyphs (clusters[i].num_chars, clusters[i].num_glyphs, gids + clusters[i].base_glyph); 29681ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod buffer->swap_buffers (); 297a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 298a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_glyph_position_t *pPos; 29981ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod for (pPos = hb_buffer_get_glyph_positions (buffer, NULL), is = gr_seg_first_slot (seg); 30081ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod is; pPos++, is = gr_slot_next_in_segment (is)) 301a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 302a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pPos->x_offset = gr_slot_origin_X(is) - curradvx; 303a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pPos->y_offset = gr_slot_origin_Y(is) - curradvy; 304e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod pPos->x_advance = gr_slot_advance_X(is, grface, grfont); 305e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod pPos->y_advance = gr_slot_advance_Y(is, grface, grfont); 306a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod// if (pPos->x_advance < 0 && gr_slot_attached_to(is)) 307a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod// pPos->x_advance = 0; 308a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod curradvx += pPos->x_advance; 309a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod curradvy += pPos->y_advance; 310a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 311a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pPos[-1].x_advance += gr_seg_advance_X(seg) - curradvx; 312f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod 313f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod /* TODO(behdad): 314f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod * This shaper is badly broken with RTL text. It returns glyphs 315f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod * in the logical order! 316f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod */ 317f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod// if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 318f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod// hb_buffer_reverse (buffer); 319f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod 320a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod success = 1; 3211f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 3221f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahboddieout: 323a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (gids) free (gids); 324a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (clusters) free (clusters); 325a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (seg) gr_seg_destroy (seg); 326a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (text) free (text); 327a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod return success; 3281f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 329