/src/harfbuzz/src/hb-aat-layout.cc
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * Copyright © 2017  Google, Inc.  | 
3  |  |  * Copyright © 2018  Ebrahim Byagowi  | 
4  |  |  *  | 
5  |  |  *  This is part of HarfBuzz, a text shaping library.  | 
6  |  |  *  | 
7  |  |  * Permission is hereby granted, without written agreement and without  | 
8  |  |  * license or royalty fees, to use, copy, modify, and distribute this  | 
9  |  |  * software and its documentation for any purpose, provided that the  | 
10  |  |  * above copyright notice and the following two paragraphs appear in  | 
11  |  |  * all copies of this software.  | 
12  |  |  *  | 
13  |  |  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR  | 
14  |  |  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES  | 
15  |  |  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN  | 
16  |  |  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH  | 
17  |  |  * DAMAGE.  | 
18  |  |  *  | 
19  |  |  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,  | 
20  |  |  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND  | 
21  |  |  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS  | 
22  |  |  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO  | 
23  |  |  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.  | 
24  |  |  *  | 
25  |  |  * Google Author(s): Behdad Esfahbod  | 
26  |  |  */  | 
27  |  |  | 
28  |  | #include "hb.hh"  | 
29  |  |  | 
30  |  | #include "hb-aat-layout.hh"  | 
31  |  | #include "hb-aat-layout-ankr-table.hh"  | 
32  |  | #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise.  | 
33  |  | #include "hb-aat-layout-feat-table.hh"  | 
34  |  | #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise.  | 
35  |  | #include "hb-aat-layout-kerx-table.hh"  | 
36  |  | #include "hb-aat-layout-morx-table.hh"  | 
37  |  | #include "hb-aat-layout-trak-table.hh"  | 
38  |  | #include "hb-aat-ltag-table.hh"  | 
39  |  |  | 
40  |  |  | 
41  |  | /*  | 
42  |  |  * hb_aat_apply_context_t  | 
43  |  |  */  | 
44  |  |  | 
45  |  | /* Note: This context is used for kerning, even without AAT, hence the condition. */  | 
46  |  | #if !defined(HB_NO_AAT) || !defined(HB_NO_OT_KERN)  | 
47  |  |  | 
48  |  | AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,  | 
49  |  |                  hb_font_t *font_,  | 
50  |  |                  hb_buffer_t *buffer_,  | 
51  |  |                  hb_blob_t *blob) :  | 
52  |  |                    plan (plan_),  | 
53  |  |                    font (font_),  | 
54  |  |                    face (font->face),  | 
55  |  |                    buffer (buffer_),  | 
56  |  |                    sanitizer (),  | 
57  |  |                    ankr_table (&Null (AAT::ankr)),  | 
58  |  |                    gdef_table (face->table.GDEF->table),  | 
59  |  |                    lookup_index (0)  | 
60  | 43.9k  | { | 
61  | 43.9k  |   sanitizer.init (blob);  | 
62  | 43.9k  |   sanitizer.set_num_glyphs (face->get_num_glyphs ());  | 
63  | 43.9k  |   sanitizer.start_processing ();  | 
64  | 43.9k  |   sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);  | 
65  | 43.9k  | }  | 
66  |  |  | 
67  |  | AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()  | 
68  | 43.9k  | { sanitizer.end_processing (); } | 
69  |  |  | 
70  |  | void  | 
71  |  | AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)  | 
72  | 13.0k  | { ankr_table = ankr_table_; } | 
73  |  |  | 
74  |  | #endif  | 
75  |  |  | 
76  |  |  | 
77  |  | /**  | 
78  |  |  * SECTION:hb-aat-layout  | 
79  |  |  * @title: hb-aat-layout  | 
80  |  |  * @short_description: Apple Advanced Typography Layout  | 
81  |  |  * @include: hb-aat.h  | 
82  |  |  *  | 
83  |  |  * Functions for querying AAT Layout features in the font face.  | 
84  |  |  *  | 
85  |  |  * HarfBuzz supports all of the AAT tables used to implement shaping. Other  | 
86  |  |  * AAT tables and their associated features are not supported.  | 
87  |  |  **/  | 
88  |  |  | 
89  |  |  | 
90  |  | #if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT)  | 
91  |  |  | 
92  |  | /* Mapping from OpenType feature tags to AAT feature names and selectors.  | 
93  |  |  *  | 
94  |  |  * Table data courtesy of Apple.  Converted from mnemonics to integers  | 
95  |  |  * when moving to this file. */  | 
96  |  | static const hb_aat_feature_mapping_t feature_mappings[] =  | 
97  |  | { | 
98  |  |   {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS,               HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS,             HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS}, | 
99  |  |   {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE,              HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS,         HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE}, | 
100  |  |   {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE,              HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS,          HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE}, | 
101  |  |   {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON,       HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF}, | 
102  |  |   {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT,   HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON,       HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF}, | 
103  |  |   {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,               HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF}, | 
104  |  |   {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT,   HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON,      HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF}, | 
105  |  |   {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF}, | 
106  |  |   {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,               HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON,              HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF}, | 
107  |  |   {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS,              (hb_aat_layout_feature_selector_t) 16}, | 
108  |  |   {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS,               HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS,             HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS}, | 
109  |  |   {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT,                (hb_aat_layout_feature_selector_t) 7}, | 
110  |  |   {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT,            (hb_aat_layout_feature_selector_t) 7}, | 
111  |  |   {HB_TAG ('h','i','s','t'), (hb_aat_layout_feature_type_t) 40,                  (hb_aat_layout_feature_selector_t) 0,                          (hb_aat_layout_feature_selector_t) 1}, | 
112  |  |   {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA,          HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF}, | 
113  |  |   {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,               HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF}, | 
114  |  |   {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION,         HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL,                HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION}, | 
115  |  |   {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS,                (hb_aat_layout_feature_selector_t) 16}, | 
116  |  |   {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT,                (hb_aat_layout_feature_selector_t) 7}, | 
117  |  |   {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN,        HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON,            HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF}, | 
118  |  |   {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS,             (hb_aat_layout_feature_selector_t) 16}, | 
119  |  |   {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS,             (hb_aat_layout_feature_selector_t) 16}, | 
120  |  |   {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS,             (hb_aat_layout_feature_selector_t) 16}, | 
121  |  |   {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS,             (hb_aat_layout_feature_selector_t) 16}, | 
122  |  |   {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,               HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON,            HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF}, | 
123  |  |   {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE,             HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS,             (hb_aat_layout_feature_selector_t) 2}, | 
124  |  |   {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS,     HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON,          HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF}, | 
125  |  |   {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS,                  (hb_aat_layout_feature_selector_t) 16}, | 
126  |  |   {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE,             HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS,             (hb_aat_layout_feature_selector_t) 2}, | 
127  |  |   {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,       HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS,                       HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, | 
128  |  |   {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT,          (hb_aat_layout_feature_selector_t) 7}, | 
129  |  |   {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE,              HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS,         HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE}, | 
130  |  |   {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT,              (hb_aat_layout_feature_selector_t) 7}, | 
131  |  |   {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING,          HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS,           (hb_aat_layout_feature_selector_t) 4}, | 
132  |  |   {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT,              (hb_aat_layout_feature_selector_t) 7}, | 
133  |  |   {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT,             (hb_aat_layout_feature_selector_t) 7}, | 
134  |  |   {HB_TAG ('r','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,               HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON,          HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF}, | 
135  |  |   {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA,               HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON,                   HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF}, | 
136  |  |   {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,       HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS,           HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, | 
137  |  |   {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE,              HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS,          HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE}, | 
138  |  |   {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS,          (hb_aat_layout_feature_selector_t) 16}, | 
139  |  |   {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON,           HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF}, | 
140  |  |   {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON,           HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF}, | 
141  |  |   {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON,         HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF}, | 
142  |  |   {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON,          HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF}, | 
143  |  |   {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON,          HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF}, | 
144  |  |   {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON,           HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF}, | 
145  |  |   {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON,         HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF}, | 
146  |  |   {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON,         HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF}, | 
147  |  |   {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON,          HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF}, | 
148  |  |   {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON,           HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF}, | 
149  |  |   {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF}, | 
150  |  |   {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF}, | 
151  |  |   {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON,      HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF}, | 
152  |  |   {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON,      HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF}, | 
153  |  |   {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON,       HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF}, | 
154  |  |   {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON,       HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF}, | 
155  |  |   {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON,     HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF}, | 
156  |  |   {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON,      HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF}, | 
157  |  |   {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON,      HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF}, | 
158  |  |   {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES,  HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF}, | 
159  |  |   {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,       HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS,                      HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, | 
160  |  |   {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION,       HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS,                      HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, | 
161  |  |   {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON,            HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF}, | 
162  |  |   {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS,           HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS,                   HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS}, | 
163  |  |   {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS,   (hb_aat_layout_feature_selector_t) 16}, | 
164  |  |   {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING,          HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS,             (hb_aat_layout_feature_selector_t) 4}, | 
165  |  |   {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE,         HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS,         (hb_aat_layout_feature_selector_t) 16}, | 
166  |  |   {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT,               (hb_aat_layout_feature_selector_t) 7}, | 
167  |  |   {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE,             (hb_aat_layout_feature_selector_t) 14,                 (hb_aat_layout_feature_selector_t) 15}, | 
168  |  |   {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT,          (hb_aat_layout_feature_selector_t) 7}, | 
169  |  |   {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION,   HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON,   HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, | 
170  |  |   {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT,            (hb_aat_layout_feature_selector_t) 7}, | 
171  |  |   {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA,          HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON,         HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF}, | 
172  |  |   {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT,          (hb_aat_layout_feature_selector_t) 7}, | 
173  |  |   {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION,   HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON,   HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, | 
174  |  |   {HB_TAG ('v','r','t','r'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION,   (hb_aat_layout_feature_selector_t) 2,                          (hb_aat_layout_feature_selector_t) 3}, | 
175  |  |   {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS,      HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON,                HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF}, | 
176  |  | };  | 
177  |  |  | 
178  |  | /**  | 
179  |  |  * hb_aat_layout_find_feature_mapping:  | 
180  |  |  * @tag: The requested #hb_tag_t feature tag  | 
181  |  |  *  | 
182  |  |  * Fetches the AAT feature-and-selector combination that corresponds  | 
183  |  |  * to a given OpenType feature tag.  | 
184  |  |  *  | 
185  |  |  * Return value: the AAT features and selectors corresponding to the  | 
186  |  |  * OpenType feature tag queried  | 
187  |  |  *  | 
188  |  |  **/  | 
189  |  | const hb_aat_feature_mapping_t *  | 
190  |  | hb_aat_layout_find_feature_mapping (hb_tag_t tag)  | 
191  | 0  | { | 
192  | 0  |   return hb_sorted_array (feature_mappings).bsearch (tag);  | 
193  | 0  | }  | 
194  |  | #endif  | 
195  |  |  | 
196  |  |  | 
197  |  | #ifndef HB_NO_AAT  | 
198  |  |  | 
199  |  | /*  | 
200  |  |  * mort/morx/kerx/trak  | 
201  |  |  */  | 
202  |  |  | 
203  |  |  | 
204  |  | void  | 
205  |  | hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,  | 
206  |  |          hb_aat_map_t *map)  | 
207  | 21.7k  | { | 
208  | 21.7k  |   const AAT::morx& morx = *mapper->face->table.morx;  | 
209  | 21.7k  |   if (morx.has_data ())  | 
210  | 17.8k  |   { | 
211  | 17.8k  |     morx.compile_flags (mapper, map);  | 
212  | 17.8k  |     return;  | 
213  | 17.8k  |   }  | 
214  |  |  | 
215  | 3.97k  |   const AAT::mort& mort = *mapper->face->table.mort;  | 
216  | 3.97k  |   if (mort.has_data ())  | 
217  | 3.97k  |   { | 
218  | 3.97k  |     mort.compile_flags (mapper, map);  | 
219  | 3.97k  |     return;  | 
220  | 3.97k  |   }  | 
221  | 3.97k  | }  | 
222  |  |  | 
223  |  |  | 
224  |  | /**  | 
225  |  |  * hb_aat_layout_has_substitution:  | 
226  |  |  * @face: #hb_face_t to work upon  | 
227  |  |  *  | 
228  |  |  * Tests whether the specified face includes any substitutions in the  | 
229  |  |  * `morx` or `mort` tables.  | 
230  |  |  *  | 
231  |  |  * <note>Note: does not examine the `GSUB` table.</note>  | 
232  |  |  *  | 
233  |  |  * Return value: `true` if data found, `false` otherwise  | 
234  |  |  *  | 
235  |  |  * Since: 2.3.0  | 
236  |  |  */  | 
237  |  | hb_bool_t  | 
238  |  | hb_aat_layout_has_substitution (hb_face_t *face)  | 
239  | 123k  | { | 
240  | 123k  |   return face->table.morx->has_data () ||  | 
241  | 123k  |    face->table.mort->has_data ();  | 
242  | 123k  | }  | 
243  |  |  | 
244  |  | void  | 
245  |  | hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,  | 
246  |  |         hb_font_t *font,  | 
247  |  |         hb_buffer_t *buffer,  | 
248  |  |         const hb_feature_t *features,  | 
249  |  |         unsigned num_features)  | 
250  | 22.5k  | { | 
251  | 22.5k  |   hb_aat_map_builder_t builder (font->face, plan->props);  | 
252  | 22.5k  |   for (unsigned i = 0; i < num_features; i++)  | 
253  | 0  |     builder.add_feature (features[i]);  | 
254  | 22.5k  |   hb_aat_map_t map;  | 
255  | 22.5k  |   builder.compile (map);  | 
256  |  |  | 
257  | 22.5k  |   hb_blob_t *morx_blob = font->face->table.morx.get_blob ();  | 
258  | 22.5k  |   const AAT::morx& morx = *morx_blob->as<AAT::morx> ();  | 
259  | 22.5k  |   if (morx.has_data ())  | 
260  | 18.2k  |   { | 
261  | 18.2k  |     AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob);  | 
262  | 18.2k  |     if (!buffer->message (font, "start table morx")) return;  | 
263  | 18.2k  |     morx.apply (&c, map);  | 
264  | 18.2k  |     (void) buffer->message (font, "end table morx");  | 
265  | 18.2k  |     return;  | 
266  | 18.2k  |   }  | 
267  |  |  | 
268  | 4.23k  |   hb_blob_t *mort_blob = font->face->table.mort.get_blob ();  | 
269  | 4.23k  |   const AAT::mort& mort = *mort_blob->as<AAT::mort> ();  | 
270  | 4.23k  |   if (mort.has_data ())  | 
271  | 4.23k  |   { | 
272  | 4.23k  |     AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob);  | 
273  | 4.23k  |     if (!buffer->message (font, "start table mort")) return;  | 
274  | 4.23k  |     mort.apply (&c, map);  | 
275  | 4.23k  |     (void) buffer->message (font, "end table mort");  | 
276  | 4.23k  |     return;  | 
277  | 4.23k  |   }  | 
278  | 4.23k  | }  | 
279  |  |  | 
280  |  | void  | 
281  |  | hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)  | 
282  | 22.5k  | { | 
283  | 22.5k  |   unsigned int count = buffer->len;  | 
284  | 22.5k  |   hb_glyph_info_t *info = buffer->info;  | 
285  | 22.5k  |   hb_glyph_position_t *pos = buffer->pos;  | 
286  | 6.57M  |   for (unsigned int i = 0; i < count; i++)  | 
287  | 6.54M  |     if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH))  | 
288  | 71.4k  |       pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;  | 
289  | 22.5k  | }  | 
290  |  |  | 
291  |  | static bool  | 
292  |  | is_deleted_glyph (const hb_glyph_info_t *info)  | 
293  | 6.54M  | { | 
294  | 6.54M  |   return info->codepoint == AAT::DELETED_GLYPH;  | 
295  | 6.54M  | }  | 
296  |  |  | 
297  |  | void  | 
298  |  | hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)  | 
299  | 22.5k  | { | 
300  | 22.5k  |   buffer->delete_glyphs_inplace (is_deleted_glyph);  | 
301  | 22.5k  | }  | 
302  |  |  | 
303  |  | /**  | 
304  |  |  * hb_aat_layout_has_positioning:  | 
305  |  |  * @face: #hb_face_t to work upon  | 
306  |  |  *  | 
307  |  |  * Tests whether the specified face includes any positioning information  | 
308  |  |  * in the `kerx` table.  | 
309  |  |  *  | 
310  |  |  * <note>Note: does not examine the `GPOS` table.</note>  | 
311  |  |  *  | 
312  |  |  * Return value: `true` if data found, `false` otherwise  | 
313  |  |  *  | 
314  |  |  * Since: 2.3.0  | 
315  |  |  */  | 
316  |  | hb_bool_t  | 
317  |  | hb_aat_layout_has_positioning (hb_face_t *face)  | 
318  | 123k  | { | 
319  | 123k  |   return face->table.kerx->has_data ();  | 
320  | 123k  | }  | 
321  |  |  | 
322  |  | void  | 
323  |  | hb_aat_layout_position (const hb_ot_shape_plan_t *plan,  | 
324  |  |       hb_font_t *font,  | 
325  |  |       hb_buffer_t *buffer)  | 
326  | 13.0k  | { | 
327  | 13.0k  |   hb_blob_t *kerx_blob = font->face->table.kerx.get_blob ();  | 
328  | 13.0k  |   const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> ();  | 
329  |  |  | 
330  | 13.0k  |   AAT::hb_aat_apply_context_t c (plan, font, buffer, kerx_blob);  | 
331  | 13.0k  |   if (!buffer->message (font, "start table kerx")) return;  | 
332  | 13.0k  |   c.set_ankr_table (font->face->table.ankr.get ());  | 
333  | 13.0k  |   kerx.apply (&c);  | 
334  | 13.0k  |   (void) buffer->message (font, "end table kerx");  | 
335  | 13.0k  | }  | 
336  |  |  | 
337  |  |  | 
338  |  | /**  | 
339  |  |  * hb_aat_layout_has_tracking:  | 
340  |  |  * @face:: #hb_face_t to work upon  | 
341  |  |  *  | 
342  |  |  * Tests whether the specified face includes any tracking information  | 
343  |  |  * in the `trak` table.  | 
344  |  |  *  | 
345  |  |  * Return value: `true` if data found, `false` otherwise  | 
346  |  |  *  | 
347  |  |  * Since: 2.3.0  | 
348  |  |  */  | 
349  |  | hb_bool_t  | 
350  |  | hb_aat_layout_has_tracking (hb_face_t *face)  | 
351  | 121k  | { | 
352  | 121k  |   return face->table.trak->has_data ();  | 
353  | 121k  | }  | 
354  |  |  | 
355  |  | void  | 
356  |  | hb_aat_layout_track (const hb_ot_shape_plan_t *plan,  | 
357  |  |          hb_font_t *font,  | 
358  |  |          hb_buffer_t *buffer)  | 
359  | 748  | { | 
360  | 748  |   const AAT::trak& trak = *font->face->table.trak;  | 
361  |  |  | 
362  | 748  |   AAT::hb_aat_apply_context_t c (plan, font, buffer);  | 
363  | 748  |   trak.apply (&c);  | 
364  | 748  | }  | 
365  |  |  | 
366  |  | /**  | 
367  |  |  * hb_aat_layout_get_feature_types:  | 
368  |  |  * @face: #hb_face_t to work upon  | 
369  |  |  * @start_offset: offset of the first feature type to retrieve  | 
370  |  |  * @feature_count: (inout) (optional): Input = the maximum number of feature types to return;  | 
371  |  |  *                 Output = the actual number of feature types returned (may be zero)  | 
372  |  |  * @features: (out caller-allocates) (array length=feature_count): Array of feature types found  | 
373  |  |  *  | 
374  |  |  * Fetches a list of the AAT feature types included in the specified face.  | 
375  |  |  *  | 
376  |  |  * Return value: Number of all available feature types.  | 
377  |  |  *  | 
378  |  |  * Since: 2.2.0  | 
379  |  |  */  | 
380  |  | unsigned int  | 
381  |  | hb_aat_layout_get_feature_types (hb_face_t                    *face,  | 
382  |  |          unsigned int                  start_offset,  | 
383  |  |          unsigned int                 *feature_count, /* IN/OUT.  May be NULL. */  | 
384  |  |          hb_aat_layout_feature_type_t *features       /* OUT.     May be NULL. */)  | 
385  | 94.9k  | { | 
386  | 94.9k  |   return face->table.feat->get_feature_types (start_offset, feature_count, features);  | 
387  | 94.9k  | }  | 
388  |  |  | 
389  |  | /**  | 
390  |  |  * hb_aat_layout_feature_type_get_name_id:  | 
391  |  |  * @face: #hb_face_t to work upon  | 
392  |  |  * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type  | 
393  |  |  *  | 
394  |  |  * Fetches the name identifier of the specified feature type in the face's `name` table.  | 
395  |  |  *  | 
396  |  |  * Return value: Name identifier of the requested feature type  | 
397  |  |  *  | 
398  |  |  * Since: 2.2.0  | 
399  |  |  */  | 
400  |  | hb_ot_name_id_t  | 
401  |  | hb_aat_layout_feature_type_get_name_id (hb_face_t                    *face,  | 
402  |  |           hb_aat_layout_feature_type_t  feature_type)  | 
403  | 94.9k  | { | 
404  | 94.9k  |   return face->table.feat->get_feature_name_id (feature_type);  | 
405  | 94.9k  | }  | 
406  |  |  | 
407  |  | /**  | 
408  |  |  * hb_aat_layout_feature_type_get_selector_infos:  | 
409  |  |  * @face: #hb_face_t to work upon  | 
410  |  |  * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type  | 
411  |  |  * @start_offset: offset of the first feature type to retrieve  | 
412  |  |  * @selector_count: (inout) (optional): Input = the maximum number of selectors to return;  | 
413  |  |  *                  Output = the actual number of selectors returned (may be zero)  | 
414  |  |  * @selectors: (out caller-allocates) (array length=selector_count) (optional):  | 
415  |  |  *             A buffer pointer. The selectors available for the feature type queries.  | 
416  |  |  * @default_index: (out) (optional): The index of the feature's default selector, if any  | 
417  |  |  *  | 
418  |  |  * Fetches a list of the selectors available for the specified feature in the given face.  | 
419  |  |  *  | 
420  |  |  * If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then  | 
421  |  |  * the feature type is non-exclusive.  Otherwise, @default_index is the index of  | 
422  |  |  * the selector that is selected by default.  | 
423  |  |  *  | 
424  |  |  * Return value: Number of all available feature selectors  | 
425  |  |  *  | 
426  |  |  * Since: 2.2.0  | 
427  |  |  */  | 
428  |  | unsigned int  | 
429  |  | hb_aat_layout_feature_type_get_selector_infos (hb_face_t                             *face,  | 
430  |  |                  hb_aat_layout_feature_type_t           feature_type,  | 
431  |  |                  unsigned int                           start_offset,  | 
432  |  |                  unsigned int                          *selector_count, /* IN/OUT.  May be NULL. */  | 
433  |  |                  hb_aat_layout_feature_selector_info_t *selectors,      /* OUT.     May be NULL. */  | 
434  |  |                  unsigned int                          *default_index   /* OUT.     May be NULL. */)  | 
435  | 94.9k  | { | 
436  | 94.9k  |   return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index);  | 
437  | 94.9k  | }  | 
438  |  |  | 
439  |  |  | 
440  |  | #endif  |