hb-ot-layout.cc revision 52ea47767c7c35650ebddfba6ddc8203a3e33d3a
1fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod/* 26f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod * Copyright (C) 1998-2004 David Turner and Werner Lemberg 36f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod * Copyright (C) 2006 Behdad Esfahbod 4ee58aaebd296ea8237516754fd4e825d524b11b7Behdad Esfahbod * Copyright (C) 2007,2008,2009 Red Hat, Inc. 5fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 6fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library. 7fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 8fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * Permission is hereby granted, without written agreement and without 9fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 10fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * software and its documentation for any purpose, provided that the 11fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * above copyright notice and the following two paragraphs appear in 12fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * all copies of this software. 13fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 14fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * DAMAGE. 19fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 20fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * 26fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 27fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod */ 28fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 29fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#define HB_OT_LAYOUT_CC 30fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 31fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#include "hb-ot-layout-private.h" 32fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 335f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#include "hb-ot-layout-gdef-private.hh" 345f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#include "hb-ot-layout-gsub-private.hh" 355f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#include "hb-ot-layout-gpos-private.hh" 36fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 376f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod 38fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#include <stdlib.h> 39aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod#include <string.h> 40aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 41fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 420ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodvoid 4370e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod_hb_ot_layout_init (hb_face_t *face) 444a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 4570e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_ot_layout_t *layout = &face->ot_layout; 4670e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 47d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_get_table (face, HB_OT_TAG_GDEF)); 48d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod layout->gdef = &Sanitizer<GDEF>::lock_instance (layout->gdef_blob); 4970e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 50d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_get_table (face, HB_OT_TAG_GSUB)); 51d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod layout->gsub = &Sanitizer<GSUB>::lock_instance (layout->gsub_blob); 5270e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 53d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_get_table (face, HB_OT_TAG_GPOS)); 54d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod layout->gpos = &Sanitizer<GPOS>::lock_instance (layout->gpos_blob); 55f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 56f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 5723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodvoid 5870e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod_hb_ot_layout_fini (hb_face_t *face) 59fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod{ 6070e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_ot_layout_t *layout = &face->ot_layout; 61fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 6270e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_blob_unlock (layout->gdef_blob); 6370e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_blob_unlock (layout->gsub_blob); 6470e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_blob_unlock (layout->gpos_blob); 6570e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod 6670e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_blob_destroy (layout->gdef_blob); 6770e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_blob_destroy (layout->gsub_blob); 6870e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod hb_blob_destroy (layout->gpos_blob); 69679f41fe61242aa8d7f45b64bdb66395aa530fe2Behdad Esfahbod 70679f41fe61242aa8d7f45b64bdb66395aa530fe2Behdad Esfahbod free (layout->new_gdef.klasses); 7123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod} 72f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 7323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodstatic const GDEF& 7423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gdef (hb_face_t *face) 7523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod{ 7670e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod return HB_LIKELY (face->ot_layout.gdef) ? *face->ot_layout.gdef : Null(GDEF); 7723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod} 78f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 7923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodstatic const GSUB& 8023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gsub (hb_face_t *face) 81fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod{ 8270e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod return HB_LIKELY (face->ot_layout.gsub) ? *face->ot_layout.gsub : Null(GSUB); 83fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod} 84fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 8523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodstatic const GPOS& 8623c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_get_gpos (hb_face_t *face) 872ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod{ 8870e0f2a75ec1559f2f70ada837ce4bc4baca49e3Behdad Esfahbod return HB_LIKELY (face->ot_layout.gpos) ? *face->ot_layout.gpos : Null(GPOS); 892ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod} 902ebb89d63dd27e800f2b6cbf624924601105f48aBehdad Esfahbod 9123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod 92590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod/* 93590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod * GDEF 94590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod */ 95590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 96d6aae5f5cad54fc5dac8b0ff10a3921ebda533d4Behdad Esfahbod/* TODO the public class_t is a mess */ 9730bd763fa2fa4aceee51433ec9fc8dc28480b5d7Behdad Esfahbod 98590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbodhb_bool_t 9952ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbodhb_ot_layout_has_glyph_classes (hb_face_t *face) 100590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod{ 10123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return _get_gdef (face).has_glyph_classes (); 102590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod} 103590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 104081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodhb_bool_t 10523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_hb_ot_layout_has_new_glyph_classes (hb_face_t *face) 106590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod{ 10723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return face->ot_layout.new_gdef.len > 0; 108590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod} 109590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 11023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodstatic unsigned int 11123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_hb_ot_layout_get_glyph_property (hb_face_t *face, 11230bd763fa2fa4aceee51433ec9fc8dc28480b5d7Behdad Esfahbod hb_codepoint_t glyph) 113ead428d7a0bf4dc84340a99f3959e5cc58123e99Behdad Esfahbod{ 114aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod hb_ot_layout_class_t klass; 11523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GDEF &gdef = _get_gdef (face); 116aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 11723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod klass = gdef.get_glyph_class (glyph); 118ead428d7a0bf4dc84340a99f3959e5cc58123e99Behdad Esfahbod 11923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod if (!klass && glyph < face->ot_layout.new_gdef.len) 12023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod klass = face->ot_layout.new_gdef.klasses[glyph]; 121aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 122aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod switch (klass) { 123aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod default: 124aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case GDEF::UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED; 125aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case GDEF::BaseGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH; 126aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case GDEF::LigatureGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE; 127aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case GDEF::ComponentGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT; 1285130c35e93528bcf3095fee5baf3847589167a58Behdad Esfahbod case GDEF::MarkGlyph: 12923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod klass = gdef.get_mark_attachment_type (glyph); 13009c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod return HB_OT_LAYOUT_GLYPH_CLASS_MARK + (klass << 8); 131aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod } 132ead428d7a0bf4dc84340a99f3959e5cc58123e99Behdad Esfahbod} 133fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 134081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodhb_bool_t 13523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_hb_ot_layout_check_glyph_property (hb_face_t *face, 136f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod hb_internal_glyph_info_t *ginfo, 13723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod unsigned int lookup_flags, 13823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod unsigned int *property_out) 139590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod{ 1404189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod unsigned int property; 1416f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod 142f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN) 14323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint); 144f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod property = ginfo->gproperty; 1454189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (property_out) 1464189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod *property_out = property; 1476f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod 1484189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod /* Not covered, if, for example, glyph class is ligature and 1491246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod * lookup_flags includes LookupFlags::IgnoreLigatures 1506f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod */ 151aa87d951739f6beacb66daa235cd033fdcfcadd7Behdad Esfahbod if (property & lookup_flags & LookupFlag::IgnoreFlags) 1526f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod return false; 1536f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod 1544189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) 155590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod { 1561246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod /* If using mark filtering sets, the high short of 1574189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod * lookup_flags has the set index. 1581246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod */ 1591246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod if (lookup_flags & LookupFlag::UseMarkFilteringSet) 16023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return _get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint); 1611246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod 1621246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod /* The second byte of lookup_flags has the meaning 1631246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod * "ignore marks of attachment type different than 1641246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod * the attachment type specified." 1651246e41021ab1d782b4c97e5d81c4917a57e3ed4Behdad Esfahbod */ 1664189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType) 1674189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod return (lookup_flags & LookupFlag::MarkAttachmentType) == (property & LookupFlag::MarkAttachmentType); 168590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod } 169590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 1706f425b11799aa20dab553085f05744191b7318e2Behdad Esfahbod return true; 171590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod} 172590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 173081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodhb_bool_t 17423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_hb_ot_layout_skip_mark (hb_face_t *face, 175f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod hb_internal_glyph_info_t *ginfo, 17623c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod unsigned int lookup_flags, 17723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod unsigned int *property_out) 1784189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod{ 1794189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod unsigned int property; 1804189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod 181f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN) 18223c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint); 183f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod property = ginfo->gproperty; 1844189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (property_out) 1854189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod *property_out = property; 1864189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod 1874189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) 1884189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod { 1894189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod /* Skip mark if lookup_flags includes LookupFlags::IgnoreMarks */ 1904189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (lookup_flags & LookupFlag::IgnoreMarks) 1914189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod return true; 1924189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod 1934189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod /* If using mark filtering sets, the high short of lookup_flags has the set index. */ 1944189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (lookup_flags & LookupFlag::UseMarkFilteringSet) 19523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return !_get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint); 1964189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod 1974189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod /* The second byte of lookup_flags has the meaning "ignore marks of attachment type 1984189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod * different than the attachment type specified." */ 1994189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType) 2004189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod return (lookup_flags & LookupFlag::MarkAttachmentType) != (property & LookupFlag::MarkAttachmentType); 2014189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod } 2024189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod 2034189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod return false; 2044189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod} 2054189b92aaa41e4a1756c561cc6e08b0ed024afdaBehdad Esfahbod 206081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 20723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_hb_ot_layout_set_glyph_class (hb_face_t *face, 2080ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_codepoint_t glyph, 2090ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_ot_layout_glyph_class_t klass) 210aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod{ 21123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod if (HB_OBJECT_IS_INERT (face)) 21223c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return; 21323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod 2142c80296aa5991ad67483889147f5c84fefe54af2Behdad Esfahbod /* TODO optimize this? similar to old harfbuzz code for example */ 215aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 21623c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod hb_ot_layout_t *layout = &face->ot_layout; 217aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod hb_ot_layout_class_t gdef_klass; 21815164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod unsigned int len = layout->new_gdef.len; 219aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 2204acaffd786a11b5bd7d41b39fc65625fd8cd5077Behdad Esfahbod if (HB_UNLIKELY (glyph > 65535)) 22130bd763fa2fa4aceee51433ec9fc8dc28480b5d7Behdad Esfahbod return; 22230bd763fa2fa4aceee51433ec9fc8dc28480b5d7Behdad Esfahbod 2232c80296aa5991ad67483889147f5c84fefe54af2Behdad Esfahbod /* XXX this is not threadsafe */ 224aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod if (glyph >= len) { 22537006bd1bd107ac1a1c1b131579e9c494ba3a20fBehdad Esfahbod unsigned int new_len; 226590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod unsigned char *new_klasses; 227aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 228aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod new_len = len == 0 ? 120 : 2 * len; 22937006bd1bd107ac1a1c1b131579e9c494ba3a20fBehdad Esfahbod while (new_len <= glyph) 23037006bd1bd107ac1a1c1b131579e9c494ba3a20fBehdad Esfahbod new_len *= 2; 23137006bd1bd107ac1a1c1b131579e9c494ba3a20fBehdad Esfahbod 232f0c7540c4e217a7354072365a7301453d1e25b80Behdad Esfahbod if (new_len > 65536) 233f0c7540c4e217a7354072365a7301453d1e25b80Behdad Esfahbod new_len = 65536; 234590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod new_klasses = (unsigned char *) realloc (layout->new_gdef.klasses, new_len * sizeof (unsigned char)); 235aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 2364acaffd786a11b5bd7d41b39fc65625fd8cd5077Behdad Esfahbod if (HB_UNLIKELY (!new_klasses)) 237aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod return; 238ce48f03946bef895912019046bdbe62bb1301d0bBehdad Esfahbod 239aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod memset (new_klasses + len, 0, new_len - len); 240aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 241aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod layout->new_gdef.klasses = new_klasses; 242aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod layout->new_gdef.len = new_len; 243aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod } 244aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 245aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod switch (klass) { 246aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod default: 247aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: gdef_klass = GDEF::UnclassifiedGlyph; break; 248aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: gdef_klass = GDEF::BaseGlyph; break; 249aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: gdef_klass = GDEF::LigatureGlyph; break; 250aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case HB_OT_LAYOUT_GLYPH_CLASS_MARK: gdef_klass = GDEF::MarkGlyph; break; 251aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod case HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT: gdef_klass = GDEF::ComponentGlyph; break; 252aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod } 253aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod 254aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod layout->new_gdef.klasses[glyph] = gdef_klass; 255aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod return; 256aff831ed6787abe8e24a977e34d97ff2e0b7dc21Behdad Esfahbod} 257590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 258081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 25923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod_hb_ot_layout_set_glyph_property (hb_face_t *face, 2600ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_codepoint_t glyph, 2610ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int property) 26223c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod{ _hb_ot_layout_set_glyph_class (face, glyph, (hb_ot_layout_glyph_class_t) (property & 0xff)); } 2630ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 2640ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 2650ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_glyph_class_t 2660ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_get_glyph_class (hb_face_t *face, 2670ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_codepoint_t glyph) 2680ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 26923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return (hb_ot_layout_glyph_class_t) (_hb_ot_layout_get_glyph_property (face, glyph) & 0xff); 2700ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 2710ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 272590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbodvoid 2730ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_set_glyph_class (hb_face_t *face, 2740ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_codepoint_t glyph, 2750ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_ot_layout_glyph_class_t klass) 2760ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 27723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod _hb_ot_layout_set_glyph_class (face, glyph, klass); 2780ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 2790ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 2800ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodvoid 2810ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_build_glyph_classes (hb_face_t *face, 282e50c3978d37b2c0d6ddd4ced6a6196f6857cd596Behdad Esfahbod uint16_t num_total_glyphs, 2832d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod hb_codepoint_t *glyphs, 284e50c3978d37b2c0d6ddd4ced6a6196f6857cd596Behdad Esfahbod unsigned char *klasses, 285e50c3978d37b2c0d6ddd4ced6a6196f6857cd596Behdad Esfahbod uint16_t count) 286590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod{ 28723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod if (HB_OBJECT_IS_INERT (face)) 28823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return; 28923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod 29023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod hb_ot_layout_t *layout = &face->ot_layout; 2910ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 2924acaffd786a11b5bd7d41b39fc65625fd8cd5077Behdad Esfahbod if (HB_UNLIKELY (!count || !glyphs || !klasses)) 293590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod return; 294590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 295590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod if (layout->new_gdef.len == 0) { 296590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod layout->new_gdef.klasses = (unsigned char *) calloc (num_total_glyphs, sizeof (unsigned char)); 297590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod layout->new_gdef.len = count; 298590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod } 299590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod 300f4c9514935cf97a58dcb3b1962ac3f3b5ba61264Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 30123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod _hb_ot_layout_set_glyph_class (face, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]); 302590d55cbb9e21ef74dfd88eee51fd0a763958cd2Behdad Esfahbod} 303706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 304e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 3050ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_get_attach_points (hb_face_t *face, 30679420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod hb_codepoint_t glyph, 307e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 30879420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod unsigned int *point_count /* IN/OUT */, 30979420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod unsigned int *point_array /* OUT */) 31079420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod{ 311e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array); 31262964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod} 31362964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod 314e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 31552ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbodhb_ot_layout_get_lig_carets (hb_font_t *font, 31652ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbod hb_face_t *face, 31762964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod hb_codepoint_t glyph, 318e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 31962964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod unsigned int *caret_count /* IN/OUT */, 32062964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod int *caret_array /* OUT */) 32162964afcecd96038cfaa8bc2bc931f43ee83be7eBehdad Esfahbod{ 3220ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_ot_layout_context_t context; 3230ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod context.font = font; 32423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod context.face = face; 325e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return _get_gdef (face).get_lig_carets (&context, glyph, start_offset, caret_count, caret_array); 32679420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod} 32779420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod 328706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod/* 329706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod * GSUB/GPOS 330706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod */ 331706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 332706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbodstatic const GSUBGPOS& 33323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbodget_gsubgpos_table (hb_face_t *face, 33423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod hb_tag_t table_tag) 335706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 3360ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod switch (table_tag) { 33723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod case HB_OT_TAG_GSUB: return _get_gsub (face); 33823c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod case HB_OT_TAG_GPOS: return _get_gpos (face); 3390ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod default: return Null(GSUBGPOS); 340706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod } 341706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 342706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 343706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 344e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 345bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_table_get_script_tags (hb_face_t *face, 346bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 347e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 348bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *script_count /* IN/OUT */, 349bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *script_tags /* OUT */) 350706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 35123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 352706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 353e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return g.get_script_tags (start_offset, script_count, script_tags); 354706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 355706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 356706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbodhb_bool_t 3570ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_table_find_script (hb_face_t *face, 3580ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 3590ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t script_tag, 3600ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *script_index) 361706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 3624a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 36323c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 364706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 365706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod if (g.find_script_index (script_tag, script_index)) 366706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return TRUE; 367706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 368706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod /* try finding 'DFLT' */ 3698a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) 370706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return FALSE; 371706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 372706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 3738a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) 374706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return FALSE; 375706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 376706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 377706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return FALSE; 378706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 379706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 380e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 381bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_table_get_feature_tags (hb_face_t *face, 382bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 383e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 384bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 385bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) 386c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod{ 38723c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 388c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 389e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return g.get_feature_tags (start_offset, feature_count, feature_tags); 390c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 391c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 392c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 393e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 394bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_script_get_language_tags (hb_face_t *face, 395bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 396bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 397e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 398bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *language_count /* IN/OUT */, 399bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *language_tags /* OUT */) 400706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 40123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 402706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 403e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return s.get_lang_sys_tags (start_offset, language_count, language_tags); 404706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 405706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 406706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbodhb_bool_t 4070ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_script_find_language (hb_face_t *face, 4080ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 4090ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int script_index, 4100ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t language_tag, 4110ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *language_index) 412706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod{ 4134a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX); 41423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); 415706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4164a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (s.find_lang_sys_index (language_tag, language_index)) 417706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return TRUE; 418706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 419706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 4208a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) 421706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return FALSE; 422706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4234a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; 424706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return FALSE; 4254a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 426706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4274a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbodhb_bool_t 4280ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_language_get_required_feature_index (hb_face_t *face, 4290ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 4300ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int script_index, 4310ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int language_index, 4320ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *feature_index) 4334a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 43423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index); 435706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4364a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_index) *feature_index = l.get_required_feature_index (); 437706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 4384a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod return l.has_required_feature (); 4394a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 440706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 441e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 442bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_language_get_feature_indexes (hb_face_t *face, 443bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 444bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 445bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int language_index, 446e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 447bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 448bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_indexes /* OUT */) 4490ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 45023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4514a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4524a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 453e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return l.get_feature_indexes (start_offset, feature_count, feature_indexes); 454c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 455c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 456e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 457bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_language_get_feature_tags (hb_face_t *face, 458bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 459bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int script_index, 460bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int language_index, 461e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 462bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 463bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) 4640ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 46523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 466c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4674a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 468bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t)); 469e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags); 470bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 4719897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod if (feature_tags) { 4729897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod unsigned int count = *feature_count; 4739897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 4749897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]); 4759897749113f76dc26a83bfae8de62e55d384fcadBehdad Esfahbod } 476bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 477bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod return ret; 4784a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod} 4794a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 4804a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 4814a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbodhb_bool_t 4820ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_language_find_feature (hb_face_t *face, 4830ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t table_tag, 4840ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int script_index, 4850ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int language_index, 4860ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_tag_t feature_tag, 4870ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod unsigned int *feature_index) 4884a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod{ 4894a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); 49023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 4914a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 4924a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 493f4c9514935cf97a58dcb3b1962ac3f3b5ba61264Behdad Esfahbod unsigned int num_features = l.get_feature_count (); 494f4c9514935cf97a58dcb3b1962ac3f3b5ba61264Behdad Esfahbod for (unsigned int i = 0; i < num_features; i++) { 4954a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod unsigned int f_index = l.get_feature_index (i); 4964a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod 4974a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_tag == g.get_feature_tag (f_index)) { 4984a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_index) *feature_index = f_index; 4994a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod return TRUE; 5004a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod } 5014a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod } 502706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 5034a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; 504706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return FALSE; 505706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod} 506c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 507e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbodunsigned int 508bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodhb_ot_layout_feature_get_lookup_indexes (hb_face_t *face, 509bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod hb_tag_t table_tag, 510bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int feature_index, 511e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int start_offset, 512bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *lookup_count /* IN/OUT */, 513bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod unsigned int *lookup_indexes /* OUT */) 514c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod{ 51523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 516c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod const Feature &f = g.get_feature (feature_index); 517c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 518e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); 519c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod} 520c44733596c6648e209c12349e18e35424edf3d59Behdad Esfahbod 5212d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 5222d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod/* 5232d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod * GSUB 5242d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod */ 5252d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 5262d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbodhb_bool_t 5270ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_has_substitution (hb_face_t *face) 5280ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 52923c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return &_get_gsub (face) != &Null(GSUB); 5300ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 5310ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 5320ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_bool_t 533468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbodhb_ot_layout_substitute_lookup (hb_face_t *face, 534468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod hb_buffer_t *buffer, 535468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod unsigned int lookup_index, 536468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod hb_mask_t mask) 5372d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod{ 5380ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_ot_layout_context_t context; 5390ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod context.font = NULL; 54023c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod context.face = face; 54123c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return _get_gsub (face).substitute_lookup (&context, buffer, lookup_index, mask); 5425a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod} 5435a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 544bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 5459c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod/* 5469c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod * GPOS 5479c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod */ 5489c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod 5499c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbodhb_bool_t 5500ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_ot_layout_has_positioning (hb_face_t *face) 5510ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod{ 55223c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return &_get_gpos (face) != &Null(GPOS); 5530ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod} 5540ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod 5550ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbodhb_bool_t 55652ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbodhb_ot_layout_position_lookup (hb_font_t *font, 55752ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbod hb_face_t *face, 558468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod hb_buffer_t *buffer, 559468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod unsigned int lookup_index, 560468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod hb_mask_t mask) 5619c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod{ 5620ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod hb_ot_layout_context_t context; 5630ead481a5a8623103565fd7d924666e7342278ddBehdad Esfahbod context.font = font; 56423c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod context.face = face; 56523c86aa0009324433e78fcd0c47f2c0ff14b1949Behdad Esfahbod return _get_gpos (face).position_lookup (&context, buffer, lookup_index, mask); 5669c42f05a5ccbb48a9367b80ecdf3679e88088fcfBehdad Esfahbod} 5679db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod 5689db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbodvoid 56952ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbodhb_ot_layout_position_finish (hb_font_t *font, 57052ea47767c7c35650ebddfba6ddc8203a3e33d3aBehdad Esfahbod hb_face_t *face, 5719db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod hb_buffer_t *buffer) 5729db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod{ 5739db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod unsigned int i, j; 5749db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod unsigned int len = hb_buffer_get_length (buffer); 5759db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod hb_internal_glyph_position_t *positions = (hb_internal_glyph_position_t *) hb_buffer_get_glyph_positions (buffer); 5769db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod 5779db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod /* TODO: Vertical */ 5789db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod 5799db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod /* Handle cursive connections */ 5809db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod /* First handle all left-to-right connections */ 5819db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod for (j = 0; j < len; j++) { 5829db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod if (positions[j].cursive_chain > 0) { 5839db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[j].y_offset += positions[j - positions[j].cursive_chain].y_offset; 5849db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[j].cursive_chain = 0; 5859db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod } 5869db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod } 5879db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod /* Then handle all right-to-left connections */ 5889db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod for (i = len; i > 0; i--) { 5899db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod j = i - 1; 5909db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod if (positions[j].cursive_chain < 0) { 5919db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[j].y_offset += positions[j - positions[j].cursive_chain].y_offset; 5929db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[j].cursive_chain = 0; 5939db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod } 5949db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod } 5959db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod 5969db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod /* Handle attachments */ 5979db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod for (i = 0; i < len; i++) 5989db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod if (positions[i].back) 5999db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod { 6009db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod unsigned int back = i - positions[i].back; 6019db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[i].back = 0; 6029db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[i].x_offset += positions[back].x_offset; 6039db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[i].y_offset += positions[back].y_offset; 6049db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod 6059db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod if (buffer->direction == HB_DIRECTION_RTL) 6069db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod for (j = back + 1; j < i + 1; j++) { 6079db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[i].x_offset += positions[j].x_advance; 6089db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[i].y_offset += positions[j].y_advance; 6099db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod } 6109db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod else 6119db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod for (j = back; j < i; j++) { 6129db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[i].x_offset -= positions[j].x_advance; 6139db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod positions[i].y_offset -= positions[j].y_advance; 6149db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod } 6159db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod } 6169db8ad75317d589807e7725455f49cafece58d5dBehdad Esfahbod} 617