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