Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-layout.cc

Issue 10915172: harfbuzz-ng roll (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright © 1998-2004 David Turner and Werner Lemberg 2 * Copyright © 1998-2004 David Turner and Werner Lemberg
3 * Copyright © 2006 Behdad Esfahbod 3 * Copyright © 2006 Behdad Esfahbod
4 * Copyright © 2007,2008,2009 Red Hat, Inc. 4 * Copyright © 2007,2008,2009 Red Hat, Inc.
5 * Copyright © 2012 Google, Inc.
5 * 6 *
6 * This is part of HarfBuzz, a text shaping library. 7 * This is part of HarfBuzz, a text shaping library.
7 * 8 *
8 * Permission is hereby granted, without written agreement and without 9 * Permission is hereby granted, without written agreement and without
9 * license or royalty fees, to use, copy, modify, and distribute this 10 * license or royalty fees, to use, copy, modify, and distribute this
10 * software and its documentation for any purpose, provided that the 11 * software and its documentation for any purpose, provided that the
11 * above copyright notice and the following two paragraphs appear in 12 * above copyright notice and the following two paragraphs appear in
12 * all copies of this software. 13 * all copies of this software.
13 * 14 *
14 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
15 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18 * DAMAGE. 19 * DAMAGE.
19 * 20 *
20 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
21 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
23 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25 * 26 *
26 * Red Hat Author(s): Behdad Esfahbod 27 * Red Hat Author(s): Behdad Esfahbod
28 * Google Author(s): Behdad Esfahbod
27 */ 29 */
28 30
29 #include "hb-ot-layout-private.hh" 31 #include "hb-ot-layout-private.hh"
30 32
31 #include "hb-ot-layout-gdef-table.hh" 33 #include "hb-ot-layout-gdef-table.hh"
32 #include "hb-ot-layout-gsub-table.hh" 34 #include "hb-ot-layout-gsub-table.hh"
33 #include "hb-ot-layout-gpos-table.hh" 35 #include "hb-ot-layout-gpos-table.hh"
34 #include "hb-ot-maxp-table.hh" 36 #include "hb-ot-maxp-table.hh"
35 37
36
37 #include <stdlib.h> 38 #include <stdlib.h>
38 #include <string.h> 39 #include <string.h>
39 40
40 41
42 HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
41 43
42 hb_ot_layout_t * 44 hb_ot_layout_t *
43 _hb_ot_layout_create (hb_face_t *face) 45 _hb_ot_layout_create (hb_face_t *face)
44 { 46 {
45 /* TODO Remove this object altogether */
46 hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t) ); 47 hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t) );
48 if (unlikely (!layout))
49 return NULL;
47 50
48 layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GDEF)); 51 layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table ( HB_OT_TAG_GDEF));
49 layout->gdef = Sanitizer<GDEF>::lock_instance (layout->gdef_blob); 52 layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
50 53
51 layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GSUB)); 54 layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table ( HB_OT_TAG_GSUB));
52 layout->gsub = Sanitizer<GSUB>::lock_instance (layout->gsub_blob); 55 layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
53 56
54 layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS)); 57 layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table ( HB_OT_TAG_GPOS));
55 layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob); 58 layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
59
60 layout->gsub_lookup_count = layout->gsub->get_lookup_count ();
61 layout->gpos_lookup_count = layout->gpos->get_lookup_count ();
62
63 layout->gsub_digests = (hb_set_digest_t *) calloc (layout->gsub->get_lookup_co unt (), sizeof (hb_set_digest_t));
64 layout->gpos_digests = (hb_set_digest_t *) calloc (layout->gpos->get_lookup_co unt (), sizeof (hb_set_digest_t));
65
66 if (unlikely ((layout->gsub_lookup_count && !layout->gsub_digests) ||
67 » » (layout->gpos_lookup_count && !layout->gpos_digests)))
68 {
69 _hb_ot_layout_destroy (layout);
70 return NULL;
71 }
72
73 for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
74 layout->gsub->add_coverage (&layout->gsub_digests[i], i);
75 for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
76 layout->gpos->add_coverage (&layout->gpos_digests[i], i);
56 77
57 return layout; 78 return layout;
58 } 79 }
59 80
60 void 81 void
61 _hb_ot_layout_destroy (hb_ot_layout_t *layout) 82 _hb_ot_layout_destroy (hb_ot_layout_t *layout)
62 { 83 {
63 hb_blob_destroy (layout->gdef_blob); 84 hb_blob_destroy (layout->gdef_blob);
64 hb_blob_destroy (layout->gsub_blob); 85 hb_blob_destroy (layout->gsub_blob);
65 hb_blob_destroy (layout->gpos_blob); 86 hb_blob_destroy (layout->gpos_blob);
66 87
88 free (layout->gsub_digests);
89 free (layout->gpos_digests);
90
67 free (layout); 91 free (layout);
68 } 92 }
69 93
70 static inline const GDEF& 94 static inline const OT::GDEF&
71 _get_gdef (hb_face_t *face) 95 _get_gdef (hb_face_t *face)
72 { 96 {
73 return likely (face->ot_layout && face->ot_layout->gdef) ? *face->ot_layout->g def : Null(GDEF); 97 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF );
98 return *hb_ot_layout_from_face (face)->gdef;
74 } 99 }
75 static inline const GSUB& 100 static inline const OT::GSUB&
76 _get_gsub (hb_face_t *face) 101 _get_gsub (hb_face_t *face)
77 { 102 {
78 return likely (face->ot_layout && face->ot_layout->gsub) ? *face->ot_layout->g sub : Null(GSUB); 103 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB );
104 return *hb_ot_layout_from_face (face)->gsub;
79 } 105 }
80 static inline const GPOS& 106 static inline const OT::GPOS&
81 _get_gpos (hb_face_t *face) 107 _get_gpos (hb_face_t *face)
82 { 108 {
83 return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->g pos : Null(GPOS); 109 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS );
110 return *hb_ot_layout_from_face (face)->gpos;
84 } 111 }
85 112
86 113
87 /* 114 /*
88 * GDEF 115 * GDEF
89 */ 116 */
90 117
91 hb_bool_t 118 hb_bool_t
92 hb_ot_layout_has_glyph_classes (hb_face_t *face) 119 hb_ot_layout_has_glyph_classes (hb_face_t *face)
93 { 120 {
94 return _get_gdef (face).has_glyph_classes (); 121 return _get_gdef (face).has_glyph_classes ();
95 } 122 }
96 123
97 unsigned int
98 _hb_ot_layout_get_glyph_property (hb_face_t *face,
99 hb_glyph_info_t *info)
100 {
101 if (!info->props_cache())
102 {
103 const GDEF &gdef = _get_gdef (face);
104 info->props_cache() = gdef.get_glyph_props (info->codepoint);
105 }
106
107 return info->props_cache();
108 }
109
110 static hb_bool_t
111 _hb_ot_layout_match_properties (hb_face_t *face,
112 hb_codepoint_t codepoint,
113 unsigned int glyph_props,
114 unsigned int lookup_props)
115 {
116 /* Not covered, if, for example, glyph class is ligature and
117 * lookup_props includes LookupFlags::IgnoreLigatures
118 */
119 if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
120 return false;
121
122 if (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
123 {
124 /* If using mark filtering sets, the high short of
125 * lookup_props has the set index.
126 */
127 if (lookup_props & LookupFlag::UseMarkFilteringSet)
128 return _get_gdef (face).mark_set_covers (lookup_props >> 16, codepoint);
129
130 /* The second byte of lookup_props has the meaning
131 * "ignore marks of attachment type different than
132 * the attachment type specified."
133 */
134 if (lookup_props & LookupFlag::MarkAttachmentType && glyph_props & LookupFla g::MarkAttachmentType)
135 return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & L ookupFlag::MarkAttachmentType);
136 }
137
138 return true;
139 }
140
141 hb_bool_t
142 _hb_ot_layout_check_glyph_property (hb_face_t *face,
143 hb_glyph_info_t *ginfo,
144 unsigned int lookup_props,
145 unsigned int *property_out)
146 {
147 unsigned int property;
148
149 property = _hb_ot_layout_get_glyph_property (face, ginfo);
150 (void) (property_out && (*property_out = property));
151
152 return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, looku p_props);
153 }
154
155 hb_bool_t
156 _hb_ot_layout_skip_mark (hb_face_t *face,
157 hb_glyph_info_t *ginfo,
158 unsigned int lookup_props,
159 unsigned int *property_out)
160 {
161 unsigned int property;
162
163 property = _hb_ot_layout_get_glyph_property (face, ginfo);
164 (void) (property_out && (*property_out = property));
165
166 /* If it's a mark, skip it we don't accept it. */
167 if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
168 return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lo okup_props);
169
170 /* If not a mark, don't skip. */
171 return false;
172 }
173
174
175 124
176 unsigned int 125 unsigned int
177 hb_ot_layout_get_attach_points (hb_face_t *face, 126 hb_ot_layout_get_attach_points (hb_face_t *face,
178 hb_codepoint_t glyph, 127 hb_codepoint_t glyph,
179 unsigned int start_offset, 128 unsigned int start_offset,
180 unsigned int *point_count /* IN/OUT */, 129 unsigned int *point_count /* IN/OUT */,
181 unsigned int *point_array /* OUT */) 130 unsigned int *point_array /* OUT */)
182 { 131 {
183 return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, p oint_array); 132 return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, p oint_array);
184 } 133 }
185 134
186 unsigned int 135 unsigned int
187 hb_ot_layout_get_ligature_carets (hb_font_t *font, 136 hb_ot_layout_get_ligature_carets (hb_font_t *font,
188 hb_direction_t direction, 137 hb_direction_t direction,
189 hb_codepoint_t glyph, 138 hb_codepoint_t glyph,
190 unsigned int start_offset, 139 unsigned int start_offset,
191 unsigned int *caret_count /* IN/OUT */, 140 unsigned int *caret_count /* IN/OUT */,
192 int *caret_array /* OUT */) 141 int *caret_array /* OUT */)
193 { 142 {
194 return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_of fset, caret_count, caret_array); 143 return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_of fset, caret_count, caret_array);
195 } 144 }
196 145
146
197 /* 147 /*
198 * GSUB/GPOS 148 * GSUB/GPOS
199 */ 149 */
200 150
201 static const GSUBGPOS& 151 static const OT::GSUBGPOS&
202 get_gsubgpos_table (hb_face_t *face, 152 get_gsubgpos_table (hb_face_t *face,
203 hb_tag_t table_tag) 153 hb_tag_t table_tag)
204 { 154 {
205 switch (table_tag) { 155 switch (table_tag) {
206 case HB_OT_TAG_GSUB: return _get_gsub (face); 156 case HB_OT_TAG_GSUB: return _get_gsub (face);
207 case HB_OT_TAG_GPOS: return _get_gpos (face); 157 case HB_OT_TAG_GPOS: return _get_gpos (face);
208 default: return Null(GSUBGPOS); 158 default: return OT::Null(OT::GSUBGPOS);
209 } 159 }
210 } 160 }
211 161
212 162
213 unsigned int 163 unsigned int
214 hb_ot_layout_table_get_script_tags (hb_face_t *face, 164 hb_ot_layout_table_get_script_tags (hb_face_t *face,
215 hb_tag_t table_tag, 165 hb_tag_t table_tag,
216 unsigned int start_offset, 166 unsigned int start_offset,
217 unsigned int *script_count /* IN/OUT */, 167 unsigned int *script_count /* IN/OUT */,
218 hb_tag_t *script_tags /* OUT */) 168 hb_tag_t *script_tags /* OUT */)
219 { 169 {
220 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 170 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
221 171
222 return g.get_script_tags (start_offset, script_count, script_tags); 172 return g.get_script_tags (start_offset, script_count, script_tags);
223 } 173 }
224 174
225 hb_bool_t 175 hb_bool_t
226 hb_ot_layout_table_find_script (hb_face_t *face, 176 hb_ot_layout_table_find_script (hb_face_t *face,
227 hb_tag_t table_tag, 177 hb_tag_t table_tag,
228 hb_tag_t script_tag, 178 hb_tag_t script_tag,
229 unsigned int *script_index) 179 unsigned int *script_index)
230 { 180 {
231 ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 181 ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
232 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 182 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
233 183
234 if (g.find_script_index (script_tag, script_index)) 184 if (g.find_script_index (script_tag, script_index))
235 return true; 185 return true;
236 186
237 /* try finding 'DFLT' */ 187 /* try finding 'DFLT' */
238 if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) 188 if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
239 return false; 189 return false;
240 190
241 /* try with 'dflt'; MS site has had typos and many fonts use it now :(. 191 /* try with 'dflt'; MS site has had typos and many fonts use it now :(.
242 * including many versions of DejaVu Sans Mono! */ 192 * including many versions of DejaVu Sans Mono! */
243 if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) 193 if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
244 return false; 194 return false;
245 195
246 if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; 196 if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
247 return false; 197 return false;
248 } 198 }
249 199
250 hb_bool_t 200 hb_bool_t
251 hb_ot_layout_table_choose_script (hb_face_t *face, 201 hb_ot_layout_table_choose_script (hb_face_t *face,
252 hb_tag_t table_tag, 202 hb_tag_t table_tag,
253 const hb_tag_t *script_tags, 203 const hb_tag_t *script_tags,
254 unsigned int *script_index, 204 unsigned int *script_index,
255 hb_tag_t *chosen_script) 205 hb_tag_t *chosen_script)
256 { 206 {
257 ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); 207 ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
258 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 208 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
259 209
260 while (*script_tags) 210 while (*script_tags)
261 { 211 {
262 if (g.find_script_index (*script_tags, script_index)) { 212 if (g.find_script_index (*script_tags, script_index)) {
263 if (chosen_script) 213 if (chosen_script)
264 *chosen_script = *script_tags; 214 *chosen_script = *script_tags;
265 return true; 215 return true;
266 } 216 }
267 script_tags++; 217 script_tags++;
268 } 218 }
(...skipping 27 matching lines...) Expand all
296 return false; 246 return false;
297 } 247 }
298 248
299 unsigned int 249 unsigned int
300 hb_ot_layout_table_get_feature_tags (hb_face_t *face, 250 hb_ot_layout_table_get_feature_tags (hb_face_t *face,
301 hb_tag_t table_tag, 251 hb_tag_t table_tag,
302 unsigned int start_offset, 252 unsigned int start_offset,
303 unsigned int *feature_count /* IN/OUT */, 253 unsigned int *feature_count /* IN/OUT */,
304 hb_tag_t *feature_tags /* OUT */) 254 hb_tag_t *feature_tags /* OUT */)
305 { 255 {
306 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 256 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
307 257
308 return g.get_feature_tags (start_offset, feature_count, feature_tags); 258 return g.get_feature_tags (start_offset, feature_count, feature_tags);
309 } 259 }
310 260
311 261
312 unsigned int 262 unsigned int
313 hb_ot_layout_script_get_language_tags (hb_face_t *face, 263 hb_ot_layout_script_get_language_tags (hb_face_t *face,
314 hb_tag_t table_tag, 264 hb_tag_t table_tag,
315 unsigned int script_index, 265 unsigned int script_index,
316 unsigned int start_offset, 266 unsigned int start_offset,
317 unsigned int *language_count /* IN/OUT */ , 267 unsigned int *language_count /* IN/OUT */ ,
318 hb_tag_t *language_tags /* OUT */) 268 hb_tag_t *language_tags /* OUT */)
319 { 269 {
320 const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_inde x); 270 const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_ index);
321 271
322 return s.get_lang_sys_tags (start_offset, language_count, language_tags); 272 return s.get_lang_sys_tags (start_offset, language_count, language_tags);
323 } 273 }
324 274
325 hb_bool_t 275 hb_bool_t
326 hb_ot_layout_script_find_language (hb_face_t *face, 276 hb_ot_layout_script_find_language (hb_face_t *face,
327 hb_tag_t table_tag, 277 hb_tag_t table_tag,
328 unsigned int script_index, 278 unsigned int script_index,
329 hb_tag_t language_tag, 279 hb_tag_t language_tag,
330 unsigned int *language_index) 280 unsigned int *language_index)
331 { 281 {
332 ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX); 282 ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_IND EX);
333 const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_inde x); 283 const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_ index);
334 284
335 if (s.find_lang_sys_index (language_tag, language_index)) 285 if (s.find_lang_sys_index (language_tag, language_index))
336 return true; 286 return true;
337 287
338 /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ 288 /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
339 if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) 289 if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
340 return false; 290 return false;
341 291
342 if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; 292 if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
343 return false; 293 return false;
344 } 294 }
345 295
346 hb_bool_t 296 hb_bool_t
347 hb_ot_layout_language_get_required_feature_index (hb_face_t *face, 297 hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
348 hb_tag_t table_tag, 298 hb_tag_t table_tag,
349 unsigned int script_index, 299 unsigned int script_index,
350 unsigned int language_index, 300 unsigned int language_index,
351 unsigned int *feature_index) 301 unsigned int *feature_index)
352 { 302 {
353 const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_ind ex).get_lang_sys (language_index); 303 const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script _index).get_lang_sys (language_index);
354 304
355 if (feature_index) *feature_index = l.get_required_feature_index (); 305 if (feature_index) *feature_index = l.get_required_feature_index ();
356 306
357 return l.has_required_feature (); 307 return l.has_required_feature ();
358 } 308 }
359 309
360 unsigned int 310 unsigned int
361 hb_ot_layout_language_get_feature_indexes (hb_face_t *face, 311 hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
362 hb_tag_t table_tag, 312 hb_tag_t table_tag,
363 unsigned int script_index, 313 unsigned int script_index,
364 unsigned int language_index, 314 unsigned int language_index,
365 unsigned int start_offset, 315 unsigned int start_offset,
366 unsigned int *feature_count /* IN/OUT */, 316 unsigned int *feature_count /* IN/OUT */,
367 unsigned int *feature_indexes /* OUT */) 317 unsigned int *feature_indexes /* OUT */)
368 { 318 {
369 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 319 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
370 const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 320 const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_inde x);
371 321
372 return l.get_feature_indexes (start_offset, feature_count, feature_indexes); 322 return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
373 } 323 }
374 324
375 unsigned int 325 unsigned int
376 hb_ot_layout_language_get_feature_tags (hb_face_t *face, 326 hb_ot_layout_language_get_feature_tags (hb_face_t *face,
377 hb_tag_t table_tag, 327 hb_tag_t table_tag,
378 unsigned int script_index, 328 unsigned int script_index,
379 unsigned int language_index, 329 unsigned int language_index,
380 unsigned int start_offset, 330 unsigned int start_offset,
381 unsigned int *feature_count /* IN/OUT */ , 331 unsigned int *feature_count /* IN/OUT */ ,
382 hb_tag_t *feature_tags /* OUT */) 332 hb_tag_t *feature_tags /* OUT */)
383 { 333 {
384 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 334 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
385 const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 335 const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_inde x);
386 336
387 ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t)); 337 ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
388 unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsign ed int *) feature_tags); 338 unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsign ed int *) feature_tags);
389 339
390 if (feature_tags) { 340 if (feature_tags) {
391 unsigned int count = *feature_count; 341 unsigned int count = *feature_count;
392 for (unsigned int i = 0; i < count; i++) 342 for (unsigned int i = 0; i < count; i++)
393 feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]); 343 feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
394 } 344 }
395 345
396 return ret; 346 return ret;
397 } 347 }
398 348
399 349
400 hb_bool_t 350 hb_bool_t
401 hb_ot_layout_language_find_feature (hb_face_t *face, 351 hb_ot_layout_language_find_feature (hb_face_t *face,
402 hb_tag_t table_tag, 352 hb_tag_t table_tag,
403 unsigned int script_index, 353 unsigned int script_index,
404 unsigned int language_index, 354 unsigned int language_index,
405 hb_tag_t feature_tag, 355 hb_tag_t feature_tag,
406 unsigned int *feature_index) 356 unsigned int *feature_index)
407 { 357 {
408 ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); 358 ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
409 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 359 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
410 const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); 360 const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_inde x);
411 361
412 unsigned int num_features = l.get_feature_count (); 362 unsigned int num_features = l.get_feature_count ();
413 for (unsigned int i = 0; i < num_features; i++) { 363 for (unsigned int i = 0; i < num_features; i++) {
414 unsigned int f_index = l.get_feature_index (i); 364 unsigned int f_index = l.get_feature_index (i);
415 365
416 if (feature_tag == g.get_feature_tag (f_index)) { 366 if (feature_tag == g.get_feature_tag (f_index)) {
417 if (feature_index) *feature_index = f_index; 367 if (feature_index) *feature_index = f_index;
418 return true; 368 return true;
419 } 369 }
420 } 370 }
421 371
422 if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; 372 if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
423 return false; 373 return false;
424 } 374 }
425 375
426 unsigned int 376 unsigned int
427 hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face, 377 hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face,
428 hb_tag_t table_tag, 378 hb_tag_t table_tag,
429 unsigned int feature_index, 379 unsigned int feature_index,
430 unsigned int start_offset, 380 unsigned int start_offset,
431 unsigned int *lookup_count /* IN/OUT */ , 381 unsigned int *lookup_count /* IN/OUT */ ,
432 unsigned int *lookup_indexes /* OUT */) 382 unsigned int *lookup_indexes /* OUT */)
433 { 383 {
434 const GSUBGPOS &g = get_gsubgpos_table (face, table_tag); 384 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
435 const Feature &f = g.get_feature (feature_index); 385 const OT::Feature &f = g.get_feature (feature_index);
436 386
437 return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); 387 return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
438 } 388 }
439 389
440 390
441 /* 391 /*
442 * GSUB 392 * OT::GSUB
443 */ 393 */
444 394
445 hb_bool_t 395 hb_bool_t
446 hb_ot_layout_has_substitution (hb_face_t *face) 396 hb_ot_layout_has_substitution (hb_face_t *face)
447 { 397 {
448 return &_get_gsub (face) != &Null(GSUB); 398 return &_get_gsub (face) != &OT::Null(OT::GSUB);
399 }
400
401 hb_bool_t
402 hb_ot_layout_would_substitute_lookup (hb_face_t *face,
403 » » » » unsigned int lookup_index,
404 » » » » const hb_codepoint_t *glyphs,
405 » » » » unsigned int glyphs_length,
406 » » » » hb_bool_t zero_context)
407 {
408 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
409 return hb_ot_layout_would_substitute_lookup_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
410 }
411
412 hb_bool_t
413 hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face,
414 » » » » » unsigned int lookup_index,
415 » » » » » const hb_codepoint_t *glyphs,
416 » » » » » unsigned int glyphs_length,
417 » » » » » hb_bool_t zero_context)
418 {
419 if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count )) return false;
420 OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context);
421
422 const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lo okup_index);
423
424 return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_digests[lookup_ index]);
449 } 425 }
450 426
451 void 427 void
452 hb_ot_layout_substitute_start (hb_buffer_t *buffer) 428 hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer)
453 { 429 {
454 GSUB::substitute_start (buffer); 430 OT::GSUB::substitute_start (font, buffer);
455 } 431 }
456 432
457 hb_bool_t 433 hb_bool_t
458 hb_ot_layout_substitute_lookup (hb_face_t *face, 434 hb_ot_layout_substitute_lookup (hb_font_t *font,
459 hb_buffer_t *buffer, 435 hb_buffer_t *buffer,
460 unsigned int lookup_index, 436 unsigned int lookup_index,
461 hb_mask_t mask) 437 hb_mask_t mask)
462 { 438 {
463 hb_apply_context_t c (NULL, face, buffer, mask); 439 if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gsub_lookup _count)) return false;
464 return _get_gsub (face).substitute_lookup (&c, lookup_index); 440
441 OT::hb_apply_context_t c (font, buffer, mask);
442
443 const OT::SubstLookup& l = hb_ot_layout_from_face (font->face)->gsub->get_look up (lookup_index);
444
445 return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gsub_digests[ lookup_index]);
465 } 446 }
466 447
467 void 448 void
468 hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED) 449 hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer)
469 { 450 {
470 GSUB::substitute_finish (buffer); 451 OT::GSUB::substitute_finish (font, buffer);
471 } 452 }
472 453
473 void 454 void
474 hb_ot_layout_substitute_closure_lookup (hb_face_t *face, 455 hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
475 » » » » hb_set_t *glyphs, 456 » » » » unsigned int lookup_index,
476 » » » » unsigned int lookup_index) 457 » » » » hb_set_t *glyphs)
477 { 458 {
478 hb_closure_context_t c (face, glyphs); 459 OT::hb_closure_context_t c (face, glyphs);
479 _get_gsub (face).closure_lookup (&c, lookup_index); 460 _get_gsub (face).closure_lookup (&c, lookup_index);
480 } 461 }
481 462
482 /* 463 /*
483 * GPOS 464 * OT::GPOS
484 */ 465 */
485 466
486 hb_bool_t 467 hb_bool_t
487 hb_ot_layout_has_positioning (hb_face_t *face) 468 hb_ot_layout_has_positioning (hb_face_t *face)
488 { 469 {
489 return &_get_gpos (face) != &Null(GPOS); 470 return &_get_gpos (face) != &OT::Null(OT::GPOS);
490 } 471 }
491 472
492 void 473 void
493 hb_ot_layout_position_start (hb_buffer_t *buffer) 474 hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
494 { 475 {
495 GPOS::position_start (buffer); 476 OT::GPOS::position_start (font, buffer);
496 } 477 }
497 478
498 hb_bool_t 479 hb_bool_t
499 hb_ot_layout_position_lookup (hb_font_t *font, 480 hb_ot_layout_position_lookup (hb_font_t *font,
500 » » » » hb_buffer_t *buffer, 481 » » » hb_buffer_t *buffer,
501 » » » » unsigned int lookup_index, 482 » » » unsigned int lookup_index,
502 » » » » hb_mask_t mask) 483 » » » hb_mask_t mask)
503 { 484 {
504 hb_apply_context_t c (font, font->face, buffer, mask); 485 if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gpos_lookup _count)) return false;
505 return _get_gpos (font->face).position_lookup (&c, lookup_index); 486
487 OT::hb_apply_context_t c (font, buffer, mask);
488
489 const OT::PosLookup& l = hb_ot_layout_from_face (font->face)->gpos->get_lookup (lookup_index);
490
491 return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gpos_digests[ lookup_index]);
506 } 492 }
507 493
508 void 494 void
509 hb_ot_layout_position_finish (hb_buffer_t *buffer) 495 hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t ze ro_width_attached_marks)
510 { 496 {
511 GPOS::position_finish (buffer); 497 OT::GPOS::position_finish (font, buffer, zero_width_attached_marks);
512 } 498 }
513
514
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-layout.h ('k') | third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698