15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2009,2010 Red Hat, Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2010,2011,2012 Google, Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Red Hat Author(s): Behdad Esfahbod 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_SHAPER ot 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_ot_shaper_face_data_t hb_ot_layout_t 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-shaper-impl-private.hh" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-shape-private.hh" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-shape-complex-private.hh" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-shape-fallback-private.hh" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-shape-normalize-private.hh" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-layout-private.hh" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-set-private.hh" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static hb_tag_t common_features[] = { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('c','c','m','p'), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('l','i','g','a'), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('l','o','c','l'), 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('m','a','r','k'), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('m','k','m','k'), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('r','l','i','g'), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static hb_tag_t horizontal_features[] = { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('c','a','l','t'), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('c','l','i','g'), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('c','u','r','s'), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('k','e','r','n'), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('r','c','l','t'), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static hb_tag_t vertical_features[] = { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_TAG('v','e','r','t'), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_segment_properties_t *props, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *user_features, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_user_features) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_builder_t *map = &planner->map; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (props->direction) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_LTR: 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_global_bool_feature (HB_TAG ('l','t','r','a')); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_global_bool_feature (HB_TAG ('l','t','r','m')); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_RTL: 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_global_bool_feature (HB_TAG ('r','t','l','a')); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_TTB: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_BTT: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HB_DIRECTION_INVALID: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (planner->shaper->collect_features) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) planner->shaper->collect_features (planner); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_global_bool_feature (common_features[i]); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_feature (horizontal_features[i], 1, F_GLOBAL | 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (horizontal_features[i] == HB_TAG('k','e','r','n') ? 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) F_HAS_FALLBACK : F_NONE)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_feature (vertical_features[i], 1, F_GLOBAL | 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (vertical_features[i] == HB_TAG('v','k','r','n') ? 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) F_HAS_FALLBACK : F_NONE)); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (planner->shaper->override_features) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) planner->shaper->override_features (planner); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_user_features; i++) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *feature = &user_features[i]; 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->add_feature (feature->tag, feature->value, 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (feature->start == 0 && feature->end == (unsigned int) -1) ? 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) F_GLOBAL : F_NONE); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper face data 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_shaper_face_data_t * 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ot_shaper_face_data_create (hb_face_t *face) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return _hb_ot_layout_create (face); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_ot_layout_destroy (data); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper font data 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_ot_shaper_font_data_t {}; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_shaper_font_data_t * 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ot_shaper_font_data_create (hb_font_t *font) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper shape_plan data 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_shaper_shape_plan_data_t * 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *user_features, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_user_features) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!plan)) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_planner_t planner (shape_plan); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) planner.shaper = hb_ot_shape_complex_categorize (&planner); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) planner.compile (*plan); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plan->shaper->data_create) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plan->data = plan->shaper->data_create (plan); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!plan->data)) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return plan; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plan->shaper->data_destroy) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plan->shaper->data_destroy (const_cast<void *> (plan->data)); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plan->finish (); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free (plan); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_ot_shape_context_t 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_plan_t *plan; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_font_t *font; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_face_t *face; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_t *buffer; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *user_features; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_user_features; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Transient stuff */ 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_direction_t target_direction; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Main shaper */ 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Prepare */ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_set_unicode_props (hb_buffer_t *buffer) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = buffer->len; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_glyph_info_get_general_category (&buffer->info[0]) != 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_codepoint_t dottedcircle_glyph; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph)) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_info_t dottedcircle; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dottedcircle.codepoint = 0x25CC; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->clear_output (); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->idx = 0; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_info_t info = dottedcircle; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.cluster = buffer->cur().cluster; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.mask = buffer->cur().mask; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->output_info (info); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (buffer->idx < buffer->len) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->next_glyph (); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->swap_buffers (); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_form_clusters (hb_buffer_t *buffer) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = buffer->len; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < count; i++) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i]))) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->merge_clusters (i - 1, i + 1); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ensure_native_direction (hb_buffer_t *buffer) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_direction_t direction = buffer->props.direction; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO vertical: 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Ogham fonts are supposed to be implemented BTT or not. Need to research that 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * first. */ 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) || 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_reverse_clusters (buffer); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Substitute */ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_mirror_chars (hb_ot_shape_context_t *c) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_DIRECTION_IS_FORWARD (c->target_direction)) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_unicode_funcs_t *unicode = buffer->unicode; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m')); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int count = buffer->len; 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_info_t *info = buffer->info; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (likely (codepoint == info[i].codepoint)) 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) info[i].mask |= rtlm_mask; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) info[i].codepoint = codepoint; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_t *map = &c->plan->map; 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_mask_t global_mask = map->get_global_mask (); 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->reset_masks (global_mask); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c->plan->shaper->setup_masks) 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->plan->shaper->setup_masks (c->plan, buffer, c->font); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < c->num_user_features; i++) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *feature = &c->user_features[i]; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int shift; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_mask_t mask = map->get_mask (feature->tag, &shift); 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->set_masks (feature->value << shift, mask, feature->start, feature->end); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_map_glyphs_fast (hb_buffer_t *buffer) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Normalization process sets up glyph_index(), we just copy it. */ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = buffer->len; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->info[i].codepoint = buffer->info[i].glyph_index(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = c->buffer->len; 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_info_t *info = c->buffer->info; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_glyph_props (&info[i], 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_get_general_category (&info[i]) 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ? 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HB_OT_LAYOUT_GLYPH_PROPS_MARK : 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_substitute_default (hb_ot_shape_context_t *c) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c->plan->shaper->preprocess_text) 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->plan->shaper->preprocess_text (c->plan, buffer, c->font); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_mirror_chars (c); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_ot_shape_normalize (c->plan, buffer, c->font); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_setup_masks (c); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This is unfortunate to go here, but necessary... */ 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hb_ot_layout_has_positioning (c->face)) 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_ot_map_glyphs_fast (buffer); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_substitute_complex (hb_ot_shape_context_t *c) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_ot_layout_substitute_start (c->font, buffer); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hb_ot_layout_has_glyph_classes (c->face)) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_synthesize_glyph_classes (c); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->plan->substitute (c->font, buffer); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_ot_layout_substitute_finish (c->font, buffer); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_substitute (hb_ot_shape_context_t *c) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_substitute_default (c); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_substitute_complex (c); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Position */ 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)zero_mark_widths_by_unicode (hb_buffer_t *buffer) 4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles){ 4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) unsigned int count = buffer->len; 4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) 4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) buffer->pos[i].x_advance = 0; 4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) buffer->pos[i].y_advance = 0; 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static inline void 4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)zero_mark_widths_by_gdef (hb_buffer_t *buffer) 4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles){ 4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) unsigned int count = buffer->len; 4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (_hb_glyph_info_is_mark (&buffer->info[i])) 4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) buffer->pos[i].x_advance = 0; 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) buffer->pos[i].y_advance = 0; 4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static inline void 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_position_default (hb_ot_shape_context_t *c) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_direction_t direction = c->buffer->props.direction; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = c->buffer->len; 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_info_t *info = c->buffer->info; 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_position_t *pos = c->buffer->pos; 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->font->get_glyph_advance_for_direction (info[i].codepoint, 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) direction, 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].x_advance, 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].y_advance); 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->font->subtract_glyph_origin_for_direction (info[i].codepoint, 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) direction, 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].x_offset, 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].y_offset); 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static inline bool 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)hb_ot_position_complex (hb_ot_shape_context_t *c) 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool ret = false; 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int count = c->buffer->len; 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (c->plan->shaper->zero_width_marks) 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) zero_mark_widths_by_gdef (c->buffer); 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) /* Not currently used for any shaper: 4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: 4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) zero_mark_widths_by_unicode (c->buffer); 4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) */ 4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: 4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hb_ot_layout_has_positioning (c->face)) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_info_t *info = c->buffer->info; 477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_position_t *pos = c->buffer->pos; 478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->font->add_glyph_origin_for_direction (info[i].codepoint, 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_DIRECTION_LTR, 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].x_offset, 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].y_offset); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->plan->position (c->font, c->buffer); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) { 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->font->subtract_glyph_origin_for_direction (info[i].codepoint, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_DIRECTION_LTR, 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].x_offset, 494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &pos[i].y_offset); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = true; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (c->plan->shaper->zero_width_marks) 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: 5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) zero_mark_widths_by_unicode (c->buffer); 5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) zero_mark_widths_by_gdef (c->buffer); 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: 5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return ret; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_position (hb_ot_shape_context_t *c) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_ot_layout_position_start (c->font, c->buffer); 524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_position_default (c); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_bool_t fallback = !hb_ot_position_complex (c); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_ot_layout_position_finish (c->font, c->buffer); 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fallback && c->plan->shaper->fallback_position) 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_reverse (c->buffer); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Visual fallback goes here. */ 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fallback) 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Post-process */ 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_codepoint_t space; 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enum { 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SPACE_DONT_KNOW, 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SPACE_AVAILABLE, 556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SPACE_UNAVAILABLE 557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } space_status = SPACE_DONT_KNOW; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = c->buffer->len; 560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_info_t *info = c->buffer->info; 561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_glyph_position_t *pos = c->buffer->pos; 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int j = 0; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (unlikely (!_hb_glyph_info_ligated (&info[i]) && 566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_is_default_ignorable (&info[i]))) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (space_status == SPACE_DONT_KNOW) 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE; 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (space_status == SPACE_AVAILABLE) 572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) info[i].codepoint = space; 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pos[i].x_advance = 0; 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pos[i].y_advance = 0; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; /* Delete it. */ 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (j != i) 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) info[j] = info[i]; 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pos[j] = pos[i]; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) j++; 586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->buffer->len = j; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Pull it all together! */ 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_shape_internal (hb_ot_shape_context_t *c) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->buffer->deallocate_var_all (); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Save the original direction, we use it later. */ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->target_direction = c->buffer->props.direction; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_buffer_allocate_unicode_vars (c->buffer); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->buffer->clear_output (); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_set_unicode_props (c->buffer); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_insert_dotted_circle (c->buffer, c->font); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_form_clusters (c->buffer); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ensure_native_direction (c->buffer); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_substitute (c); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_position (c); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_ot_hide_default_ignorables (c); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_buffer_deallocate_unicode_vars (c->buffer); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->buffer->props.direction = c->target_direction; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->buffer->deallocate_var_all (); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_bool_t 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ot_shape (hb_shape_plan_t *shape_plan, 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_font_t *font, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_t *buffer, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *features, 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_features) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features}; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_internal (&c); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_tag_t table_tag, 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *lookup_indexes /* OUT */) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* XXX Does the first part always succeed? */ 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */ 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)add_char (hb_font_t *font, 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_unicode_funcs_t *unicode, 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_bool_t mirror, 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_codepoint_t u, 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_codepoint_t glyph; 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (font->get_glyph (u, 0, &glyph)) 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glyphs->add (glyph); 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mirror) 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_codepoint_t m = unicode->mirroring (u); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (m != u && font->get_glyph (m, 0, &glyph)) 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glyphs->add (glyph); 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_shape_glyphs_closure (hb_font_t *font, 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_t *buffer, 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *features, 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_features, 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_set_t *glyphs) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_shape_plan_t plan; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *shapers[] = {"ot", NULL}; 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) features, num_features, shapers); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = buffer->len; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs); 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t lookups; 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookups.init (); 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* And find transitive closure. */ 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_set_t copy; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy.init (); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy.set (glyphs); 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index);) 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } while (!copy.is_equal (glyphs)); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_shape_plan_destroy (shape_plan); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 702