hb-graphite2.cc revision a5a4ab3846ef06769784e6469d76eace35e68805
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 struct hb_graphite2_tablelist_t *next; 5132d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod hb_blob_t *blob; 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 6132d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbodstatic const void *hb_graphite2_get_table (const void *data, unsigned int tag, size_t *len) 621f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 6332d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod hb_graphite2_shaper_face_data_t *face_data = (hb_graphite2_shaper_face_data_t *) data; 6432d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod hb_graphite2_tablelist_t *tlist = face_data->tlist; 6532d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod 6632d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod hb_blob_t *blob = NULL; 6732d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod 6832d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod for (hb_graphite2_tablelist_t *p = tlist; p; p = p->next) 6932d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod if (p->tag == tag) { 7032d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod blob = p->blob; 7132d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod break; 7232d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod } 7332d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod 7432d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod if (unlikely (!blob)) 75a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 764c8ac4f47e95d2b266b2f64e75c55af8233b6b91Behdad Esfahbod blob = face_data->face->reference_table (tag); 7732d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod 7832d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod hb_graphite2_tablelist_t *p = (hb_graphite2_tablelist_t *) calloc (1, sizeof (hb_graphite2_tablelist_t)); 7932d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod if (unlikely (!p)) { 8081ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod hb_blob_destroy (blob); 81a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod return NULL; 82a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 8332d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod p->blob = blob; 8432d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod p->tag = tag; 8532d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod 8632d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod /* TODO Not thread-safe, but fairly harmless. 8732d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod * We can do the double-chcked pointer cmpexch thing here. */ 8832d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod p->next = face_data->tlist; 8932d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod face_data->tlist = p; 90a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 91a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 92a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int tlen; 93a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod const char *d = hb_blob_get_data (blob, &tlen); 94a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod *len = tlen; 95a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod return d; 961f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 971f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 98e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodhb_graphite2_shaper_face_data_t * 99e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_face_data_create (hb_face_t *face) 1001f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 1014c8ac4f47e95d2b266b2f64e75c55af8233b6b91Behdad Esfahbod hb_blob_t *silf_blob = face->reference_table (HB_GRAPHITE2_TAG_SILF); 102ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod /* Umm, we just reference the table to check whether it exists. 103ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod * Maybe add better API for this? */ 104e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod if (!hb_blob_get_length (silf_blob)) 105e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod { 106e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_blob_destroy (silf_blob); 107e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return NULL; 108e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod } 109ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod hb_blob_destroy (silf_blob); 110ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod 111ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod hb_graphite2_shaper_face_data_t *data = (hb_graphite2_shaper_face_data_t *) calloc (1, sizeof (hb_graphite2_shaper_face_data_t)); 112ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod if (unlikely (!data)) 113ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod hb_blob_destroy (silf_blob); 114e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 115e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod data->face = face; 116737ba156442f723d126c7c58c73729786b67c17aBehdad Esfahbod data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll); 117e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 118ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod if (unlikely (!data->grface)) { 119ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod free (data); 120ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod return NULL; 121ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod } 122ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod 123e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return data; 1241f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 1251f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 126e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodvoid 127e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_face_data_destroy (hb_graphite2_shaper_face_data_t *data) 1281f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 129e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_tablelist_t *tlist = data->tlist; 130e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod 131a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod while (tlist) 132a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 133e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_tablelist_t *old = tlist; 134a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_blob_destroy (tlist->blob); 135a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod tlist = tlist->next; 13681ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod free (old); 137a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 1381f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 139e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_face_destroy (data->grface); 1401f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 141e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod free (data); 1421f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 1431f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 144a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbodgr_face * 145a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbodhb_graphite2_face_get_gr_face (hb_face_t *face) 146a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod{ 147a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return NULL; 148a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod return HB_SHAPER_DATA_GET (face)->grface; 149a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod} 150a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod 151a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 152e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod/* 153e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * shaper font data 154e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod */ 155a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 15632d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbodstatic float hb_graphite2_get_advance (const void *hb_font, unsigned short gid) 157e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 158e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return ((hb_font_t *) hb_font)->get_glyph_h_advance (gid); 159e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 160a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 161e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodhb_graphite2_shaper_font_data_t * 162e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_font_data_create (hb_font_t *font) 163e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 164e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod if (unlikely (!hb_graphite2_shaper_face_data_ensure (font->face))) return NULL; 165a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 166e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_face_t *face = font->face; 167e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); 168a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 16932d71dc13317b322e2c5de00d767b2cb15fddd8bBehdad Esfahbod return gr_make_font_with_advance_fn (font->x_scale, font, &hb_graphite2_get_advance, face_data->grface); 1701f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 1711f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 172e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodvoid 173e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shaper_font_data_destroy (hb_graphite2_shaper_font_data_t *data) 1741f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 175e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_font_destroy (data); 176e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 177a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 178a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbodgr_font * 179a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbodhb_graphite2_font_get_gr_font (hb_font_t *font) 180a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod{ 181a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod if (unlikely (!hb_graphite2_shaper_font_data_ensure (font))) return NULL; 182a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod return HB_SHAPER_DATA_GET (font); 183a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod} 184a5a4ab3846ef06769784e6469d76eace35e68805Behdad Esfahbod 185a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 186e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod/* 187e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * shaper shape_plan data 188e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod */ 189a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 190e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodstruct hb_graphite2_shaper_shape_plan_data_t {}; 191a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 192e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodhb_graphite2_shaper_shape_plan_data_t * 19345c1383cc7315f89c23c0ed388b99e87224884e7Behdad Esfahbod_hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, 19445c1383cc7315f89c23c0ed388b99e87224884e7Behdad Esfahbod const hb_feature_t *user_features HB_UNUSED, 19545c1383cc7315f89c23c0ed388b99e87224884e7Behdad Esfahbod unsigned int num_user_features HB_UNUSED) 196e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 197e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod return (hb_graphite2_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; 198e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 199a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 200e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodvoid 20145c1383cc7315f89c23c0ed388b99e87224884e7Behdad Esfahbod_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shaper_shape_plan_data_t *data HB_UNUSED) 202e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod{ 203e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod} 204a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 205a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 206e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod/* 207e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod * shaper 208e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod */ 2091f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 210e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbodstruct hb_graphite2_cluster_t { 211e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int base_char; 212e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int num_chars; 213e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int base_glyph; 214e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int num_glyphs; 215e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod}; 2161f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 217a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbodhb_bool_t 218e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod_hb_graphite2_shape (hb_shape_plan_t *shape_plan, 219e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_font_t *font, 220e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_buffer_t *buffer, 221e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod const hb_feature_t *features, 222e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod unsigned int num_features) 2231f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod{ 224e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_face_t *face = font->face; 225e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_face *grface = HB_SHAPER_DATA_GET (face)->grface; 226e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_font *grfont = HB_SHAPER_DATA_GET (font); 227a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 228a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod const char *lang = hb_language_to_string (hb_buffer_get_language (buffer)); 229290e3ee51727df75d136ccfff79831b94d1583b6Behdad Esfahbod const char *lang_end = strchr (lang, '-'); 230290e3ee51727df75d136ccfff79831b94d1583b6Behdad Esfahbod int lang_len = lang_end ? lang_end - lang : -1; 231e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod gr_feature_val *feats = gr_face_featureval_for_lang (grface, lang ? hb_tag_from_string (lang, lang_len) : 0); 232a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 233a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod while (num_features--) 234a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 235e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod const gr_feature_ref *fref = gr_face_find_fref (grface, features->tag); 236a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (fref) 237a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod gr_fref_set_feature_value (fref, features->value, feats); 238a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod features++; 239a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 240a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 241a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod gr_segment *seg = NULL; 242a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod const gr_slot *is; 243a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int ci = 0, ic = 0; 244a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod float curradvx = 0., curradvy = 0.; 245a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 24656e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod unsigned int scratch_size; 24756e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); 24856e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod 24956e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod#define ALLOCATE_ARRAY(Type, name, len) \ 25056e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod Type *name = (Type *) scratch; \ 25156e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod scratch += (len) * sizeof ((name)[0]); \ 25256e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod scratch_size -= (len) * sizeof ((name)[0]); 25356e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod 25456e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod ALLOCATE_ARRAY (uint32_t, chars, buffer->len); 255a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 25656e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod for (unsigned int i = 0; i < buffer->len; ++i) 25756e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod chars[i] = buffer->info[i].codepoint; 258a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 259a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_tag_t script_tag[2]; 26081ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]); 261a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 262e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod seg = gr_make_seg (grfont, grface, 263a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1], 264a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod feats, 26556e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod gr_utf32, chars, buffer->len, 26681ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod 2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0)); 267a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 26856e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod if (unlikely (!seg)) { 26956e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod if (feats) gr_featureval_destroy (feats); 27056e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod return false; 27156e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod } 27256e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod 27356e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod unsigned int glyph_count = gr_seg_n_slots (seg); 27456e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod if (unlikely (!glyph_count)) { 27556e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod if (feats) gr_featureval_destroy (feats); 27656e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod gr_seg_destroy (seg); 27756e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod return false; 27856e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod } 27956e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod 28056e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod scratch = (char *) buffer->get_scratch_buffer (&scratch_size); 28156e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod while ((sizeof (hb_graphite2_cluster_t) * buffer->len + 28256e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod sizeof (hb_codepoint_t) * glyph_count) > scratch_size) 28356e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod { 28456e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod buffer->ensure (buffer->allocated * 2); 28556e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod if (unlikely (buffer->in_error)) { 28656e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod if (feats) gr_featureval_destroy (feats); 28756e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod gr_seg_destroy (seg); 28856e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod return false; 28956e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod } 29056e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod scratch = (char *) buffer->get_scratch_buffer (&scratch_size); 29156e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod } 292a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 29356e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len); 29456e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count); 295a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 29656e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod memset (clusters, 0, sizeof (clusters[0]) * buffer->len); 29756e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod 29856e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod hb_codepoint_t *pg = gids; 299a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++) 300a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 301a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int before = gr_slot_before (is); 302a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod unsigned int after = gr_slot_after (is); 303a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod *pg = gr_slot_gid (is); 304a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod pg++; 305a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod while (clusters[ci].base_char > before && ci) 3061f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod { 307a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod clusters[ci-1].num_chars += clusters[ci].num_chars; 308a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod clusters[ci-1].num_glyphs += clusters[ci].num_glyphs; 309a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod ci--; 3101f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod } 3111f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod 312a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (gr_slot_can_insert_before (is) && clusters[ci].num_chars && before >= clusters[ci].base_char + clusters[ci].num_chars) 3131f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod { 314e4992e13e19877a73ea05fc1d31005a262c685adBehdad Esfahbod hb_graphite2_cluster_t *c = clusters + ci + 1; 315a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->base_char = clusters[ci].base_char + clusters[ci].num_chars; 316a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->num_chars = before - c->base_char; 317a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->base_glyph = ic; 318a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod c->num_glyphs = 0; 319a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod ci++; 3201f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod } 321a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod clusters[ci].num_glyphs++; 322a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 323a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod if (clusters[ci].base_char + clusters[ci].num_chars < after + 1) 324a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod clusters[ci].num_chars = after + 1 - clusters[ci].base_char; 325a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 326a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod ci++; 327a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 32881ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod buffer->clear_output (); 329a5edb1031c204464da4f852ba3d90e8cc20cd20eBehdad Esfahbod for (unsigned int i = 0; i < ci; ++i) 3303380de5abbaff535e1cf57ea7e5c2a7c4fdcfe66Behdad Esfahbod buffer->replace_glyphs (clusters[i].num_chars, clusters[i].num_glyphs, gids + clusters[i].base_glyph); 33181ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod buffer->swap_buffers (); 332a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 3332fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) 3342fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod curradvx = gr_seg_advance_X(seg); 3352fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod 336a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod hb_glyph_position_t *pPos; 33781ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod for (pPos = hb_buffer_get_glyph_positions (buffer, NULL), is = gr_seg_first_slot (seg); 33881ec289da799bd2f50da9382507c606d2c779ab9Behdad Esfahbod is; pPos++, is = gr_slot_next_in_segment (is)) 339a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod { 3402fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod pPos->x_offset = gr_slot_origin_X (is) - curradvx; 3412fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod pPos->y_offset = gr_slot_origin_Y (is) - curradvy; 3422fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod pPos->x_advance = gr_slot_advance_X (is, grface, grfont); 3432fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod pPos->y_advance = gr_slot_advance_Y (is, grface, grfont); 3442fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 3452fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod curradvx -= pPos->x_advance; 3462fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod pPos->x_offset = gr_slot_origin_X (is) - curradvx; 3472fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod if (!HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 3482fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod curradvx += pPos->x_advance; 3492fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod pPos->y_offset = gr_slot_origin_Y (is) - curradvy; 350a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod curradvy += pPos->y_advance; 351a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod } 3522fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod if (!HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 3532fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod pPos[-1].x_advance += gr_seg_advance_X(seg) - curradvx; 3542fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod 3552fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 3562fef993460dcfd94c92ab35413bdde18ad2b0cebBehdad Esfahbod hb_buffer_reverse_clusters (buffer); 357f83f0f4836691b04306c2ef80979f2e1d76a2f28Behdad Esfahbod 358ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod if (feats) gr_featureval_destroy (feats); 35956e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod gr_seg_destroy (seg); 36056e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod 36156e878ab875ff06d74702145e380e198be967bd6Behdad Esfahbod return true; 3621f49cf32c96cb45a4d8ba2c210aeb7a8076b4762Behdad Esfahbod} 363