hb-ot-layout.cc revision 395b35903e052aecc97d0807e4f813c64c0d2b0b
1fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod/* 22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 1998-2004 David Turner and Werner Lemberg 32409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2006 Behdad Esfahbod 42409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2007,2008,2009 Red Hat, Inc. 545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod * Copyright © 2012,2013 Google, Inc. 6fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 7c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 8fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 9fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * Permission is hereby granted, without written agreement and without 10fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 11fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * software and its documentation for any purpose, provided that the 12fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * above copyright notice and the following two paragraphs appear in 13fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * all copies of this software. 14fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 15fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 16fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 17fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 18fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 19fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * DAMAGE. 20fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 21fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 22fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 23fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 24fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 25fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 26fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 27fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 28f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod * Google Author(s): Behdad Esfahbod 29fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod */ 30fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 3122da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-ot-layout-private.hh" 32fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 337a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gdef-table.hh" 347a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gsub-table.hh" 357a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gpos-table.hh" 366c48f20eea22c6e686416ab4ec8388be3e8cd0b5Behdad Esfahbod#include "hb-ot-layout-jstf-table.hh" 37fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 38d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod#include "hb-ot-map-private.hh" 39d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 40fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#include <stdlib.h> 41aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod#include <string.h> 42aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 43acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 44cfe9882610489e1b917e09a74dfbf6bbba2e4a57Behdad EsfahbodHB_SHAPER_DATA_ENSURE_DECLARE(ot, face) 4511f4c87d01924cac43bf40044f67838440e19e42Behdad Esfahbod 460a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbodhb_ot_layout_t * 47266b34418c9bbe23ccaf29cb354b58c465fa3b22Behdad Esfahbod_hb_ot_layout_create (hb_face_t *face) 484a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 490a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbod hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t)); 503dcbdc2125c04c173f29f04922fc031929893f4eBehdad Esfahbod if (unlikely (!layout)) 513dcbdc2125c04c173f29f04922fc031929893f4eBehdad Esfahbod return NULL; 52555d11273ee4c30e84eda3a78ffadb3ee7da65d0Behdad Esfahbod 537c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF)); 547c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob); 5570e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 567c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB)); 577c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob); 5870e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 597c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS)); 607c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob); 610a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbod 626f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod layout->gsub_lookup_count = layout->gsub->get_lookup_count (); 636f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod layout->gpos_lookup_count = layout->gpos->get_lookup_count (); 646f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod 6545fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); 6645fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); 671336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 6845fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) || 6945fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod (layout->gpos_lookup_count && !layout->gpos_accels))) 701336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod { 711336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod _hb_ot_layout_destroy (layout); 721336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod return NULL; 731336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod } 741336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 756f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) 7645fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gsub_accels[i].init (layout->gsub->get_lookup (i)); 776f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) 7845fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gpos_accels[i].init (layout->gpos->get_lookup (i)); 791336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 800a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbod return layout; 81f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 82f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 8323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodvoid 84266b34418c9bbe23ccaf29cb354b58c465fa3b22Behdad Esfahbod_hb_ot_layout_destroy (hb_ot_layout_t *layout) 85fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod{ 8645fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) 87395b35903e052aecc97d0807e4f813c64c0d2b0bBehdad Esfahbod layout->gsub_accels[i].fini (); 8845fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) 89395b35903e052aecc97d0807e4f813c64c0d2b0bBehdad Esfahbod layout->gpos_accels[i].fini (); 9045fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod 9145fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod free (layout->gsub_accels); 9245fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod free (layout->gpos_accels); 931336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 9489312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger hb_blob_destroy (layout->gdef_blob); 9589312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger hb_blob_destroy (layout->gsub_blob); 9689312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger hb_blob_destroy (layout->gpos_blob); 9789312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger 989ea7368fce3fa373d8d2925961ad211f5cf6ce70Behdad Esfahbod free (layout); 9923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod} 100f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 1017c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic inline const OT::GDEF& 10223c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gdef (hb_face_t *face) 10323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod{ 1047c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF); 105ea278d3895fe0c92801d692cd71d8d9f1de7c048Behdad Esfahbod return *hb_ot_layout_from_face (face)->gdef; 10623c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod} 1077c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic inline const OT::GSUB& 10823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gsub (hb_face_t *face) 109fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod{ 1107c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB); 111ea278d3895fe0c92801d692cd71d8d9f1de7c048Behdad Esfahbod return *hb_ot_layout_from_face (face)->gsub; 112fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod} 1137c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic inline const OT::GPOS& 11423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gpos (hb_face_t *face) 1152ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod{ 1167c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS); 117ea278d3895fe0c92801d692cd71d8d9f1de7c048Behdad Esfahbod return *hb_ot_layout_from_face (face)->gpos; 1182ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod} 1192ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod 12023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod 121590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod/* 122590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod * GDEF 123590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod */ 124590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 125590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbodhb_bool_t 12652ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbodhb_ot_layout_has_glyph_classes (hb_face_t *face) 127590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod{ 12823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return _get_gdef (face).has_glyph_classes (); 129590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod} 130590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 1315a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbodhb_ot_layout_glyph_class_t 1325a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbodhb_ot_layout_get_glyph_class (hb_face_t *face, 1335a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod hb_codepoint_t glyph) 1345a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod{ 1355a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); 1365a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod} 1374a2d844c2f12dc1b858ab4ddd737ded7c0852221Behdad Esfahbod 13889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbodvoid 13989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbodhb_ot_layout_get_glyphs_in_class (hb_face_t *face, 14089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod hb_ot_layout_glyph_class_t klass, 14189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod hb_set_t *glyphs /* OUT */) 14289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod{ 14389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod return _get_gdef (face).get_glyphs_in_class (klass, glyphs); 14489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod} 14589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 146e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 1470ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_get_attach_points (hb_face_t *face, 14879420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod hb_codepoint_t glyph, 149e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 15079420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod unsigned int *point_count /* IN/OUT */, 15179420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod unsigned int *point_array /* OUT */) 15279420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod{ 153e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array); 15462964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod} 15562964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod 156e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 157e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbodhb_ot_layout_get_ligature_carets (hb_font_t *font, 158e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod hb_direction_t direction, 159e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod hb_codepoint_t glyph, 160e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod unsigned int start_offset, 161e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod unsigned int *caret_count /* IN/OUT */, 162e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod int *caret_array /* OUT */) 16362964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod{ 164abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); 16579420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod} 16679420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod 16705bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbod 168706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod/* 169706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod * GSUB/GPOS 170706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod */ 171706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 1727c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic const OT::GSUBGPOS& 17323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodget_gsubgpos_table (hb_face_t *face, 17423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod hb_tag_t table_tag) 175706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 1760ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod switch (table_tag) { 17723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod case HB_OT_TAG_GSUB: return _get_gsub (face); 17823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod case HB_OT_TAG_GPOS: return _get_gpos (face); 1797c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod default: return OT::Null(OT::GSUBGPOS); 180706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod } 181706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 182706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 183706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 184e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 185bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_table_get_script_tags (hb_face_t *face, 186bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 187e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 188bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *script_count /* IN/OUT */, 189bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *script_tags /* OUT */) 190706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 1917c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 192706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 193e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return g.get_script_tags (start_offset, script_count, script_tags); 194706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 195706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 196eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod#define HB_OT_TAG_LATIN_SCRIPT HB_TAG ('l', 'a', 't', 'n') 197eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod 198706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbodhb_bool_t 1990ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_table_find_script (hb_face_t *face, 2000ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 2010ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t script_tag, 2020ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *script_index) 203706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 2047c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 2057c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 206706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 207706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod if (g.find_script_index (script_tag, script_index)) 2080594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 209706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 210706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod /* try finding 'DFLT' */ 2118a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) 2120594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 213706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 214dca8aff24652c83c53efbb9d06e5e1c7ef1c2fa5Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :(. 215dca8aff24652c83c53efbb9d06e5e1c7ef1c2fa5Behdad Esfahbod * including many versions of DejaVu Sans Mono! */ 2168a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) 2170594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 2182014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 219eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod /* try with 'latn'; some old fonts put their features there even though 220eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod they're really trying to support Thai, for example :( */ 221eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) 222eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod return false; 223eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod 2242014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 2250594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 2262014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod} 2272014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2282014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbodhb_bool_t 2292014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbodhb_ot_layout_table_choose_script (hb_face_t *face, 2302014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod hb_tag_t table_tag, 2312014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod const hb_tag_t *script_tags, 232c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod unsigned int *script_index, 233c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod hb_tag_t *chosen_script) 2342014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod{ 2357c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 2367c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 2372014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2382014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod while (*script_tags) 2392014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod { 240c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (g.find_script_index (*script_tags, script_index)) { 241c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 242c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = *script_tags; 2430594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 244c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod } 2452014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod script_tags++; 2462014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod } 2472014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2482014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod /* try finding 'DFLT' */ 249c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) { 250c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 251c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT; 2520594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 253c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod } 2542014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2552014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 256c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) { 257c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 258c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE; 2590594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 260c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod } 261706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 26271632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod /* try with 'latn'; some old fonts put their features there even though 26371632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod they're really trying to support Thai, for example :( */ 26471632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) { 26571632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod if (chosen_script) 26671632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod *chosen_script = HB_OT_TAG_LATIN_SCRIPT; 2670594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 26871632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod } 26971632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod 270706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 271c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 272c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 2730594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 274706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 275706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 276e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 277bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_table_get_feature_tags (hb_face_t *face, 278bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 279e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 280bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 281bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) 282c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod{ 2837c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 284c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 285e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return g.get_feature_tags (start_offset, feature_count, feature_tags); 286c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 287c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 288c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 289e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 290bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_script_get_language_tags (hb_face_t *face, 291bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 292bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 293e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 294bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *language_count /* IN/OUT */, 295bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *language_tags /* OUT */) 296706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 2977c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 298706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 299e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return s.get_lang_sys_tags (start_offset, language_count, language_tags); 300706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 301706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 302706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbodhb_bool_t 3030ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_script_find_language (hb_face_t *face, 3040ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 3050ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int script_index, 3060ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t language_tag, 3070ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *language_index) 308706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 3097c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX); 3107c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 311706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 3124a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (s.find_lang_sys_index (language_tag, language_index)) 3130594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 314706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 315706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 3168a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) 3170594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 318706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 3194a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; 3200594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 3214a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 322706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 3234a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbodhb_bool_t 324911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbodhb_ot_layout_language_get_required_feature_index (hb_face_t *face, 325911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod hb_tag_t table_tag, 326911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod unsigned int script_index, 327911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod unsigned int language_index, 328911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod unsigned int *feature_index) 329911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod{ 330911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod return hb_ot_layout_language_get_required_feature (face, 331911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod table_tag, 332911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod script_index, 333911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod language_index, 334911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod feature_index, 335911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod NULL); 336911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod} 337911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod 338911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbodhb_bool_t 339da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kewhb_ot_layout_language_get_required_feature (hb_face_t *face, 340da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew hb_tag_t table_tag, 341da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int script_index, 342da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int language_index, 343da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int *feature_index, 344da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew hb_tag_t *feature_tag) 3454a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 346da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 347da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 348706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 349da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int index = l.get_required_feature_index (); 350da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew if (feature_index) *feature_index = index; 351da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew if (feature_tag) *feature_tag = g.get_feature_tag (index); 352706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 3534a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod return l.has_required_feature (); 3544a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 355706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 356e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 357bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_language_get_feature_indexes (hb_face_t *face, 358bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 359bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 360bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int language_index, 361e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 362bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 363bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_indexes /* OUT */) 3640ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 3657c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 3667c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 3674a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 368e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return l.get_feature_indexes (start_offset, feature_count, feature_indexes); 369c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 370c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 371e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 372bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_language_get_feature_tags (hb_face_t *face, 373bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 374bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 375bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int language_index, 376e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 377bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 378bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) 3790ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 3807c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 3817c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 3824a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 383bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t)); 384e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags); 385bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 3869897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod if (feature_tags) { 3879897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod unsigned int count = *feature_count; 3889897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 3899897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]); 3909897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod } 391bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 392bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod return ret; 3934a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 3944a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 3954a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 3964a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbodhb_bool_t 3970ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_language_find_feature (hb_face_t *face, 3980ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 3990ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int script_index, 4000ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int language_index, 4010ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t feature_tag, 4020ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *feature_index) 4034a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 4047c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); 4057c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4067c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4074a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 408f4c9514935cf97a58dcb3b1962ac3f3b5ba61264Behdad Esfahbod unsigned int num_features = l.get_feature_count (); 409f4c9514935cf97a58dcb3b1962ac3f3b5ba61264Behdad Esfahbod for (unsigned int i = 0; i < num_features; i++) { 4104a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod unsigned int f_index = l.get_feature_index (i); 4114a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 4124a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_tag == g.get_feature_tag (f_index)) { 4134a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_index) *feature_index = f_index; 4140594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 4154a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod } 4164a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod } 417706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4184a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; 4190594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 420706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 421c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 422e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 423f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbodhb_ot_layout_feature_get_lookups (hb_face_t *face, 424f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod hb_tag_t table_tag, 425f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int feature_index, 426f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int start_offset, 427f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int *lookup_count /* IN/OUT */, 428f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int *lookup_indexes /* OUT */) 429c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod{ 4307c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4317c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::Feature &f = g.get_feature (feature_index); 432c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 433e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); 434c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 435c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 43627674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbodunsigned int 43727674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbodhb_ot_layout_table_get_lookup_count (hb_face_t *face, 43827674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod hb_tag_t table_tag) 43927674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod{ 44027674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod switch (table_tag) 44127674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod { 44227674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod case HB_OT_TAG_GSUB: 44327674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod { 44427674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod return hb_ot_layout_from_face (face)->gsub_lookup_count; 44527674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod } 44627674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod case HB_OT_TAG_GPOS: 44727674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod { 44827674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod return hb_ot_layout_from_face (face)->gpos_lookup_count; 44927674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod } 45027674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod } 4514e6e53db5da0a5da87ae732c3f9d01babf4ae6c2Behdad Esfahbod return 0; 45227674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod} 45327674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod 454a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodstatic void 455a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod_hb_ot_layout_collect_lookups_lookups (hb_face_t *face, 456a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 457a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int feature_index, 458a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 459a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 460a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int lookup_indices[32]; 461a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int offset, len; 462a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 463a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod offset = 0; 464a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod do { 465a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod len = ARRAY_LENGTH (lookup_indices); 466a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_ot_layout_feature_get_lookups (face, 467a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod table_tag, 468a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod feature_index, 469a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod offset, &len, 470a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod lookup_indices); 471a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 472a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (unsigned int i = 0; i < len; i++) 473a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod lookup_indexes->add (lookup_indices[i]); 474a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 475a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod offset += len; 476a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } while (len == ARRAY_LENGTH (lookup_indices)); 477a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 478a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 479a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodstatic void 480a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod_hb_ot_layout_collect_lookups_features (hb_face_t *face, 481a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 482a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int script_index, 483a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int language_index, 484a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *features, 485a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 486a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 487a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod if (!features) 488a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 4895f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod unsigned int required_feature_index; 490da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew if (hb_ot_layout_language_get_required_feature (face, 491da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew table_tag, 492da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew script_index, 493da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew language_index, 494da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew &required_feature_index, 495da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew NULL)) 4965f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod _hb_ot_layout_collect_lookups_lookups (face, 4975f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod table_tag, 4985f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod required_feature_index, 4995f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod lookup_indexes); 5005f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod 501a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod /* All features */ 50215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod unsigned int feature_indices[32]; 50315e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod unsigned int offset, len; 50415e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod 50515e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod offset = 0; 50615e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod do { 50715e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod len = ARRAY_LENGTH (feature_indices); 50815e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod hb_ot_layout_language_get_feature_indexes (face, 50915e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod table_tag, 51015e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod script_index, 51115e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod language_index, 51215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod offset, &len, 51315e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod feature_indices); 51415e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod 51515e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod for (unsigned int i = 0; i < len; i++) 51615e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod _hb_ot_layout_collect_lookups_lookups (face, 51715e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod table_tag, 51815e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod feature_indices[i], 51915e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod lookup_indexes); 52015e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod 52115e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod offset += len; 52215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } while (len == ARRAY_LENGTH (feature_indices)); 52315e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } 52415e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod else 52515e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 526a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (; *features; features++) 527a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 528a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int feature_index; 529733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod if (hb_ot_layout_language_find_feature (face, 530733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 531733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 532733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod language_index, 533733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod *features, 534733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod &feature_index)) 535733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_lookups (face, 536733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 537733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod feature_index, 538733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 539a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 540a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 541a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 542a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 543a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodstatic void 544a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod_hb_ot_layout_collect_lookups_languages (hb_face_t *face, 545a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 546a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int script_index, 547a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *languages, 548a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *features, 549a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 550a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 551f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod _hb_ot_layout_collect_lookups_features (face, 552f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod table_tag, 553f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod script_index, 554f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 555f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod features, 556f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod lookup_indexes); 557f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod 558a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod if (!languages) 559a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 560a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod /* All languages */ 561733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod unsigned int count = hb_ot_layout_script_get_language_tags (face, 562733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 563733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 564733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod 0, NULL, NULL); 565a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (unsigned int language_index = 0; language_index < count; language_index++) 566733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_features (face, 567733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 568733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 569733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod language_index, 570733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 571733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 57215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } 57315e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod else 57415e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 575a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (; *languages; languages++) 576a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 577a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int language_index; 578733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod if (hb_ot_layout_script_find_language (face, 579733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 580733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 581733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod *languages, 582733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod &language_index)) 583733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_features (face, 584733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 585733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 586733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod language_index, 587733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 588733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 589a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 590a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 591a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 592a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 593a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodvoid 594a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodhb_ot_layout_collect_lookups (hb_face_t *face, 595a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 596a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *scripts, 597a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *languages, 598a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *features, 599a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 600a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 601a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod if (!scripts) 602a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 603a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod /* All scripts */ 604733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod unsigned int count = hb_ot_layout_table_get_script_tags (face, 605733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 606733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod 0, NULL, NULL); 607a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (unsigned int script_index = 0; script_index < count; script_index++) 608733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_languages (face, 609733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 610733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 611733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod languages, 612733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 613733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 61415e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } 61515e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod else 61615e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 617a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (; *scripts; scripts++) 618a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 619a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int script_index; 620733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod if (hb_ot_layout_table_find_script (face, 621733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 622733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod *scripts, 623733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod &script_index)) 624733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_languages (face, 625733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 626733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 627733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod languages, 628733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 629733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 630a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 631a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 632a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 633a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 634e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbodvoid 635e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbodhb_ot_layout_lookup_collect_glyphs (hb_face_t *face, 636e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_tag_t table_tag, 637e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int lookup_index, 638e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_before, /* OUT. May be NULL */ 639e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_input, /* OUT. May be NULL */ 640e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_after, /* OUT. May be NULL */ 641e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_output /* OUT. May be NULL */) 642e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod{ 643e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; 644e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 645733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod OT::hb_collect_glyphs_context_t c (face, 646733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_before, 647733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_input, 648733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_after, 649733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_output); 650e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 65115e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod switch (table_tag) 65215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 653e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod case HB_OT_TAG_GSUB: 654e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 655cdd756b9f40665a201f5c4e65a87b9a27c390601Behdad Esfahbod const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); 656780cd930a974165d76dbf7a87701d11b7f15db06Behdad Esfahbod l.collect_glyphs (&c); 657e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod return; 658e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 659e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod case HB_OT_TAG_GPOS: 660e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 661cdd756b9f40665a201f5c4e65a87b9a27c390601Behdad Esfahbod const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index); 662780cd930a974165d76dbf7a87701d11b7f15db06Behdad Esfahbod l.collect_glyphs (&c); 663e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod return; 664e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 665e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 666e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod} 667e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 6682d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 6692d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod/* 6707c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod * OT::GSUB 6712d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod */ 6722d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 6732d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbodhb_bool_t 6740ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_has_substitution (hb_face_t *face) 6750ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 6767c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod return &_get_gsub (face) != &OT::Null(OT::GSUB); 6770ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 6780ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 679e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodhb_bool_t 680362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbodhb_ot_layout_lookup_would_substitute (hb_face_t *face, 681d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod unsigned int lookup_index, 682e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const hb_codepoint_t *glyphs, 683e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int glyphs_length, 684d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod hb_bool_t zero_context) 685e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 6866f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false; 687362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbod return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context); 688e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 689e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 690f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbodhb_bool_t 691362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbodhb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, 692d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod unsigned int lookup_index, 693f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod const hb_codepoint_t *glyphs, 694f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod unsigned int glyphs_length, 695d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod hb_bool_t zero_context) 696f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod{ 6976f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false; 6982bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context); 6992bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod 7002bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); 7012bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod 70245fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest); 703f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod} 704f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod 70546d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbodvoid 706afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbodhb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) 70746d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod{ 7087c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod OT::GSUB::substitute_start (font, buffer); 70946d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod} 71046d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod 71146d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbodvoid 712afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbodhb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) 71346d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod{ 7147c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod OT::GSUB::substitute_finish (font, buffer); 71546d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod} 71646d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod 7175caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbodvoid 718362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbodhb_ot_layout_lookup_substitute_closure (hb_face_t *face, 719d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod unsigned int lookup_index, 720d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod hb_set_t *glyphs) 721f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod{ 7229b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod OT::hb_closure_context_t c (face, glyphs); 7239b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 7249b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); 7259b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 7269b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod l.closure (&c); 727f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod} 728bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 7299c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod/* 7307c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod * OT::GPOS 7319c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod */ 7329c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod 7339c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbodhb_bool_t 7340ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_has_positioning (hb_face_t *face) 7350ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 7367c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod return &_get_gpos (face) != &OT::Null(OT::GPOS); 7370ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 7380ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 7398f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbodvoid 74005bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbodhb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) 7418f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod{ 7427c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod OT::GPOS::position_start (font, buffer); 7438f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod} 7448f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 7459db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbodvoid 746568000274c8edb5f41bc4f876ce21fcc8bdaeed8Behdad Esfahbodhb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) 7479db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod{ 748568000274c8edb5f41bc4f876ce21fcc8bdaeed8Behdad Esfahbod OT::GPOS::position_finish (font, buffer); 7499db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod} 750f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 751f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodhb_bool_t 752875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbodhb_ot_layout_get_size_params (hb_face_t *face, 753875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *design_size, /* OUT. May be NULL */ 754875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *subfamily_id, /* OUT. May be NULL */ 755875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *subfamily_name_id, /* OUT. May be NULL */ 756875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *range_start, /* OUT. May be NULL */ 757875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *range_end /* OUT. May be NULL */) 758f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 759f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod const OT::GPOS &gpos = _get_gpos (face); 760efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod const hb_tag_t tag = HB_TAG ('s','i','z','e'); 761f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 7620dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod unsigned int num_features = gpos.get_feature_count (); 7630dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod for (unsigned int i = 0; i < num_features; i++) 7640dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod { 765efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == gpos.get_feature_tag (i)) 766f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod { 7670dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod const OT::Feature &f = gpos.get_feature (i); 768efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod const OT::FeatureParamsSize ¶ms = f.get_feature_params ().get_size_params (tag); 769f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 770efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (params.designSize) 77185bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod { 772efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod#define PARAM(a, A) if (a) *a = params.A 77385bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (design_size, designSize); 77485bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (subfamily_id, subfamilyID); 77585bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (subfamily_name_id, subfamilyNameID); 77685bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (range_start, rangeStart); 77785bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (range_end, rangeEnd); 77885bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod#undef PARAM 779efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 780efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return true; 781efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod } 782f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 783f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 784f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 785875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod#define PARAM(a, A) if (a) *a = 0 786efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (design_size, designSize); 787efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (subfamily_id, subfamilyID); 788efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (subfamily_name_id, subfamilyNameID); 789efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (range_start, rangeStart); 790efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (range_end, rangeEnd); 791875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod#undef PARAM 792f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 793efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return false; 794f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod} 795d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 796d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 797d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod/* 798bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod * Parts of different types are implemented here such that they have direct 799d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod * access to GSUB/GPOS lookups. 800d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod */ 801d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 802d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 803bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodstruct GSUBProxy 804bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod{ 805bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod static const unsigned int table_index = 0; 8066ffc007b61402c9d1d4de368deed4971a10ed00bBehdad Esfahbod static const bool inplace = false; 807bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod typedef OT::SubstLookup Lookup; 808bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 809bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GSUBProxy (hb_face_t *face) : 810bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod table (*hb_ot_layout_from_face (face)->gsub), 811bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod accels (hb_ot_layout_from_face (face)->gsub_accels) {} 812bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 813bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const OT::GSUB &table; 814bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t *accels; 815bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod}; 816bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 817bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodstruct GPOSProxy 818bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod{ 819bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod static const unsigned int table_index = 1; 8206ffc007b61402c9d1d4de368deed4971a10ed00bBehdad Esfahbod static const bool inplace = true; 821bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod typedef OT::PosLookup Lookup; 822bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 823bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GPOSProxy (hb_face_t *face) : 824bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod table (*hb_ot_layout_from_face (face)->gpos), 825bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod accels (hb_ot_layout_from_face (face)->gpos_accels) {} 826bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 827bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const OT::GPOS &table; 828bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t *accels; 829bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod}; 830bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 831bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 83245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbodtemplate <typename Lookup> 83345f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbodstatic inline bool apply_once (OT::hb_apply_context_t *c, 83445f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod const Lookup &lookup) 83545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod{ 83645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) 83745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod return false; 83845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod return lookup.dispatch (c); 83945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod} 84045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 84145f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbodtemplate <typename Proxy> 84245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbodstatic inline bool 84345f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbodapply_string (OT::hb_apply_context_t *c, 84445f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod const typename Proxy::Lookup &lookup, 84545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod const hb_ot_layout_lookup_accelerator_t &accel) 84645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod{ 84745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod bool ret = false; 848ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 84945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 850ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod if (unlikely (!buffer->len || !c->lookup_mask)) 85145f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod return false; 85245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 85345f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod c->set_lookup (lookup); 85445f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 85545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod if (likely (!lookup.is_reverse ())) 85645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod { 85745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod /* in/out forward substitution/positioning */ 85845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod if (Proxy::table_index == 0) 859ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->clear_output (); 860ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->idx = 0; 86145f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 862ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod while (buffer->idx < buffer->len) 86345f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod { 864ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod if (accel.digest.may_have (buffer->cur().codepoint) && 865ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod (buffer->cur().mask & c->lookup_mask) && 86645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod apply_once (c, lookup)) 86745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod ret = true; 86845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod else 869ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->next_glyph (); 87045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod } 8719d9e72e94e7914f82ce62a304e7242f79c13edafBehdad Esfahbod if (ret) 8729d9e72e94e7914f82ce62a304e7242f79c13edafBehdad Esfahbod { 8736ffc007b61402c9d1d4de368deed4971a10ed00bBehdad Esfahbod if (!Proxy::inplace) 874ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->swap_buffers (); 8759d9e72e94e7914f82ce62a304e7242f79c13edafBehdad Esfahbod else 876ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod assert (!buffer->has_separate_output ()); 8779d9e72e94e7914f82ce62a304e7242f79c13edafBehdad Esfahbod } 87845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod } 87945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod else 88045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod { 88145f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod /* in-place backward substitution/positioning */ 88245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod if (Proxy::table_index == 0) 883ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->remove_output (); 884ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->idx = buffer->len - 1; 88545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod do 88645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod { 887ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod if (accel.digest.may_have (buffer->cur().codepoint) && 888ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod (buffer->cur().mask & c->lookup_mask) && 88945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod apply_once (c, lookup)) 89045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod ret = true; 89149901862e36e1c153835877a9f1183729333bbbeBehdad Esfahbod /* The reverse lookup doesn't "advance" cursor (for good reason). */ 892ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->idx--; 89345f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 89445f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod } 895ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod while ((int) buffer->idx >= 0); 89645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod } 89745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 89845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod return ret; 89945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod} 90045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 901bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodtemplate <typename Proxy> 902bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodinline void hb_ot_map_t::apply (const Proxy &proxy, 903d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod const hb_ot_shape_plan_t *plan, 904d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod hb_font_t *font, 905d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod hb_buffer_t *buffer) const 906d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod{ 907bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const unsigned int table_index = proxy.table_index; 908d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod unsigned int i = 0; 909bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod OT::hb_apply_context_t c (table_index, font, buffer); 91045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod c.set_recurse_func (Proxy::Lookup::apply_recurse_func); 911d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 912d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { 913d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod const stage_map_t *stage = &stages[table_index][stage_index]; 914d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod for (; i < stage->last_lookup; i++) 915bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod { 916bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod unsigned int lookup_index = lookups[table_index][i].index; 917bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod c.set_lookup_mask (lookups[table_index][i].mask); 918bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod c.set_auto_zwj (lookups[table_index][i].auto_zwj); 91945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod apply_string<Proxy> (&c, 92045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod proxy.table.get_lookup (lookup_index), 92145f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod proxy.accels[lookup_index]); 922bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod } 923d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 924d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod if (stage->pause_func) 925d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod { 926d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod buffer->clear_output (); 927d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod stage->pause_func (plan, font, buffer); 928d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod } 929d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod } 930d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod} 931d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 932d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbodvoid hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 933d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod{ 934bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GSUBProxy proxy (font->face); 935bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod apply (proxy, plan, font, buffer); 936d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod} 937d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 938d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbodvoid hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 939d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod{ 940bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GPOSProxy proxy (font->face); 941bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod apply (proxy, plan, font, buffer); 942bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod} 943bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 944bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad EsfahbodHB_INTERNAL void 945bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodhb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, 946bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const OT::SubstLookup &lookup, 947bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t &accel) 948bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod{ 94945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod apply_string<GSUBProxy> (c, lookup, accel); 950d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod} 951