hb-ot-layout.cc revision b9d3f60520c022dc952e65a66eb138d1f7cae2e1
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Copyright © 1998-2004 David Turner and Werner Lemberg 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Copyright © 2006 Behdad Esfahbod 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Copyright © 2007,2008,2009 Red Hat, Inc. 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Copyright © 2012,2013 Google, Inc. 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * This is part of HarfBuzz, a text shaping library. 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Permission is hereby granted, without written agreement and without 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * license or royalty fees, to use, copy, modify, and distribute this 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * software and its documentation for any purpose, provided that the 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * above copyright notice and the following two paragraphs appear in 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * all copies of this software. 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * DAMAGE. 207e41fe84a841d7b9d7b36b245b65e9dcb3314943cristy * 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Red Hat Author(s): Behdad Esfahbod 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Google Author(s): Behdad Esfahbod 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "hb-ot-layout-private.hh" 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "hb-ot-layout-gdef-table.hh" 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "hb-ot-layout-gsub-table.hh" 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "hb-ot-layout-gpos-table.hh" 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "hb-ot-layout-jstf-table.hh" 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "hb-ot-map-private.hh" 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdlib.h> 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <string.h> 423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 443ed852eea50f9d4cd633efb8c2b054b8e33c253cristyHB_SHAPER_DATA_ENSURE_DECLARE(ot, face) 453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 463ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_t * 473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy_hb_ot_layout_create (hb_face_t *face) 483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t)); 503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unlikely (!layout)) 513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return NULL; 523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF)); 543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob); 553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB)); 573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob); 583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS)); 603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob); 613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gsub_lookup_count = layout->gsub->get_lookup_count (); 633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gpos_lookup_count = layout->gpos->get_lookup_count (); 643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); 663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); 673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) || 693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (layout->gpos_lookup_count && !layout->gpos_accels))) 703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_destroy (layout); 723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return NULL; 733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) 763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gsub_accels[i].init (layout->gsub->get_lookup (i)); 773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) 783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gpos_accels[i].init (layout->gpos->get_lookup (i)); 793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return layout; 813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 833ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy_hb_ot_layout_destroy (hb_ot_layout_t *layout) 853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) 873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy layout->gsub_accels[i].fini (); 88a20c904a6f3e3a11939d5260485be72d5c849c63cristy for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) 89a20c904a6f3e3a11939d5260485be72d5c849c63cristy layout->gpos_accels[i].fini (); 90b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free (layout->gsub_accels); 923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free (layout->gpos_accels); 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_blob_destroy (layout->gdef_blob); 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_blob_destroy (layout->gsub_blob); 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_blob_destroy (layout->gpos_blob); 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy free (layout); 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline const OT::GDEF& 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy_get_gdef (hb_face_t *face) 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 104b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF); 105a20c904a6f3e3a11939d5260485be72d5c849c63cristy return *hb_ot_layout_from_face (face)->gdef; 106a20c904a6f3e3a11939d5260485be72d5c849c63cristy} 107a20c904a6f3e3a11939d5260485be72d5c849c63cristystatic inline const OT::GSUB& 108a20c904a6f3e3a11939d5260485be72d5c849c63cristy_get_gsub (hb_face_t *face) 109a20c904a6f3e3a11939d5260485be72d5c849c63cristy{ 110b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB); 111a20c904a6f3e3a11939d5260485be72d5c849c63cristy return *hb_ot_layout_from_face (face)->gsub; 112a20c904a6f3e3a11939d5260485be72d5c849c63cristy} 113b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristystatic inline const OT::GPOS& 114a20c904a6f3e3a11939d5260485be72d5c849c63cristy_get_gpos (hb_face_t *face) 115b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 116a20c904a6f3e3a11939d5260485be72d5c849c63cristy if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS); 117a20c904a6f3e3a11939d5260485be72d5c849c63cristy return *hb_ot_layout_from_face (face)->gpos; 118b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 119a20c904a6f3e3a11939d5260485be72d5c849c63cristy 120a20c904a6f3e3a11939d5260485be72d5c849c63cristy 121b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy/* 122b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy * GDEF 123a20c904a6f3e3a11939d5260485be72d5c849c63cristy */ 124b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 125b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_bool_t 126a20c904a6f3e3a11939d5260485be72d5c849c63cristyhb_ot_layout_has_glyph_classes (hb_face_t *face) 127b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 128b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return _get_gdef (face).has_glyph_classes (); 129b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 130b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 131b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_glyph_class_t 132b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_get_glyph_class (hb_face_t *face, 133b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_codepoint_t glyph) 134b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 135b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); 136b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 137b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 138b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyvoid 139b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_get_glyphs_in_class (hb_face_t *face, 140b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_ot_layout_glyph_class_t klass, 141b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_set_t *glyphs /* OUT */) 142b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 143b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return _get_gdef (face).get_glyphs_in_class (klass, glyphs); 144b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 145b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 146b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyunsigned int 147b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_get_attach_points (hb_face_t *face, 148b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_codepoint_t glyph, 149b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int start_offset, 150b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *point_count /* IN/OUT */, 151b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *point_array /* OUT */) 152b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 153b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array); 154b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 155b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 156b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyunsigned int 157b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_get_ligature_carets (hb_font_t *font, 158b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_direction_t direction, 159a20c904a6f3e3a11939d5260485be72d5c849c63cristy hb_codepoint_t glyph, 160a20c904a6f3e3a11939d5260485be72d5c849c63cristy unsigned int start_offset, 161a20c904a6f3e3a11939d5260485be72d5c849c63cristy unsigned int *caret_count /* IN/OUT */, 162a20c904a6f3e3a11939d5260485be72d5c849c63cristy int *caret_array /* OUT */) 163a20c904a6f3e3a11939d5260485be72d5c849c63cristy{ 164a20c904a6f3e3a11939d5260485be72d5c849c63cristy return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); 165a20c904a6f3e3a11939d5260485be72d5c849c63cristy} 1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * GSUB/GPOS 1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const OT::GSUBGPOS& 1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristyget_gsubgpos_table (hb_face_t *face, 1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag) 1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (table_tag) { 1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case HB_OT_TAG_GSUB: return _get_gsub (face); 1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case HB_OT_TAG_GPOS: return _get_gpos (face); 1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: return OT::Null(OT::GSUBGPOS); 1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristyunsigned int 1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_table_get_script_tags (hb_face_t *face, 1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int start_offset, 1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *script_count /* IN/OUT */, 1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t *script_tags /* OUT */) 1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return g.get_script_tags (start_offset, script_count, script_tags); 1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HB_OT_TAG_LATIN_SCRIPT HB_TAG ('l', 'a', 't', 'n') 1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_bool_t 1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_table_find_script (hb_face_t *face, 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t script_tag, 202b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *script_index) 203a20c904a6f3e3a11939d5260485be72d5c849c63cristy{ 204a20c904a6f3e3a11939d5260485be72d5c849c63cristy ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 205a20c904a6f3e3a11939d5260485be72d5c849c63cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 206a20c904a6f3e3a11939d5260485be72d5c849c63cristy 207a20c904a6f3e3a11939d5260485be72d5c849c63cristy if (g.find_script_index (script_tag, script_index)) 208b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return true; 209b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 210b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy /* try finding 'DFLT' */ 211b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) 212a20c904a6f3e3a11939d5260485be72d5c849c63cristy return false; 213b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 214a20c904a6f3e3a11939d5260485be72d5c849c63cristy /* try with 'dflt'; MS site has had typos and many fonts use it now :(. 215b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy * including many versions of DejaVu Sans Mono! */ 216b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) 217b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 218b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 219b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy /* try with 'latn'; some old fonts put their features there even though 220b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy they're really trying to support Thai, for example :( */ 221a20c904a6f3e3a11939d5260485be72d5c849c63cristy if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) 222a20c904a6f3e3a11939d5260485be72d5c849c63cristy return false; 223b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 224b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 225b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 226a20c904a6f3e3a11939d5260485be72d5c849c63cristy} 227b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 228b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_bool_t 229b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_table_choose_script (hb_face_t *face, 230b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t table_tag, 231b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy const hb_tag_t *script_tags, 232b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *script_index, 233b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t *chosen_script) 234b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 235b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 236b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 237b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 238b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy while (*script_tags) 239b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy { 240b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (g.find_script_index (*script_tags, script_index)) { 241b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (chosen_script) 242b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy *chosen_script = *script_tags; 243b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return true; 244b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy } 245b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy script_tags++; 246b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy } 247b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 248b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy /* try finding 'DFLT' */ 249b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) { 250b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (chosen_script) 251b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT; 252b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 253b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy } 254b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 255b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 256b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) { 257b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (chosen_script) 258b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE; 259b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 260b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy } 261a20c904a6f3e3a11939d5260485be72d5c849c63cristy 262b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy /* try with 'latn'; some old fonts put their features there even though 263b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy they're really trying to support Thai, for example :( */ 264b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) { 265b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (chosen_script) 266b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy *chosen_script = HB_OT_TAG_LATIN_SCRIPT; 267b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 268b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy } 269b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 270b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 271b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (chosen_script) 272b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 273b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 274b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 275b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 276b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyunsigned int 277b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_table_get_feature_tags (hb_face_t *face, 278b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t table_tag, 279b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int start_offset, 280b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *feature_count /* IN/OUT */, 281b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t *feature_tags /* OUT */) 282b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 283b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 284b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 285b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return g.get_feature_tags (start_offset, feature_count, feature_tags); 286b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 287b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 288b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 289b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyunsigned int 290b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_script_get_language_tags (hb_face_t *face, 291b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t table_tag, 292b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int script_index, 293b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int start_offset, 294b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *language_count /* IN/OUT */, 295b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t *language_tags /* OUT */) 296b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 297b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 298b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 299b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return s.get_lang_sys_tags (start_offset, language_count, language_tags); 300b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 301b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 302b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_bool_t 303b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_script_find_language (hb_face_t *face, 304b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t table_tag, 305b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int script_index, 306b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t language_tag, 307b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *language_index) 308b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 309b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX); 310b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 311b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 312b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (s.find_lang_sys_index (language_tag, language_index)) 313b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return true; 314b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 315b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 316b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) 317b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 318b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 319b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; 320b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return false; 321b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 322b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 323b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_bool_t 324b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_language_get_required_feature_index (hb_face_t *face, 325b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t table_tag, 326b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int script_index, 327b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int language_index, 328b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *feature_index) 329b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 330b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return hb_ot_layout_language_get_required_feature (face, 331b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy table_tag, 332b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy script_index, 333b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy language_index, 334b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy feature_index, 335b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy NULL); 336b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 337b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 338b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_bool_t 339b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_language_get_required_feature (hb_face_t *face, 340b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t table_tag, 341b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int script_index, 342b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int language_index, 343b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int *feature_index, 344b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t *feature_tag) 345b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 346b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 347b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 348b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 349b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy unsigned int index = l.get_required_feature_index (); 350b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (feature_index) *feature_index = index; 351b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (feature_tag) *feature_tag = g.get_feature_tag (index); 352b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 353b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy return l.has_required_feature (); 354b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy} 355b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy 356b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyunsigned int 357b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristyhb_ot_layout_language_get_feature_indexes (hb_face_t *face, 358b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy hb_tag_t table_tag, 359a20c904a6f3e3a11939d5260485be72d5c849c63cristy unsigned int script_index, 360a20c904a6f3e3a11939d5260485be72d5c849c63cristy unsigned int language_index, 361a20c904a6f3e3a11939d5260485be72d5c849c63cristy unsigned int start_offset, 362a20c904a6f3e3a11939d5260485be72d5c849c63cristy unsigned int *feature_count /* IN/OUT */, 363a20c904a6f3e3a11939d5260485be72d5c849c63cristy unsigned int *feature_indexes /* OUT */) 364a20c904a6f3e3a11939d5260485be72d5c849c63cristy{ 365a20c904a6f3e3a11939d5260485be72d5c849c63cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return l.get_feature_indexes (start_offset, feature_count, feature_indexes); 3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristyunsigned int 3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_language_get_feature_tags (hb_face_t *face, 3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int script_index, 3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int language_index, 3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int start_offset, 3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *feature_count /* IN/OUT */, 3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t *feature_tags /* OUT */) 3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t)); 3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags); 3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (feature_tags) { 3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int count = *feature_count; 3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < count; i++) 3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]); 3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return ret; 3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_bool_t 3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_language_find_feature (hb_face_t *face, 3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int script_index, 4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int language_index, 4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t feature_tag, 4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *feature_index) 4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); 4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int num_features = l.get_feature_count (); 4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < num_features; i++) { 4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int f_index = l.get_feature_index (i); 4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (feature_tag == g.get_feature_tag (f_index)) { 4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (feature_index) *feature_index = f_index; 4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return true; 4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; 4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return false; 4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristyunsigned int 423bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyhb_ot_layout_feature_get_lookups (hb_face_t *face, 4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int feature_index, 4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int start_offset, 4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *lookup_count /* IN/OUT */, 4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *lookup_indexes /* OUT */) 4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::Feature &f = g.get_feature (feature_index); 4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); 4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristyunsigned int 4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_table_get_lookup_count (hb_face_t *face, 4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag) 4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (table_tag) 4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case HB_OT_TAG_GSUB: 4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return hb_ot_layout_from_face (face)->gsub_lookup_count; 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case HB_OT_TAG_GPOS: 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return hb_ot_layout_from_face (face)->gpos_lookup_count; 4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return 0; 4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void 4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy_hb_ot_layout_collect_lookups_lookups (hb_face_t *face, 4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int feature_index, 458bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy hb_set_t *lookup_indexes /* OUT */) 4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int lookup_indices[32]; 4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int offset, len; 4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset = 0; 4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { 4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy len = ARRAY_LENGTH (lookup_indices); 466bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy hb_ot_layout_feature_get_lookups (face, 4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy feature_index, 4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset, &len, 4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indices); 4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < len; i++) 4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indexes->add (lookup_indices[i]); 474bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy 4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset += len; 4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } while (len == ARRAY_LENGTH (lookup_indices)); 4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void 4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy_hb_ot_layout_collect_lookups_features (hb_face_t *face, 4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int script_index, 4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int language_index, 4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_tag_t *features, 4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *lookup_indexes /* OUT */) 486f84a193d5f435588cd78d521fff3f1f852e227f8cristy{ 4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!features) 4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int required_feature_index; 4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (hb_ot_layout_language_get_required_feature (face, 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy language_index, 4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy &required_feature_index, 4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy NULL)) 496f84a193d5f435588cd78d521fff3f1f852e227f8cristy _hb_ot_layout_collect_lookups_lookups (face, 4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy required_feature_index, 499bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy lookup_indexes); 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* All features */ 5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int feature_indices[32]; 5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int offset, len; 5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset = 0; 5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { 5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy len = ARRAY_LENGTH (feature_indices); 5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_ot_layout_language_get_feature_indexes (face, 5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy language_index, 5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset, &len, 5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy feature_indices); 5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < len; i++) 5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_collect_lookups_lookups (face, 5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy feature_indices[i], 519bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy lookup_indexes); 5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset += len; 5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } while (len == ARRAY_LENGTH (feature_indices)); 5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (; *features; features++) 5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int feature_index; 5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (hb_ot_layout_language_find_feature (face, 5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy language_index, 5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *features, 5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy &feature_index)) 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_collect_lookups_lookups (face, 5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy feature_index, 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indexes); 5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void 5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy_hb_ot_layout_collect_lookups_languages (hb_face_t *face, 5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int script_index, 5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_tag_t *languages, 5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_tag_t *features, 5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *lookup_indexes /* OUT */) 5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_collect_lookups_features (face, 5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 553bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy script_index, 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy features, 5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indexes); 5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!languages) 5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* All languages */ 561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy unsigned int count = hb_ot_layout_script_get_language_tags (face, 5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 0, NULL, NULL); 5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int language_index = 0; language_index < count; language_index++) 5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_collect_lookups_features (face, 5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 569bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy language_index, 5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy features, 5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indexes); 5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (; *languages; languages++) 5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int language_index; 578f84a193d5f435588cd78d521fff3f1f852e227f8cristy if (hb_ot_layout_script_find_language (face, 5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *languages, 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy &language_index)) 5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_collect_lookups_features (face, 5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy language_index, 587f84a193d5f435588cd78d521fff3f1f852e227f8cristy features, 5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indexes); 5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 590bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy } 5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_collect_lookups (hb_face_t *face, 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_tag_t *scripts, 5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_tag_t *languages, 5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_tag_t *features, 5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *lookup_indexes /* OUT */) 6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!scripts) 6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* All scripts */ 6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int count = hb_ot_layout_table_get_script_tags (face, 6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 0, NULL, NULL); 6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int script_index = 0; script_index < count; script_index++) 6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_collect_lookups_languages (face, 6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy languages, 6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy features, 6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indexes); 6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (; *scripts; scripts++) 6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int script_index; 6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (hb_ot_layout_table_find_script (face, 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *scripts, 6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy &script_index)) 6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _hb_ot_layout_collect_lookups_languages (face, 6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table_tag, 6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy script_index, 6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy languages, 6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy features, 6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup_indexes); 6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 631b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy } 6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_lookup_collect_glyphs (hb_face_t *face, 6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_tag_t table_tag, 6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int lookup_index, 6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *glyphs_before, /* OUT. May be NULL */ 6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *glyphs_input, /* OUT. May be NULL */ 6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *glyphs_after, /* OUT. May be NULL */ 6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *glyphs_output /* OUT. May be NULL */) 6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::hb_collect_glyphs_context_t c (face, 6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyphs_before, 6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyphs_input, 6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyphs_after, 6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyphs_output); 6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (table_tag) 6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case HB_OT_TAG_GSUB: 6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); 6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy l.collect_glyphs (&c); 6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case HB_OT_TAG_GPOS: 6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index); 6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy l.collect_glyphs (&c); 6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * OT::GSUB 6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_bool_t 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_has_substitution (hb_face_t *face) 6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return &_get_gsub (face) != &OT::Null(OT::GSUB); 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_bool_t 6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_lookup_would_substitute (hb_face_t *face, 6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int lookup_index, 6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_codepoint_t *glyphs, 6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int glyphs_length, 6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_bool_t zero_context) 6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false; 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context); 6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_bool_t 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, 6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int lookup_index, 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_codepoint_t *glyphs, 6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int glyphs_length, 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_bool_t zero_context) 696b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{ 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false; 6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context); 6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); 7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index]); 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 7060157aeadef2fce908277168097a160a8f15a6952cristyhb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::GSUB::substitute_start (font, buffer); 7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::GSUB::substitute_finish (font, buffer); 7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_lookup_substitute_closure (hb_face_t *face, 7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int lookup_index, 7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_set_t *glyphs) 7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::hb_closure_context_t c (face, glyphs); 7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); 7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy l.closure (&c); 7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * OT::GPOS 7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_bool_t 7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_has_positioning (hb_face_t *face) 7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return &_get_gpos (face) != &OT::Null(OT::GPOS); 7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) 7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::GPOS::position_start (font, buffer); 7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid 7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) 7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::GPOS::position_finish (font, buffer); 7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_bool_t 7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_get_size_params (hb_face_t *face, 7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *design_size, /* OUT. May be NULL */ 7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *subfamily_id, /* OUT. May be NULL */ 7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *subfamily_name_id, /* OUT. May be NULL */ 7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *range_start, /* OUT. May be NULL */ 7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int *range_end /* OUT. May be NULL */) 7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::GPOS &gpos = _get_gpos (face); 7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_tag_t tag = HB_TAG ('s','i','z','e'); 7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int num_features = gpos.get_feature_count (); 7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int i = 0; i < num_features; i++) 7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (tag == gpos.get_feature_tag (i)) 7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::Feature &f = gpos.get_feature (i); 7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::FeatureParamsSize ¶ms = f.get_feature_params ().get_size_params (tag); 7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (params.designSize) 7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PARAM(a, A) if (a) *a = params.A 7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (design_size, designSize); 7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (subfamily_id, subfamilyID); 7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (subfamily_name_id, subfamilyNameID); 7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (range_start, rangeStart); 7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (range_end, rangeEnd); 7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PARAM 7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return true; 7814e1dff661dca8fc9ca6f524eaacb32c0eb5a9d78cristy } 7824e1dff661dca8fc9ca6f524eaacb32c0eb5a9d78cristy } 783f84a193d5f435588cd78d521fff3f1f852e227f8cristy } 7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PARAM(a, A) if (a) *a = 0 7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (design_size, designSize); 7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (subfamily_id, subfamilyID); 7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (subfamily_name_id, subfamilyNameID); 7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (range_start, rangeStart); 7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PARAM (range_end, rangeEnd); 7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PARAM 7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return false; 7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Parts of different types are implemented here such that they have direct 7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * access to GSUB/GPOS lookups. 8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystruct GSUBProxy 8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy static const unsigned int table_index = 0; 8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy static const bool inplace = false; 8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy typedef OT::SubstLookup Lookup; 8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GSUBProxy (hb_face_t *face) : 8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table (*hb_ot_layout_from_face (face)->gsub), 811f84a193d5f435588cd78d521fff3f1f852e227f8cristy accels (hb_ot_layout_from_face (face)->gsub_accels) {} 8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::GSUB &table; 8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_ot_layout_lookup_accelerator_t *accels; 8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}; 8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystruct GPOSProxy 81841c3c77d6f4e3131bf2be0b35277c086b69ce492cristy{ 81941c3c77d6f4e3131bf2be0b35277c086b69ce492cristy static const unsigned int table_index = 1; 82041c3c77d6f4e3131bf2be0b35277c086b69ce492cristy static const bool inplace = true; 8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy typedef OT::PosLookup Lookup; 8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GPOSProxy (hb_face_t *face) : 8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table (*hb_ot_layout_from_face (face)->gpos), 8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accels (hb_ot_layout_from_face (face)->gpos_accels) {} 8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::GPOS &table; 8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_ot_layout_lookup_accelerator_t *accels; 8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}; 8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristytemplate <typename Proxy> 8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline bool 8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyapply_string (OT::hb_apply_context_t *c, 8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const typename Proxy::Lookup &lookup, 8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_ot_layout_lookup_accelerator_t &accel) 8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bool ret = false; 8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_buffer_t *buffer = c->buffer; 8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unlikely (!buffer->len || !c->lookup_mask)) 8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return false; 8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c->set_lookup (lookup); 8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (likely (!lookup.is_reverse ())) 8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* in/out forward substitution/positioning */ 849bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (Proxy::table_index == 0) 8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer->clear_output (); 8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer->idx = 0; 852bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy 8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (buffer->idx < buffer->len) 8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (accel.may_have (buffer->cur().codepoint) && 8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (buffer->cur().mask & c->lookup_mask) && 8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c->check_glyph_property (&c->buffer->cur(), c->lookup_props) && 8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup.dispatch (c)) 8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = true; 8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer->next_glyph (); 862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy } 8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (ret) 8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (!Proxy::inplace) 8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer->swap_buffers (); 8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert (!buffer->has_separate_output ()); 8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 870b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy } 871b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy else 872b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy { 8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* in-place backward substitution/positioning */ 8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (Proxy::table_index == 0) 8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer->remove_output (); 876b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy buffer->idx = buffer->len - 1; 8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do 878b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy { 879b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy if (accel.may_have (buffer->cur().codepoint) && 8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (buffer->cur().mask & c->lookup_mask) && 8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c->check_glyph_property (&c->buffer->cur(), c->lookup_props) && 8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy lookup.dispatch (c)) 8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ret = true; 8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* The reverse lookup doesn't "advance" cursor (for good reason). */ 8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer->idx--; 8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while ((int) buffer->idx >= 0); 8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return ret; 8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristytemplate <typename Proxy> 8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristyinline void hb_ot_map_t::apply (const Proxy &proxy, 8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_ot_shape_plan_t *plan, 8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_font_t *font, 8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hb_buffer_t *buffer) const 8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const unsigned int table_index = proxy.table_index; 9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int i = 0; 9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OT::hb_apply_context_t c (table_index, font, buffer); 9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c.set_recurse_func (Proxy::Lookup::apply_recurse_func); 904bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy 9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { 9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const stage_map_t *stage = &stages[table_index][stage_index]; 9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (; i < stage->last_lookup; i++) 9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int lookup_index = lookups[table_index][i].index; 9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c.set_lookup_mask (lookups[table_index][i].mask); 9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c.set_auto_zwj (lookups[table_index][i].auto_zwj); 9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy apply_string<Proxy> (&c, 9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proxy.table.get_lookup (lookup_index), 9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proxy.accels[lookup_index]); 9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (stage->pause_func) 918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy { 9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer->clear_output (); 9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stage->pause_func (plan, font, buffer); 9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9239d314ff2c17a77996c05413c2013880387e50f0ecristy} 9249d314ff2c17a77996c05413c2013880387e50f0ecristy 9259d314ff2c17a77996c05413c2013880387e50f0ecristyvoid hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GSUBProxy proxy (font->face); 9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy apply (proxy, plan, font, buffer); 9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyvoid hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GPOSProxy proxy (font->face); 9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy apply (proxy, plan, font, buffer); 9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 937bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyHB_INTERNAL void 9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristyhb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, 9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const OT::SubstLookup &lookup, 9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const hb_ot_layout_lookup_accelerator_t &accel) 9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy apply_string<GSUBProxy> (c, lookup, accel); 9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy