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 3177a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod#include "hb-open-type-private.hh" 3222da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-ot-layout-private.hh" 33fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 347a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gdef-table.hh" 357a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gsub-table.hh" 367a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gpos-table.hh" 376c48f20eea22c6e686416ab4ec8388be3e8cd0b5Behdad Esfahbod#include "hb-ot-layout-jstf-table.hh" 38fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 39d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod#include "hb-ot-map-private.hh" 40d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 41fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#include <stdlib.h> 42aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod#include <string.h> 43aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 44acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 45cfe9882610489e1b917e09a74dfbf6bbba2e4a57Behdad EsfahbodHB_SHAPER_DATA_ENSURE_DECLARE(ot, face) 4611f4c87d01924cac43bf40044f67838440e19e42Behdad Esfahbod 470a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbodhb_ot_layout_t * 48266b34418c9bbe23ccaf29cb354b58c465fa3b22Behdad Esfahbod_hb_ot_layout_create (hb_face_t *face) 494a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 500a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbod hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t)); 513dcbdc2125c04c173f29f04922fc031929893f4eBehdad Esfahbod if (unlikely (!layout)) 523dcbdc2125c04c173f29f04922fc031929893f4eBehdad Esfahbod return NULL; 53555d11273ee4c30e84eda3a78ffadb3ee7da65d0Behdad Esfahbod 547c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF)); 557c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob); 5670e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 577c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB)); 587c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob); 5970e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 607c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS)); 617c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob); 620a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbod 63e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod { 64e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod /* 65e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod * The ugly business of blacklisting individual fonts' tables happen here! 66e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod * See this thread for why we finally had to bend in and do this: 67e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html 68e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod */ 69e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod unsigned int gdef_len = hb_blob_get_length (layout->gdef_blob); 70e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod unsigned int gsub_len = hb_blob_get_length (layout->gsub_blob); 71e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod unsigned int gpos_len = hb_blob_get_length (layout->gpos_blob); 72e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod if (0 73e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod || (442 == gdef_len && 42038 == gpos_len && 2874 == gsub_len) /* Windows 7 timesi.ttf */ 74e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod || (430 == gdef_len && 40662 == gpos_len && 2874 == gsub_len) /* Windows 7 timesbi.ttf */ 754f3d59a1877dcb94d09da48e9694a6c1b05a86feBehdad Esfahbod || (442 == gdef_len && 39116 == gpos_len && 2874 == gsub_len) /* Windows ??? timesi.ttf */ 764f3d59a1877dcb94d09da48e9694a6c1b05a86feBehdad Esfahbod || (430 == gdef_len && 39374 == gpos_len && 2874 == gsub_len) /* Windows ??? timesbi.ttf */ 7794dd0bb7e78125994cb7c833a5b03110f1ffc822Behdad Esfahbod || (490 == gdef_len && 41638 == gpos_len && 3046 == gsub_len) /* OS X 10.11.3 Times New Roman Italic.ttf */ 7894dd0bb7e78125994cb7c833a5b03110f1ffc822Behdad Esfahbod || (478 == gdef_len && 41902 == gpos_len && 3046 == gsub_len) /* OS X 10.11.3 Times New Roman Bold Italic.ttf */ 79e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod ) 80e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod { 81e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod /* In certain versions of Times New Roman Italic and Bold Italic, 82e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod * ASCII double quotation mark U+0022, mapped to glyph 5, has wrong 83e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod * glyph class 3 (mark) in GDEF. Nuke the GDEF to avoid zero-width 84e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod * double-quote. See: 85e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html 86e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod */ 87e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod if (3 == layout->gdef->get_glyph_class (5)) 88e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod layout->gdef = &OT::Null(OT::GDEF); 89e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod } 90e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod } 91e23cf902e91142a10229e3514be4ceee69efde04Behdad Esfahbod 926f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod layout->gsub_lookup_count = layout->gsub->get_lookup_count (); 936f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod layout->gpos_lookup_count = layout->gpos->get_lookup_count (); 946f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod 9545fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); 9645fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); 971336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 9845fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) || 9945fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod (layout->gpos_lookup_count && !layout->gpos_accels))) 1001336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod { 1011336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod _hb_ot_layout_destroy (layout); 1021336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod return NULL; 1031336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod } 1041336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 1056f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) 10645fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gsub_accels[i].init (layout->gsub->get_lookup (i)); 1076f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) 10845fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod layout->gpos_accels[i].init (layout->gpos->get_lookup (i)); 1091336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 1100a4399ca228d244e646abdb3487da0f13b228889Behdad Esfahbod return layout; 111f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 112f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 11323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodvoid 114266b34418c9bbe23ccaf29cb354b58c465fa3b22Behdad Esfahbod_hb_ot_layout_destroy (hb_ot_layout_t *layout) 115fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod{ 11645fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) 117395b35903e052aecc97d0807e4f813c64c0d2b0bBehdad Esfahbod layout->gsub_accels[i].fini (); 11845fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) 119395b35903e052aecc97d0807e4f813c64c0d2b0bBehdad Esfahbod layout->gpos_accels[i].fini (); 12045fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod 12145fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod free (layout->gsub_accels); 12245fd9424c723f115ca98995b8f8a25185a6fc71dBehdad Esfahbod free (layout->gpos_accels); 1231336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod 12489312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger hb_blob_destroy (layout->gdef_blob); 12589312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger hb_blob_destroy (layout->gsub_blob); 12689312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger hb_blob_destroy (layout->gpos_blob); 12789312b7417c0198a0635ca6b7e8ea11f6af2a4f8Bradley Grainger 1289ea7368fce3fa373d8d2925961ad211f5cf6ce70Behdad Esfahbod free (layout); 12923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod} 130f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 1317c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic inline const OT::GDEF& 13223c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gdef (hb_face_t *face) 13323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod{ 1347c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF); 135ea278d3895fe0c92801d692cd71d8d9f1de7c048Behdad Esfahbod return *hb_ot_layout_from_face (face)->gdef; 13623c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod} 1377c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic inline const OT::GSUB& 13823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gsub (hb_face_t *face) 139fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod{ 1407c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB); 141ea278d3895fe0c92801d692cd71d8d9f1de7c048Behdad Esfahbod return *hb_ot_layout_from_face (face)->gsub; 142fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod} 1437c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic inline const OT::GPOS& 14423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gpos (hb_face_t *face) 1452ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod{ 1467c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS); 147ea278d3895fe0c92801d692cd71d8d9f1de7c048Behdad Esfahbod return *hb_ot_layout_from_face (face)->gpos; 1482ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod} 1492ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod 15023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod 151590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod/* 152590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod * GDEF 153590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod */ 154590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 155590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbodhb_bool_t 15652ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbodhb_ot_layout_has_glyph_classes (hb_face_t *face) 157590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod{ 15823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return _get_gdef (face).has_glyph_classes (); 159590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod} 160590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 16101c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 16235d18585fc57750d817f57bfffe569069f9803b5Behdad Esfahbod * hb_ot_layout_get_glyph_class: 16335d18585fc57750d817f57bfffe569069f9803b5Behdad Esfahbod * 16401c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.7 16501c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 1665a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbodhb_ot_layout_glyph_class_t 1675a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbodhb_ot_layout_get_glyph_class (hb_face_t *face, 1685a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod hb_codepoint_t glyph) 1695a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod{ 1705a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); 1715a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod} 1724a2d844c2f12dc1b858ab4ddd737ded7c0852221Behdad Esfahbod 17301c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 17435d18585fc57750d817f57bfffe569069f9803b5Behdad Esfahbod * hb_ot_layout_get_glyphs_in_class: 17535d18585fc57750d817f57bfffe569069f9803b5Behdad Esfahbod * 17601c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.7 17701c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 17889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbodvoid 17989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbodhb_ot_layout_get_glyphs_in_class (hb_face_t *face, 18089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod hb_ot_layout_glyph_class_t klass, 18189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod hb_set_t *glyphs /* OUT */) 18289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod{ 18389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod return _get_gdef (face).get_glyphs_in_class (klass, glyphs); 18489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod} 18589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 186e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 1870ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_get_attach_points (hb_face_t *face, 18879420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod hb_codepoint_t glyph, 189e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 19079420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod unsigned int *point_count /* IN/OUT */, 19179420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod unsigned int *point_array /* OUT */) 19279420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod{ 193e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array); 19462964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod} 19562964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod 196e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 197e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbodhb_ot_layout_get_ligature_carets (hb_font_t *font, 198e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod hb_direction_t direction, 199e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod hb_codepoint_t glyph, 200e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod unsigned int start_offset, 201e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod unsigned int *caret_count /* IN/OUT */, 202e204674fe340a57c48a9fe7e1ed02a9a08f4aca4Behdad Esfahbod int *caret_array /* OUT */) 20362964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod{ 204abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); 20579420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod} 20679420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod 20705bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbod 208706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod/* 209706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod * GSUB/GPOS 210706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod */ 211706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 2127c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodstatic const OT::GSUBGPOS& 21323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodget_gsubgpos_table (hb_face_t *face, 21423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod hb_tag_t table_tag) 215706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 2160ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod switch (table_tag) { 21723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod case HB_OT_TAG_GSUB: return _get_gsub (face); 21823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod case HB_OT_TAG_GPOS: return _get_gpos (face); 2197c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod default: return OT::Null(OT::GSUBGPOS); 220706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod } 221706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 222706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 223706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 224e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 225bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_table_get_script_tags (hb_face_t *face, 226bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 227e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 228bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *script_count /* IN/OUT */, 229bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *script_tags /* OUT */) 230706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 2317c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 232706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 233e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return g.get_script_tags (start_offset, script_count, script_tags); 234706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 235706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 236eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod#define HB_OT_TAG_LATIN_SCRIPT HB_TAG ('l', 'a', 't', 'n') 237eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod 238706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbodhb_bool_t 2390ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_table_find_script (hb_face_t *face, 2400ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 2410ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t script_tag, 2420ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *script_index) 243706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 2447c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 2457c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 246706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 247706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod if (g.find_script_index (script_tag, script_index)) 2480594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 249706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 250706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod /* try finding 'DFLT' */ 2518a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) 2520594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 253706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 254dca8aff24652c83c53efbb9d06e5e1c7ef1c2fa5Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :(. 255dca8aff24652c83c53efbb9d06e5e1c7ef1c2fa5Behdad Esfahbod * including many versions of DejaVu Sans Mono! */ 2568a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) 2570594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 2582014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 259eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod /* try with 'latn'; some old fonts put their features there even though 260eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod they're really trying to support Thai, for example :( */ 261eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) 262eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod return false; 263eb45c0a2fbaeeb34e77a2935934e8d1302728ec8Behdad Esfahbod 2642014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 2650594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 2662014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod} 2672014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2682014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbodhb_bool_t 2692014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbodhb_ot_layout_table_choose_script (hb_face_t *face, 2702014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod hb_tag_t table_tag, 2712014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod const hb_tag_t *script_tags, 272c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod unsigned int *script_index, 273c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod hb_tag_t *chosen_script) 2742014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod{ 2757c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 2767c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 2772014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2782014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod while (*script_tags) 2792014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod { 280c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (g.find_script_index (*script_tags, script_index)) { 281c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 282c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = *script_tags; 2830594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 284c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod } 2852014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod script_tags++; 2862014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod } 2872014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2882014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod /* try finding 'DFLT' */ 289c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) { 290c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 291c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT; 2920594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 293c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod } 2942014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod 2952014b8d110231b13e524008282ece7451f1ae9e7Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 296c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) { 297c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 298c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE; 2990594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 300c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod } 301706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 30271632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod /* try with 'latn'; some old fonts put their features there even though 30371632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod they're really trying to support Thai, for example :( */ 30471632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) { 30571632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod if (chosen_script) 30671632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod *chosen_script = HB_OT_TAG_LATIN_SCRIPT; 3070594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 30871632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod } 30971632c96daa4ba15e13f4d9e7f2c121d0162614eBehdad Esfahbod 310706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 311c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod if (chosen_script) 312c47a31fb4793b825f4be57e9cb1b10db352b9512Behdad Esfahbod *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 3130594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 314706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 315706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 316e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 317bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_table_get_feature_tags (hb_face_t *face, 318bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 319e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 320bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 321bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) 322c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod{ 3237c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 324c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 325e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return g.get_feature_tags (start_offset, feature_count, feature_tags); 326c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 327c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 3280f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbodhb_bool_t 3290f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbodhb_ot_layout_table_find_feature (hb_face_t *face, 3300f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod hb_tag_t table_tag, 3310f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod hb_tag_t feature_tag, 3320f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod unsigned int *feature_index) 3330f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod{ 3340f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); 3350f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 3360f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod 3370f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod unsigned int num_features = g.get_feature_count (); 3380f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod for (unsigned int i = 0; i < num_features; i++) 3390f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod { 3400f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod if (feature_tag == g.get_feature_tag (i)) { 3410f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod if (feature_index) *feature_index = i; 3420f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod return true; 3430f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod } 3440f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod } 3450f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod 3460f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; 3470f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod return false; 3480f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod} 3490f98fe88f42471eb8fb28d08d45eca9cd8303f7aBehdad Esfahbod 350c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 351e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 352bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_script_get_language_tags (hb_face_t *face, 353bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 354bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 355e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 356bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *language_count /* IN/OUT */, 357bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *language_tags /* OUT */) 358706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 3597c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 360706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 361e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return s.get_lang_sys_tags (start_offset, language_count, language_tags); 362706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 363706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 364706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbodhb_bool_t 3650ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_script_find_language (hb_face_t *face, 3660ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 3670ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int script_index, 3680ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t language_tag, 3690ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *language_index) 370706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 3717c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX); 3727c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 373706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 3744a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (s.find_lang_sys_index (language_tag, language_index)) 3750594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 376706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 377706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 3788a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) 3790594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 380706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 3814a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; 3820594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 3834a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 384706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 3854a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbodhb_bool_t 386911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbodhb_ot_layout_language_get_required_feature_index (hb_face_t *face, 387911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod hb_tag_t table_tag, 388911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod unsigned int script_index, 389911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod unsigned int language_index, 390911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod unsigned int *feature_index) 391911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod{ 392911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod return hb_ot_layout_language_get_required_feature (face, 393911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod table_tag, 394911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod script_index, 395911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod language_index, 396911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod feature_index, 397911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod NULL); 398911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod} 399911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbod 40001c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 40135d18585fc57750d817f57bfffe569069f9803b5Behdad Esfahbod * hb_ot_layout_language_get_required_feature: 40235d18585fc57750d817f57bfffe569069f9803b5Behdad Esfahbod * 40301c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.30 40401c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 405911ca38645bd51764e7859bc482319e8f6d2f710Behdad Esfahbodhb_bool_t 406da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kewhb_ot_layout_language_get_required_feature (hb_face_t *face, 407da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew hb_tag_t table_tag, 408da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int script_index, 409da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int language_index, 410da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int *feature_index, 411da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew hb_tag_t *feature_tag) 4124a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 413da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 414da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 415706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 416da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew unsigned int index = l.get_required_feature_index (); 417da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew if (feature_index) *feature_index = index; 418da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew if (feature_tag) *feature_tag = g.get_feature_tag (index); 419706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4204a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod return l.has_required_feature (); 4214a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 422706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 423e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 424bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_language_get_feature_indexes (hb_face_t *face, 425bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 426bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 427bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int language_index, 428e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 429bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 430bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_indexes /* OUT */) 4310ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 4327c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4337c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4344a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 435e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return l.get_feature_indexes (start_offset, feature_count, feature_indexes); 436c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 437c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 438e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 439bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_language_get_feature_tags (hb_face_t *face, 440bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 441bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 442bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int language_index, 443e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 444bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 445bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) 4460ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 4477c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4487c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4494a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 450bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t)); 451e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags); 452bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 4539897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod if (feature_tags) { 4549897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod unsigned int count = *feature_count; 4559897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 4569897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]); 4579897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod } 458bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 459bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod return ret; 4604a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 4614a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 4624a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 4634a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbodhb_bool_t 4640ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_language_find_feature (hb_face_t *face, 4650ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 4660ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int script_index, 4670ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int language_index, 4680ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t feature_tag, 4690ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *feature_index) 4704a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 4717c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); 4727c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4737c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4744a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 475f4c9514935cf97a58dcb3b1962ac3f3b5ba61264Behdad Esfahbod unsigned int num_features = l.get_feature_count (); 476f4c9514935cf97a58dcb3b1962ac3f3b5ba61264Behdad Esfahbod for (unsigned int i = 0; i < num_features; i++) { 4774a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod unsigned int f_index = l.get_feature_index (i); 4784a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 4794a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_tag == g.get_feature_tag (f_index)) { 4804a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_index) *feature_index = f_index; 4810594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 4824a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod } 4834a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod } 484706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4854a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; 4860594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 487706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 488c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 48901c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 490d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * hb_ot_layout_feature_get_lookups: 491d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * 49201c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.7 49301c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 494e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 495f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbodhb_ot_layout_feature_get_lookups (hb_face_t *face, 496f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod hb_tag_t table_tag, 497f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int feature_index, 498f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int start_offset, 499f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int *lookup_count /* IN/OUT */, 500f30641038ba96e83950729b1bd9d86d2e98e46c5Behdad Esfahbod unsigned int *lookup_indexes /* OUT */) 501c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod{ 5027c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 5037c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod const OT::Feature &f = g.get_feature (feature_index); 504c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 505e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); 506c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 507c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 50801c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 509d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * hb_ot_layout_table_get_lookup_count: 510d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * 51101c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.22 51201c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 51327674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbodunsigned int 51427674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbodhb_ot_layout_table_get_lookup_count (hb_face_t *face, 51527674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod hb_tag_t table_tag) 51627674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod{ 51727674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod switch (table_tag) 51827674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod { 51927674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod case HB_OT_TAG_GSUB: 52027674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod { 52127674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod return hb_ot_layout_from_face (face)->gsub_lookup_count; 52227674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod } 52327674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod case HB_OT_TAG_GPOS: 52427674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod { 52527674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod return hb_ot_layout_from_face (face)->gpos_lookup_count; 52627674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod } 52727674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod } 5284e6e53db5da0a5da87ae732c3f9d01babf4ae6c2Behdad Esfahbod return 0; 52927674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod} 53027674b4bb351e501373bd9994e4ba6546e465cf7Behdad Esfahbod 531a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodstatic void 532a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod_hb_ot_layout_collect_lookups_lookups (hb_face_t *face, 533a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 534a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int feature_index, 535a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 536a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 537a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int lookup_indices[32]; 538a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int offset, len; 539a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 540a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod offset = 0; 541a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod do { 542a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod len = ARRAY_LENGTH (lookup_indices); 543a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_ot_layout_feature_get_lookups (face, 544a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod table_tag, 545a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod feature_index, 546a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod offset, &len, 547a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod lookup_indices); 548a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 549a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (unsigned int i = 0; i < len; i++) 550a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod lookup_indexes->add (lookup_indices[i]); 551a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 552a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod offset += len; 553a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } while (len == ARRAY_LENGTH (lookup_indices)); 554a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 555a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 556a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodstatic void 557a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod_hb_ot_layout_collect_lookups_features (hb_face_t *face, 558a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 559a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int script_index, 560a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int language_index, 561a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *features, 562a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 563a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 564a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod if (!features) 565a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 5665f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod unsigned int required_feature_index; 567da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew if (hb_ot_layout_language_get_required_feature (face, 568da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew table_tag, 569da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew script_index, 570da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew language_index, 571da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew &required_feature_index, 572da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew NULL)) 5735f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod _hb_ot_layout_collect_lookups_lookups (face, 5745f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod table_tag, 5755f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod required_feature_index, 5765f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod lookup_indexes); 5775f85c80a07dd2d18348824866bf4e984ac711a24Behdad Esfahbod 578a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod /* All features */ 57915e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod unsigned int feature_indices[32]; 58015e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod unsigned int offset, len; 58115e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod 58215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod offset = 0; 58315e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod do { 58415e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod len = ARRAY_LENGTH (feature_indices); 58515e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod hb_ot_layout_language_get_feature_indexes (face, 58615e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod table_tag, 58715e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod script_index, 58815e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod language_index, 58915e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod offset, &len, 59015e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod feature_indices); 59115e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod 59215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod for (unsigned int i = 0; i < len; i++) 59315e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod _hb_ot_layout_collect_lookups_lookups (face, 59415e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod table_tag, 59515e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod feature_indices[i], 59615e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod lookup_indexes); 59715e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod 59815e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod offset += len; 59915e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } while (len == ARRAY_LENGTH (feature_indices)); 60015e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } 60115e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod else 60215e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 603a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (; *features; features++) 604a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 605a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int feature_index; 606733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod if (hb_ot_layout_language_find_feature (face, 607733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 608733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 609733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod language_index, 610733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod *features, 611733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod &feature_index)) 612733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_lookups (face, 613733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 614733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod feature_index, 615733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 616a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 617a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 618a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 619a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 620a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodstatic void 621a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod_hb_ot_layout_collect_lookups_languages (hb_face_t *face, 622a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 623a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int script_index, 624a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *languages, 625a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *features, 626a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 627a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 628f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod _hb_ot_layout_collect_lookups_features (face, 629f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod table_tag, 630f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod script_index, 631f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, 632f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod features, 633f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod lookup_indexes); 634f0c82410dbe800cb6429ba4aa7cfd9f5a11cc70cBehdad Esfahbod 635a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod if (!languages) 636a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 637a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod /* All languages */ 638733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod unsigned int count = hb_ot_layout_script_get_language_tags (face, 639733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 640733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 641733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod 0, NULL, NULL); 642a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (unsigned int language_index = 0; language_index < count; language_index++) 643733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_features (face, 644733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 645733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 646733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod language_index, 647733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 648733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 64915e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } 65015e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod else 65115e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 652a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (; *languages; languages++) 653a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 654a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int language_index; 655733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod if (hb_ot_layout_script_find_language (face, 656733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 657733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 658733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod *languages, 659733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod &language_index)) 660733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_features (face, 661733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 662733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 663733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod language_index, 664733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 665733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 666a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 667a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 668a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 669a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 67001c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 671d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * hb_ot_layout_collect_lookups: 672d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * 67301c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.8 67401c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 675a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodvoid 676a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbodhb_ot_layout_collect_lookups (hb_face_t *face, 677a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_tag_t table_tag, 678a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *scripts, 679a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *languages, 680a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod const hb_tag_t *features, 681a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod hb_set_t *lookup_indexes /* OUT */) 682a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod{ 683a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod if (!scripts) 684a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 685a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod /* All scripts */ 686733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod unsigned int count = hb_ot_layout_table_get_script_tags (face, 687733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 688733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod 0, NULL, NULL); 689a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (unsigned int script_index = 0; script_index < count; script_index++) 690733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_languages (face, 691733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 692733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 693733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod languages, 694733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 695733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 69615e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod } 69715e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod else 69815e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 699a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod for (; *scripts; scripts++) 700a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod { 701a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod unsigned int script_index; 702733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod if (hb_ot_layout_table_find_script (face, 703733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 704733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod *scripts, 705733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod &script_index)) 706733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod _hb_ot_layout_collect_lookups_languages (face, 707733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod table_tag, 708733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod script_index, 709733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod languages, 710733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod features, 711733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod lookup_indexes); 712a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 713a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod } 714a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod} 715a88e7160217b9f44e4e5b4b814d0ca98c457ee40Behdad Esfahbod 71601c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 717d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * hb_ot_layout_lookup_collect_glyphs: 718d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * 71901c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.7 72001c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 721e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbodvoid 722e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbodhb_ot_layout_lookup_collect_glyphs (hb_face_t *face, 723e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_tag_t table_tag, 724e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int lookup_index, 725e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_before, /* OUT. May be NULL */ 726e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_input, /* OUT. May be NULL */ 727e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_after, /* OUT. May be NULL */ 728e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_output /* OUT. May be NULL */) 729e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod{ 730e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; 731e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 732733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod OT::hb_collect_glyphs_context_t c (face, 733733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_before, 734733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_input, 735733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_after, 736733e8c0d7bf0765884f2cc953c8edcd7ab7fb49bBehdad Esfahbod glyphs_output); 737e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 73815e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod switch (table_tag) 73915e9e4e1ddaad655988144e7a56a765e8adf8782Behdad Esfahbod { 740e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod case HB_OT_TAG_GSUB: 741e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 742cdd756b9f40665a201f5c4e65a87b9a27c390601Behdad Esfahbod const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); 743780cd930a974165d76dbf7a87701d11b7f15db06Behdad Esfahbod l.collect_glyphs (&c); 744e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod return; 745e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 746e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod case HB_OT_TAG_GPOS: 747e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 748cdd756b9f40665a201f5c4e65a87b9a27c390601Behdad Esfahbod const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index); 749780cd930a974165d76dbf7a87701d11b7f15db06Behdad Esfahbod l.collect_glyphs (&c); 750e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod return; 751e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 752e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 753e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod} 754e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 7552d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 7562d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod/* 7577c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod * OT::GSUB 7582d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod */ 7592d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 7602d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbodhb_bool_t 7610ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_has_substitution (hb_face_t *face) 7620ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 7637c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod return &_get_gsub (face) != &OT::Null(OT::GSUB); 7640ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 7650ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 76601c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 767d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * hb_ot_layout_lookup_would_substitute: 768d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * 76901c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.7 77001c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 771e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodhb_bool_t 772362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbodhb_ot_layout_lookup_would_substitute (hb_face_t *face, 773d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod unsigned int lookup_index, 774e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const hb_codepoint_t *glyphs, 775e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int glyphs_length, 776d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod hb_bool_t zero_context) 777e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 7786f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false; 779362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbod return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context); 780e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 781e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 782f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbodhb_bool_t 783362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbodhb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, 784d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod unsigned int lookup_index, 785f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod const hb_codepoint_t *glyphs, 786f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod unsigned int glyphs_length, 787d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod hb_bool_t zero_context) 788f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod{ 7896f7611375521c6d285a9aa763f2ea5cb44cd0d39Behdad Esfahbod if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false; 790ea512f71084296be3bd893f78650def894066de0Behdad Esfahbod OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context); 7912bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod 7922bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); 7932bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod 794241eac9559465fa79f396570af4e87f455b7e9d5Behdad Esfahbod return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index]); 795f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod} 796f860366456d9e59b139a940da6d89c3c4fb9e96eBehdad Esfahbod 79746d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbodvoid 798afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbodhb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) 79946d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod{ 8007c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod OT::GSUB::substitute_start (font, buffer); 80146d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod} 80246d6a21cc8613519e6ce27b1925e29285cccb71dBehdad Esfahbod 80301c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 804d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * hb_ot_layout_lookup_substitute_closure: 805d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * 80601c3a88543850c87483fd8671044df53b368c520Sascha Brawer * Since: 0.9.7 80701c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 8085caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbodvoid 809362a990b2246f5448ecb9d600761f710aea7d42dBehdad Esfahbodhb_ot_layout_lookup_substitute_closure (hb_face_t *face, 810d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod unsigned int lookup_index, 811d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod hb_set_t *glyphs) 812f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod{ 8139b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod OT::hb_closure_context_t c (face, glyphs); 8149b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 8159b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); 8169b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 8179b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod l.closure (&c); 818f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod} 819bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 8209c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod/* 8217c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod * OT::GPOS 8229c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod */ 8239c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod 8249c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbodhb_bool_t 8250ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_has_positioning (hb_face_t *face) 8260ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 8277c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod return &_get_gpos (face) != &OT::Null(OT::GPOS); 8280ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 8290ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 8308f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbodvoid 83105bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbodhb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) 8328f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod{ 8337c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod OT::GPOS::position_start (font, buffer); 8348f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod} 8358f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 8369db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbodvoid 8377d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbodhb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer) 8387d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbod{ 8397d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbod OT::GPOS::position_finish_advances (font, buffer); 8407d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbod} 8417d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbod 8427d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbodvoid 8437d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbodhb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) 8449db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod{ 8457d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40fBehdad Esfahbod OT::GPOS::position_finish_offsets (font, buffer); 8469db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod} 847f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 84801c3a88543850c87483fd8671044df53b368c520Sascha Brawer/** 849d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * hb_ot_layout_get_size_params: 850d7bf9d05c519a369a7b3a02e9ed5ecc05a20cd3eKhaled Hosny * 851b8811429b6810c4f13be087b593a862c17d9d987Behdad Esfahbod * Since: 0.9.10 85201c3a88543850c87483fd8671044df53b368c520Sascha Brawer **/ 853f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodhb_bool_t 854875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbodhb_ot_layout_get_size_params (hb_face_t *face, 855875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *design_size, /* OUT. May be NULL */ 856875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *subfamily_id, /* OUT. May be NULL */ 857875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *subfamily_name_id, /* OUT. May be NULL */ 858875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *range_start, /* OUT. May be NULL */ 859875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod unsigned int *range_end /* OUT. May be NULL */) 860f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 861f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod const OT::GPOS &gpos = _get_gpos (face); 862efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod const hb_tag_t tag = HB_TAG ('s','i','z','e'); 863f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 8640dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod unsigned int num_features = gpos.get_feature_count (); 8650dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod for (unsigned int i = 0; i < num_features; i++) 8660dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod { 867efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == gpos.get_feature_tag (i)) 868f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod { 8690dff11f6bfbda444a153ca75ff2b947f94e9b3c5Behdad Esfahbod const OT::Feature &f = gpos.get_feature (i); 870efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod const OT::FeatureParamsSize ¶ms = f.get_feature_params ().get_size_params (tag); 871f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 872efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (params.designSize) 87385bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod { 874efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod#define PARAM(a, A) if (a) *a = params.A 87585bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (design_size, designSize); 87685bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (subfamily_id, subfamilyID); 87785bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (subfamily_name_id, subfamilyNameID); 87885bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (range_start, rangeStart); 87985bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod PARAM (range_end, rangeEnd); 88085bc44b90a19c6a669ed567a9cd8513448600afeBehdad Esfahbod#undef PARAM 881efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 882efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return true; 883efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod } 884f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 885f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 886f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 887875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod#define PARAM(a, A) if (a) *a = 0 888efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (design_size, designSize); 889efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (subfamily_id, subfamilyID); 890efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (subfamily_name_id, subfamilyNameID); 891efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (range_start, rangeStart); 892efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod PARAM (range_end, rangeEnd); 893875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod#undef PARAM 894f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 895efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return false; 896f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod} 897d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 898d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 899d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod/* 900bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod * Parts of different types are implemented here such that they have direct 901d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod * access to GSUB/GPOS lookups. 902d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod */ 903d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 904d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 905bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodstruct GSUBProxy 906bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod{ 907bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod static const unsigned int table_index = 0; 9086ffc007b61402c9d1d4de368deed4971a10ed00bBehdad Esfahbod static const bool inplace = false; 909bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod typedef OT::SubstLookup Lookup; 910bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 911bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GSUBProxy (hb_face_t *face) : 912bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod table (*hb_ot_layout_from_face (face)->gsub), 913bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod accels (hb_ot_layout_from_face (face)->gsub_accels) {} 914bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 915bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const OT::GSUB &table; 916bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t *accels; 917bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod}; 918bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 919bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodstruct GPOSProxy 920bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod{ 921bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod static const unsigned int table_index = 1; 9226ffc007b61402c9d1d4de368deed4971a10ed00bBehdad Esfahbod static const bool inplace = true; 923bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod typedef OT::PosLookup Lookup; 924bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 925bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GPOSProxy (hb_face_t *face) : 926bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod table (*hb_ot_layout_from_face (face)->gpos), 927bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod accels (hb_ot_layout_from_face (face)->gpos_accels) {} 928bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 929bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const OT::GPOS &table; 930bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t *accels; 931bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod}; 932bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 933bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 9343e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbodstruct hb_get_subtables_context_t : 9353e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY> 9363e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod{ 9373e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod template <typename Type> 9383e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c) 9393e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 9403e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod const Type *typed_obj = (const Type *) obj; 9413e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod return typed_obj->apply (c); 9423e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod } 9433e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9443e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_apply_context_t *c); 9453e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9463e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod struct hb_applicable_t 9473e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 9483e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod inline void init (const void *obj_, hb_apply_func_t apply_func_) 9493e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 9503e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod obj = obj_; 9513e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod apply_func = apply_func_; 9523e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod } 9533e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9543e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj, c); } 9553e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9563e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod private: 9573e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod const void *obj; 9583e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod hb_apply_func_t apply_func; 9593e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod }; 9603e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9613e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod typedef hb_auto_array_t<hb_applicable_t> array_t; 9623e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9633e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod /* Dispatch interface. */ 9643e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod inline const char *get_name (void) { return "GET_SUBTABLES"; } 9653e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod template <typename T> 9663e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod inline return_t dispatch (const T &obj) 9673e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 9683e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod hb_applicable_t *entry = array.push(); 9693e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod if (likely (entry)) 9703e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod entry->init (&obj, apply_to<T>); 9713e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod return HB_VOID; 9723e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod } 9733e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod static return_t default_return_value (void) { return HB_VOID; } 9743e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 9753e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9763e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod hb_get_subtables_context_t (array_t &array_) : 9773e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod array (array_), 9783e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod debug_depth (0) {} 9793e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 9803e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod array_t &array; 9813e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod unsigned int debug_depth; 9823e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod}; 9833e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 984e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbodstatic inline bool 985e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbodapply_forward (OT::hb_apply_context_t *c, 9863e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t &accel, 9873e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod const hb_get_subtables_context_t::array_t &subtables) 988e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod{ 989e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod bool ret = false; 990e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 991abadc1717d997b69f987fdf1be9e12156d2d13d6Behdad Esfahbod while (buffer->idx < buffer->len && !buffer->in_error) 992e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod { 9933e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod bool applied = false; 994e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod if (accel.may_have (buffer->cur().codepoint) && 995e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod (buffer->cur().mask & c->lookup_mask) && 9963e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod c->check_glyph_property (&buffer->cur(), c->lookup_props)) 9973e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 9983e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod for (unsigned int i = 0; i < subtables.len; i++) 9993e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod if (subtables[i].apply (c)) 10003e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 10013e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod applied = true; 10023e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod break; 10033e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod } 10043e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod } 10053e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 10063e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod if (applied) 1007e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod ret = true; 1008e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod else 1009e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod buffer->next_glyph (); 1010e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod } 1011e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod return ret; 1012e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod} 1013e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod 1014e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbodstatic inline bool 1015e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbodapply_backward (OT::hb_apply_context_t *c, 10163e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t &accel, 10173e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod const hb_get_subtables_context_t::array_t &subtables) 1018e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod{ 1019e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod bool ret = false; 1020e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 1021e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod do 1022e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod { 1023e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod if (accel.may_have (buffer->cur().codepoint) && 1024e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod (buffer->cur().mask & c->lookup_mask) && 10253e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod c->check_glyph_property (&buffer->cur(), c->lookup_props)) 10263e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 10273e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod for (unsigned int i = 0; i < subtables.len; i++) 10283e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod if (subtables[i].apply (c)) 10293e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod { 10303e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod ret = true; 10313e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod break; 10323e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod } 10333e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod } 1034e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod /* The reverse lookup doesn't "advance" cursor (for good reason). */ 1035e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod buffer->idx--; 1036e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod 1037e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod } 1038e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod while ((int) buffer->idx >= 0); 1039e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod return ret; 1040e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod} 1041e2f50f2a7ebf9882ea89dc3f0c740e7fce964e37Behdad Esfahbod 104245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbodtemplate <typename Proxy> 10431d4a328472f094c0d75a062f6e176c6b1875cfdcBehdad Esfahbodstatic inline void 104445f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbodapply_string (OT::hb_apply_context_t *c, 104545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod const typename Proxy::Lookup &lookup, 104645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod const hb_ot_layout_lookup_accelerator_t &accel) 104745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod{ 1048ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 104945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 10505337db29af39084d677a63154f404eca0c20cfebBehdad Esfahbod if (unlikely (!buffer->len || !c->lookup_mask)) 10511d4a328472f094c0d75a062f6e176c6b1875cfdcBehdad Esfahbod return; 105245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 10532c8b3b2e5312c9858584f568b1528c57e5bb8a10Behdad Esfahbod c->set_lookup_props (lookup.get_props ()); 105445f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 10553e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod hb_get_subtables_context_t::array_t subtables; 10563e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod hb_get_subtables_context_t c_get_subtables (subtables); 10573e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod lookup.dispatch (&c_get_subtables); 10583e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod 105945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod if (likely (!lookup.is_reverse ())) 106045f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod { 106145f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod /* in/out forward substitution/positioning */ 106245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod if (Proxy::table_index == 0) 1063ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->clear_output (); 1064ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->idx = 0; 106545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 1066640b66c6348653bfd7cf88ea9caa2133c0eb949fBehdad Esfahbod bool ret; 10673e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod ret = apply_forward (c, accel, subtables); 1068640b66c6348653bfd7cf88ea9caa2133c0eb949fBehdad Esfahbod if (ret) 10699d9e72e94e7914f82ce62a304e7242f79c13edafBehdad Esfahbod { 10706ffc007b61402c9d1d4de368deed4971a10ed00bBehdad Esfahbod if (!Proxy::inplace) 1071ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->swap_buffers (); 10729d9e72e94e7914f82ce62a304e7242f79c13edafBehdad Esfahbod else 10731d4a328472f094c0d75a062f6e176c6b1875cfdcBehdad Esfahbod assert (!buffer->has_separate_output ()); 10749d9e72e94e7914f82ce62a304e7242f79c13edafBehdad Esfahbod } 107545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod } 107645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod else 107745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod { 107845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod /* in-place backward substitution/positioning */ 107945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod if (Proxy::table_index == 0) 1080ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->remove_output (); 1081ac8cd511911c7dca6222d14fa758bff75d601567Behdad Esfahbod buffer->idx = buffer->len - 1; 108245f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 10833e704521f67e021fb51cda7319925fd39eba4f97Behdad Esfahbod apply_backward (c, accel, subtables); 108445f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod } 108545f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod} 108645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod 1087bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodtemplate <typename Proxy> 1088bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodinline void hb_ot_map_t::apply (const Proxy &proxy, 1089d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod const hb_ot_shape_plan_t *plan, 1090d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod hb_font_t *font, 1091d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod hb_buffer_t *buffer) const 1092d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod{ 1093bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const unsigned int table_index = proxy.table_index; 1094d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod unsigned int i = 0; 1095bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod OT::hb_apply_context_t c (table_index, font, buffer); 109645f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod c.set_recurse_func (Proxy::Lookup::apply_recurse_func); 1097d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 1098d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { 1099d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod const stage_map_t *stage = &stages[table_index][stage_index]; 1100d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod for (; i < stage->last_lookup; i++) 1101bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod { 1102bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod unsigned int lookup_index = lookups[table_index][i].index; 11030475ef2f97e3035a2eea9a0f96031331e07e8e29Behdad Esfahbod if (!buffer->message (font, "start lookup %d", lookup_index)) continue; 11042c8b3b2e5312c9858584f568b1528c57e5bb8a10Behdad Esfahbod c.set_lookup_index (lookup_index); 1105bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod c.set_lookup_mask (lookups[table_index][i].mask); 1106bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod c.set_auto_zwj (lookups[table_index][i].auto_zwj); 110745f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod apply_string<Proxy> (&c, 110845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod proxy.table.get_lookup (lookup_index), 110945f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod proxy.accels[lookup_index]); 11100475ef2f97e3035a2eea9a0f96031331e07e8e29Behdad Esfahbod (void) buffer->message (font, "end lookup %d", lookup_index); 1111bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod } 1112d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 1113d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod if (stage->pause_func) 1114d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod { 1115d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod buffer->clear_output (); 1116d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod stage->pause_func (plan, font, buffer); 1117d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod } 1118d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod } 1119d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod} 1120d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 1121d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbodvoid hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 1122d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod{ 1123bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GSUBProxy proxy (font->face); 1124bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod apply (proxy, plan, font, buffer); 1125d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod} 1126d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod 1127d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbodvoid hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 1128d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod{ 1129bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod GPOSProxy proxy (font->face); 1130bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod apply (proxy, plan, font, buffer); 1131bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod} 1132bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod 1133bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad EsfahbodHB_INTERNAL void 1134bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbodhb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, 1135bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const OT::SubstLookup &lookup, 1136bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod const hb_ot_layout_lookup_accelerator_t &accel) 1137bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod{ 113845f3d980c9503bd94e64f6e3f67f97688347d00cBehdad Esfahbod apply_string<GSUBProxy> (c, lookup, accel); 1139d2c96819de9a7428b65ef0adf794416224221f36Behdad Esfahbod} 1140