hb-ot-layout.cc 14.6 KB
Newer Older
B
Behdad Esfahbod 已提交
1
/*
B
Behdad Esfahbod 已提交
2 3 4
 * Copyright © 1998-2004  David Turner and Werner Lemberg
 * Copyright © 2006  Behdad Esfahbod
 * Copyright © 2007,2008,2009  Red Hat, Inc.
B
Behdad Esfahbod 已提交
5
 *
B
Behdad Esfahbod 已提交
6
 *  This is part of HarfBuzz, a text shaping library.
B
Behdad Esfahbod 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Behdad Esfahbod
 */

29
#include "hb-ot-layout-private.hh"
B
Behdad Esfahbod 已提交
30

31 32 33 34
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
#include "hb-ot-maxp-table.hh"
B
Behdad Esfahbod 已提交
35

B
Behdad Esfahbod 已提交
36

B
Behdad Esfahbod 已提交
37
#include <stdlib.h>
B
Behdad Esfahbod 已提交
38 39
#include <string.h>

B
Behdad Esfahbod 已提交
40

B
Behdad Esfahbod 已提交
41

B
Behdad Esfahbod 已提交
42
hb_ot_layout_t *
43
_hb_ot_layout_create (hb_face_t *face)
44
{
45
  /* TODO Remove this object altogether */
B
Behdad Esfahbod 已提交
46
  hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
47

48
  layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GDEF));
49
  layout->gdef = Sanitizer<GDEF>::lock_instance (layout->gdef_blob);
B
Behdad Esfahbod 已提交
50

51
  layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GSUB));
52
  layout->gsub = Sanitizer<GSUB>::lock_instance (layout->gsub_blob);
B
Behdad Esfahbod 已提交
53

54
  layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS));
55
  layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob);
B
Behdad Esfahbod 已提交
56 57

  return layout;
B
Behdad Esfahbod 已提交
58 59
}

60
void
61
_hb_ot_layout_destroy (hb_ot_layout_t *layout)
B
Behdad Esfahbod 已提交
62
{
B
Behdad Esfahbod 已提交
63 64 65
  hb_blob_destroy (layout->gdef_blob);
  hb_blob_destroy (layout->gsub_blob);
  hb_blob_destroy (layout->gpos_blob);
B
Behdad Esfahbod 已提交
66

B
Behdad Esfahbod 已提交
67
  free (layout);
68
}
B
Behdad Esfahbod 已提交
69

B
Behdad Esfahbod 已提交
70
static inline const GDEF&
71 72
_get_gdef (hb_face_t *face)
{
B
Behdad Esfahbod 已提交
73
  return likely (face->ot_layout && face->ot_layout->gdef) ? *face->ot_layout->gdef : Null(GDEF);
74
}
B
Behdad Esfahbod 已提交
75
static inline const GSUB&
76
_get_gsub (hb_face_t *face)
B
Behdad Esfahbod 已提交
77
{
B
Behdad Esfahbod 已提交
78
  return likely (face->ot_layout && face->ot_layout->gsub) ? *face->ot_layout->gsub : Null(GSUB);
B
Behdad Esfahbod 已提交
79
}
B
Behdad Esfahbod 已提交
80
static inline const GPOS&
81
_get_gpos (hb_face_t *face)
B
Behdad Esfahbod 已提交
82
{
B
Behdad Esfahbod 已提交
83
  return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->gpos : Null(GPOS);
B
Behdad Esfahbod 已提交
84 85
}

86

B
Behdad Esfahbod 已提交
87 88 89 90 91
/*
 * GDEF
 */

hb_bool_t
92
hb_ot_layout_has_glyph_classes (hb_face_t *face)
B
Behdad Esfahbod 已提交
93
{
94
  return _get_gdef (face).has_glyph_classes ();
B
Behdad Esfahbod 已提交
95 96
}

B
Behdad Esfahbod 已提交
97
unsigned int
98 99 100
_hb_ot_layout_get_glyph_property (hb_face_t       *face,
				  hb_glyph_info_t *info)
{
B
Behdad Esfahbod 已提交
101
  if (!info->props_cache())
B
Behdad Esfahbod 已提交
102 103
  {
    const GDEF &gdef = _get_gdef (face);
B
Behdad Esfahbod 已提交
104
    info->props_cache() = gdef.get_glyph_props (info->codepoint);
B
Behdad Esfahbod 已提交
105
  }
106

B
Behdad Esfahbod 已提交
107
  return info->props_cache();
108 109
}

B
Behdad Esfahbod 已提交
110 111 112 113 114
static hb_bool_t
_hb_ot_layout_match_properties (hb_face_t      *face,
				hb_codepoint_t  codepoint,
				unsigned int    glyph_props,
				unsigned int    lookup_props)
B
Behdad Esfahbod 已提交
115
{
116
  /* Not covered, if, for example, glyph class is ligature and
117
   * lookup_props includes LookupFlags::IgnoreLigatures
B
Behdad Esfahbod 已提交
118
   */
B
Behdad Esfahbod 已提交
119
  if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
B
Behdad Esfahbod 已提交
120 121
    return false;

B
Behdad Esfahbod 已提交
122
  if (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
B
Behdad Esfahbod 已提交
123
  {
B
Behdad Esfahbod 已提交
124
    /* If using mark filtering sets, the high short of
125
     * lookup_props has the set index.
B
Behdad Esfahbod 已提交
126
     */
127
    if (lookup_props & LookupFlag::UseMarkFilteringSet)
B
Behdad Esfahbod 已提交
128
      return _get_gdef (face).mark_set_covers (lookup_props >> 16, codepoint);
B
Behdad Esfahbod 已提交
129

130
    /* The second byte of lookup_props has the meaning
B
Behdad Esfahbod 已提交
131 132 133
     * "ignore marks of attachment type different than
     * the attachment type specified."
     */
B
Behdad Esfahbod 已提交
134 135
    if (lookup_props & LookupFlag::MarkAttachmentType && glyph_props & LookupFlag::MarkAttachmentType)
      return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
B
Behdad Esfahbod 已提交
136 137
  }

B
Behdad Esfahbod 已提交
138
  return true;
B
Behdad Esfahbod 已提交
139 140
}

B
Behdad Esfahbod 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
hb_bool_t
_hb_ot_layout_check_glyph_property (hb_face_t    *face,
				    hb_glyph_info_t *ginfo,
				    unsigned int  lookup_props,
				    unsigned int *property_out)
{
  unsigned int property;

  property = _hb_ot_layout_get_glyph_property (face, ginfo);
  (void) (property_out && (*property_out = property));

  return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
}

hb_bool_t
_hb_ot_layout_skip_mark (hb_face_t    *face,
			 hb_glyph_info_t *ginfo,
			 unsigned int  lookup_props,
			 unsigned int *property_out)
{
  unsigned int property;

  property = _hb_ot_layout_get_glyph_property (face, ginfo);
  (void) (property_out && (*property_out = property));

  /* If it's a mark, skip it we don't accept it. */
  if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
    return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);

  /* If not a mark, don't skip. */
  return false;
}



B
Behdad Esfahbod 已提交
176
unsigned int
177
hb_ot_layout_get_attach_points (hb_face_t      *face,
B
Behdad Esfahbod 已提交
178
				hb_codepoint_t  glyph,
B
Behdad Esfahbod 已提交
179
				unsigned int    start_offset,
B
Behdad Esfahbod 已提交
180 181 182
				unsigned int   *point_count /* IN/OUT */,
				unsigned int   *point_array /* OUT */)
{
B
Behdad Esfahbod 已提交
183
  return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
B
Behdad Esfahbod 已提交
184 185
}

B
Behdad Esfahbod 已提交
186
unsigned int
187 188 189 190 191 192
hb_ot_layout_get_ligature_carets (hb_font_t      *font,
				  hb_direction_t  direction,
				  hb_codepoint_t  glyph,
				  unsigned int    start_offset,
				  unsigned int   *caret_count /* IN/OUT */,
				  int            *caret_array /* OUT */)
B
Behdad Esfahbod 已提交
193
{
194
  return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
B
Behdad Esfahbod 已提交
195 196
}

197 198 199 200 201
/*
 * GSUB/GPOS
 */

static const GSUBGPOS&
202 203
get_gsubgpos_table (hb_face_t *face,
		    hb_tag_t   table_tag)
204
{
205
  switch (table_tag) {
206 207
    case HB_OT_TAG_GSUB: return _get_gsub (face);
    case HB_OT_TAG_GPOS: return _get_gpos (face);
208
    default:             return Null(GSUBGPOS);
209 210 211 212
  }
}


B
Behdad Esfahbod 已提交
213
unsigned int
214 215
hb_ot_layout_table_get_script_tags (hb_face_t    *face,
				    hb_tag_t      table_tag,
B
Behdad Esfahbod 已提交
216
				    unsigned int  start_offset,
217 218
				    unsigned int *script_count /* IN/OUT */,
				    hb_tag_t     *script_tags /* OUT */)
219
{
220
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
221

B
Behdad Esfahbod 已提交
222
  return g.get_script_tags (start_offset, script_count, script_tags);
223 224 225
}

hb_bool_t
226 227 228 229
hb_ot_layout_table_find_script (hb_face_t    *face,
				hb_tag_t      table_tag,
				hb_tag_t      script_tag,
				unsigned int *script_index)
230
{
B
Behdad Esfahbod 已提交
231
  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
232
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
233 234 235 236 237

  if (g.find_script_index (script_tag, script_index))
    return TRUE;

  /* try finding 'DFLT' */
238
  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
239 240
    return FALSE;

241 242
  /* try with 'dflt'; MS site has had typos and many fonts use it now :(.
   * including many versions of DejaVu Sans Mono! */
243
  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
B
Behdad Esfahbod 已提交
244 245 246 247 248 249 250 251 252 253
    return FALSE;

  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
  return FALSE;
}

hb_bool_t
hb_ot_layout_table_choose_script (hb_face_t      *face,
				  hb_tag_t        table_tag,
				  const hb_tag_t *script_tags,
B
Behdad Esfahbod 已提交
254 255
				  unsigned int   *script_index,
				  hb_tag_t       *chosen_script)
B
Behdad Esfahbod 已提交
256
{
B
Behdad Esfahbod 已提交
257
  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
B
Behdad Esfahbod 已提交
258 259 260 261
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);

  while (*script_tags)
  {
B
Behdad Esfahbod 已提交
262 263 264
    if (g.find_script_index (*script_tags, script_index)) {
      if (chosen_script)
        *chosen_script = *script_tags;
B
Behdad Esfahbod 已提交
265
      return TRUE;
B
Behdad Esfahbod 已提交
266
    }
B
Behdad Esfahbod 已提交
267 268 269 270
    script_tags++;
  }

  /* try finding 'DFLT' */
B
Behdad Esfahbod 已提交
271 272 273
  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) {
    if (chosen_script)
      *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT;
B
Behdad Esfahbod 已提交
274
    return FALSE;
B
Behdad Esfahbod 已提交
275
  }
B
Behdad Esfahbod 已提交
276 277

  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
B
Behdad Esfahbod 已提交
278 279 280
  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) {
    if (chosen_script)
      *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE;
281
    return FALSE;
B
Behdad Esfahbod 已提交
282
  }
283

284 285 286 287 288 289 290 291 292
  /* try with 'latn'; some old fonts put their features there even though
     they're really trying to support Thai, for example :( */
#define HB_OT_TAG_LATIN_SCRIPT		HB_TAG ('l', 'a', 't', 'n')
  if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) {
    if (chosen_script)
      *chosen_script = HB_OT_TAG_LATIN_SCRIPT;
    return FALSE;
  }

293
  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
B
Behdad Esfahbod 已提交
294 295
  if (chosen_script)
    *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
296 297 298
  return FALSE;
}

B
Behdad Esfahbod 已提交
299
unsigned int
300 301
hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
				     hb_tag_t      table_tag,
B
Behdad Esfahbod 已提交
302
				     unsigned int  start_offset,
303 304
				     unsigned int *feature_count /* IN/OUT */,
				     hb_tag_t     *feature_tags /* OUT */)
305
{
306
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
307

B
Behdad Esfahbod 已提交
308
  return g.get_feature_tags (start_offset, feature_count, feature_tags);
309 310 311
}


B
Behdad Esfahbod 已提交
312
unsigned int
313 314 315
hb_ot_layout_script_get_language_tags (hb_face_t    *face,
				       hb_tag_t      table_tag,
				       unsigned int  script_index,
B
Behdad Esfahbod 已提交
316
				       unsigned int  start_offset,
317 318
				       unsigned int *language_count /* IN/OUT */,
				       hb_tag_t     *language_tags /* OUT */)
319
{
320
  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
321

B
Behdad Esfahbod 已提交
322
  return s.get_lang_sys_tags (start_offset, language_count, language_tags);
323 324 325
}

hb_bool_t
326 327 328 329 330
hb_ot_layout_script_find_language (hb_face_t    *face,
				   hb_tag_t      table_tag,
				   unsigned int  script_index,
				   hb_tag_t      language_tag,
				   unsigned int *language_index)
331
{
B
Behdad Esfahbod 已提交
332
  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
333
  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
334

335
  if (s.find_lang_sys_index (language_tag, language_index))
336 337 338
    return TRUE;

  /* 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))
340 341
    return FALSE;

342
  if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
343
  return FALSE;
344
}
345

346
hb_bool_t
347 348 349 350 351
hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
						  hb_tag_t      table_tag,
						  unsigned int  script_index,
						  unsigned int  language_index,
						  unsigned int *feature_index)
352
{
353
  const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
354

355
  if (feature_index) *feature_index = l.get_required_feature_index ();
356

357 358
  return l.has_required_feature ();
}
359

B
Behdad Esfahbod 已提交
360
unsigned int
361 362 363 364
hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
					   hb_tag_t      table_tag,
					   unsigned int  script_index,
					   unsigned int  language_index,
B
Behdad Esfahbod 已提交
365
					   unsigned int  start_offset,
366 367
					   unsigned int *feature_count /* IN/OUT */,
					   unsigned int *feature_indexes /* OUT */)
368
{
369
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
370 371
  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);

B
Behdad Esfahbod 已提交
372
  return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
373 374
}

B
Behdad Esfahbod 已提交
375
unsigned int
376 377 378 379
hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
					hb_tag_t      table_tag,
					unsigned int  script_index,
					unsigned int  language_index,
B
Behdad Esfahbod 已提交
380
					unsigned int  start_offset,
381 382
					unsigned int *feature_count /* IN/OUT */,
					hb_tag_t     *feature_tags /* OUT */)
383
{
384
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
385
  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
386

387
  ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
B
Behdad Esfahbod 已提交
388
  unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
389

B
Behdad Esfahbod 已提交
390 391 392 393 394
  if (feature_tags) {
    unsigned int count = *feature_count;
    for (unsigned int i = 0; i < count; i++)
      feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
  }
395 396

  return ret;
397 398 399 400
}


hb_bool_t
401 402 403 404 405 406
hb_ot_layout_language_find_feature (hb_face_t    *face,
				    hb_tag_t      table_tag,
				    unsigned int  script_index,
				    unsigned int  language_index,
				    hb_tag_t      feature_tag,
				    unsigned int *feature_index)
407
{
B
Behdad Esfahbod 已提交
408
  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
409
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
410 411
  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);

B
Behdad Esfahbod 已提交
412 413
  unsigned int num_features = l.get_feature_count ();
  for (unsigned int i = 0; i < num_features; i++) {
414 415 416 417 418 419 420
    unsigned int f_index = l.get_feature_index (i);

    if (feature_tag == g.get_feature_tag (f_index)) {
      if (feature_index) *feature_index = f_index;
      return TRUE;
    }
  }
421

422
  if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
423 424
  return FALSE;
}
425

B
Behdad Esfahbod 已提交
426
unsigned int
427 428 429
hb_ot_layout_feature_get_lookup_indexes (hb_face_t    *face,
					 hb_tag_t      table_tag,
					 unsigned int  feature_index,
B
Behdad Esfahbod 已提交
430
					 unsigned int  start_offset,
431 432
					 unsigned int *lookup_count /* IN/OUT */,
					 unsigned int *lookup_indexes /* OUT */)
433
{
434
  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
435 436
  const Feature &f = g.get_feature (feature_index);

B
Behdad Esfahbod 已提交
437
  return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
438 439
}

B
Behdad Esfahbod 已提交
440 441 442 443 444 445

/*
 * GSUB
 */

hb_bool_t
446 447
hb_ot_layout_has_substitution (hb_face_t *face)
{
448
  return &_get_gsub (face) != &Null(GSUB);
449 450
}

451 452 453
void
hb_ot_layout_substitute_start (hb_buffer_t  *buffer)
{
B
Behdad Esfahbod 已提交
454
  GSUB::substitute_start (buffer);
455 456
}

457
hb_bool_t
458 459 460 461
hb_ot_layout_substitute_lookup (hb_face_t    *face,
				hb_buffer_t  *buffer,
				unsigned int  lookup_index,
				hb_mask_t     mask)
B
Behdad Esfahbod 已提交
462
{
B
Behdad Esfahbod 已提交
463 464
  hb_apply_context_t c (NULL, face, buffer, mask);
  return _get_gsub (face).substitute_lookup (&c, lookup_index);
465 466
}

467
void
468
hb_ot_layout_substitute_finish (hb_buffer_t  *buffer HB_UNUSED)
469
{
B
Behdad Esfahbod 已提交
470
  GSUB::substitute_finish (buffer);
471 472
}

B
Behdad Esfahbod 已提交
473 474 475 476
void
hb_ot_layout_substitute_closure_lookup (hb_face_t    *face,
				        hb_set_t     *glyphs,
				        unsigned int  lookup_index)
477 478
{
  hb_closure_context_t c (face, glyphs);
B
Behdad Esfahbod 已提交
479
  _get_gsub (face).closure_lookup (&c, lookup_index);
480
}
481

482 483 484 485 486
/*
 * GPOS
 */

hb_bool_t
487 488
hb_ot_layout_has_positioning (hb_face_t *face)
{
489
  return &_get_gpos (face) != &Null(GPOS);
490 491
}

492 493 494
void
hb_ot_layout_position_start (hb_buffer_t  *buffer)
{
B
Behdad Esfahbod 已提交
495
  GPOS::position_start (buffer);
496 497
}

498
hb_bool_t
499
hb_ot_layout_position_lookup   (hb_font_t    *font,
500 501 502
				hb_buffer_t  *buffer,
				unsigned int  lookup_index,
				hb_mask_t     mask)
503
{
B
Behdad Esfahbod 已提交
504 505
  hb_apply_context_t c (font, font->face, buffer, mask);
  return _get_gpos (font->face).position_lookup (&c, lookup_index);
506
}
507 508

void
B
Behdad Esfahbod 已提交
509
hb_ot_layout_position_finish (hb_buffer_t  *buffer)
510
{
B
Behdad Esfahbod 已提交
511
  GPOS::position_finish (buffer);
512
}
B
Behdad Esfahbod 已提交
513 514