17d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod/*
27d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * Copyright © 2012  Google, Inc.
37d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod *
47d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
57d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod *
67d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * Permission is hereby granted, without written agreement and without
77d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
87d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * software and its documentation for any purpose, provided that the
97d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
107d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * all copies of this software.
117d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod *
127d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
137d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
147d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
157d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
167d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * DAMAGE.
177d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod *
187d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
197d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
207d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
217d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
227d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
237d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod *
247d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * Google Author(s): Behdad Esfahbod
257d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod */
267d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
277d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod#define HB_SHAPER icu_le
28ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod#define hb_icu_le_shaper_font_data_t PortableFontInstance
297d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod#include "hb-shaper-impl-private.hh"
307d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
317d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod#include "hb-icu-le/PortableFontInstance.h"
327d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
3371ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod#include "layout/loengine.h"
342f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod#include "unicode/unistr.h"
357d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
362f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod#include "hb-icu.h"
377d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
387d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
397d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod/*
407d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * shaper face data
417d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod */
427d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
437d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodstruct hb_icu_le_shaper_face_data_t {};
447d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
457d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodhb_icu_le_shaper_face_data_t *
460beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod_hb_icu_le_shaper_face_data_create (hb_face_t *face HB_UNUSED)
477d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod{
487d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod  return (hb_icu_le_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
497d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod}
507d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
517d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodvoid
520beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data HB_UNUSED)
537d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod{
547d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod}
557d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
567d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
577d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod/*
587d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * shaper font data
597d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod */
607d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
617d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodhb_icu_le_shaper_font_data_t *
627d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod_hb_icu_le_shaper_font_data_create (hb_font_t *font)
637d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod{
64ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod  LEErrorCode status = LE_NO_ERROR;
65ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod  hb_icu_le_shaper_font_data_t *data = new PortableFontInstance (font->face,
66ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod								 font->x_scale,
67ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod								 font->y_scale,
68ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod								 status);
69ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod  if (status != LE_NO_ERROR) {
70ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod    delete (data);
71ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod    return NULL;
72ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod  }
73ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod
74ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod  return data;
757d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod}
767d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
777d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodvoid
787d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod_hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data)
797d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod{
80ba7f6c3797e5b440557bacd9b666bf09713dca76Behdad Esfahbod  delete (data);
817d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod}
827d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
837d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
847d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod/*
857d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * shaper shape_plan data
867d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod */
877d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
887d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodstruct hb_icu_le_shaper_shape_plan_data_t {};
897d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
907d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodhb_icu_le_shaper_shape_plan_data_t *
910beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
922f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					  const hb_feature_t *user_features,
932f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					  unsigned int        num_user_features)
947d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod{
957d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod  return (hb_icu_le_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
967d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod}
977d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
987d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodvoid
997d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod_hb_icu_le_shaper_shape_plan_data_destroy (hb_icu_le_shaper_shape_plan_data_t *data)
1007d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod{
1017d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod}
1027d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
1037d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
1047d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod/*
1057d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod * shaper
1067d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod */
1077d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod
1087d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbodhb_bool_t
1097d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod_hb_icu_le_shape (hb_shape_plan_t    *shape_plan,
1107d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod		  hb_font_t          *font,
1117d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod		  hb_buffer_t        *buffer,
1127d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod		  const hb_feature_t *features,
1137d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod		  unsigned int        num_features)
1147d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod{
1152f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  LEFontInstance *font_instance = HB_SHAPER_DATA_GET (font);
1162f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  le_int32 script_code = hb_icu_script_from_script (shape_plan->props.script);
1172f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  le_int32 language_code = -1 /* TODO */;
1187d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod  le_int32 typography_flags = 3; /* Needed for ligatures and kerning */
1192f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  LEErrorCode status = LE_NO_ERROR;
12071ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  le_engine *le = le_create ((const le_font *) font_instance,
12171ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod			     script_code,
12271ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod			     language_code,
12371ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod			     typography_flags,
12471ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod			     &status);
1252f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  if (status != LE_NO_ERROR)
12671ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  { le_close (le); return false; }
1272f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1282f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbodretry:
1292f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1302f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  unsigned int scratch_size;
1312f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
1322f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1332f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod#define ALLOCATE_ARRAY(Type, name, len) \
1342f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  Type *name = (Type *) scratch; \
1352f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  scratch += (len) * sizeof ((name)[0]); \
1362f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  scratch_size -= (len) * sizeof ((name)[0]);
1372f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1382f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  ALLOCATE_ARRAY (LEUnicode, chars, buffer->len);
1392f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  ALLOCATE_ARRAY (unsigned int, clusters, buffer->len);
1402f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
141b7115b63be72e109b51f538ba581aed1017b2d55Behdad Esfahbod  /* XXX Use UTF-16 decoder! */
1422f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  for (unsigned int i = 0; i < buffer->len; i++) {
1432f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    chars[i] = buffer->info[i].codepoint;
1442f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    clusters[i] = buffer->info[i].cluster;
1452f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  }
1462f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
14771ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  unsigned int glyph_count = le_layoutChars (le,
14871ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod					     chars,
1492f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					     0,
1502f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					     buffer->len,
1512f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					     buffer->len,
1522f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					     HB_DIRECTION_IS_BACKWARD (buffer->props.direction),
1532f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					     0., 0.,
15471ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod					     &status);
1552f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  if (status != LE_NO_ERROR)
15671ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  { le_close (le); return false; }
1572f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1582f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  unsigned int num_glyphs = scratch_size / (sizeof (LEGlyphID) +
1592f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					    sizeof (le_int32) +
1602f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod					    sizeof (float) * 2);
1612f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1622f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  if (unlikely (glyph_count >= num_glyphs || glyph_count > buffer->allocated)) {
1632f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    buffer->ensure (buffer->allocated * 2);
1642f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    if (buffer->in_error)
16571ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod    { le_close (le); return false; }
1662f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    goto retry;
1672f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  }
1682f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1692f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  ALLOCATE_ARRAY (LEGlyphID, glyphs, glyph_count);
1702f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  ALLOCATE_ARRAY (le_int32, indices, glyph_count);
1712f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  ALLOCATE_ARRAY (float, positions, glyph_count * 2 + 2);
1722f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
17371ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  le_getGlyphs (le, glyphs, &status);
17471ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  le_getCharIndices (le, indices, &status);
17571ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  le_getGlyphPositions (le, positions, &status);
1762f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1772f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod#undef ALLOCATE_ARRAY
1782f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1792f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  /* Ok, we've got everything we need, now compose output buffer,
1802f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod   * very, *very*, carefully! */
1812f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1822f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  unsigned int j = 0;
1832f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  hb_glyph_info_t *info = buffer->info;
1842f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  for (unsigned int i = 0; i < glyph_count; i++)
1852f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  {
1862f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    if (glyphs[i] >= 0xFFFE)
1872f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod	continue;
1882f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1892f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    info[j].codepoint = glyphs[i];
1902f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    info[j].cluster = clusters[indices[i]];
1912f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1924c1d9244617e472464722e64d2cdbc1f9e8827f6Behdad Esfahbod    /* icu-le doesn't seem to have separate advance values. */
1932f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    info[j].mask = positions[2 * i + 2] - positions[2 * i];
1942f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    info[j].var1.u32 = 0;
1952f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    info[j].var2.u32 = -positions[2 * i + 1];
1962f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
1972f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    j++;
1982f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  }
1992f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  buffer->len = j;
2002f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
2012f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  buffer->clear_positions ();
2022f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
2032f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  for (unsigned int i = 0; i < buffer->len; i++) {
2042f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    hb_glyph_info_t *info = &buffer->info[i];
2052f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    hb_glyph_position_t *pos = &buffer->pos[i];
2062f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
2072f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    /* TODO vertical */
2082f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    pos->x_advance = info->mask;
2092f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    pos->x_offset = info->var1.u32;
2102f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod    pos->y_offset = info->var2.u32;
2112f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  }
2122f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod
21371ee1f24503cd066ffc1a36cc5dd9a3c1d1a6dfdBehdad Esfahbod  le_close (le);
2142f7586c6229096143ca0a96712a27416ee0d3c85Behdad Esfahbod  return true;
2157d242364ea647f655a7092bda25f9a10774c57f5Behdad Esfahbod}
216