15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2012 Google, Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_SHAPER icu_le 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_icu_le_shaper_font_data_t PortableFontInstance 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-shaper-impl-private.hh" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-icu-le/PortableFontInstance.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "layout/loengine.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unicode/unistr.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-icu.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper face data 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_icu_le_shaper_face_data_t {}; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_icu_le_shaper_face_data_t * 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_icu_le_shaper_face_data_create (hb_face_t *face HB_UNUSED) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (hb_icu_le_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data HB_UNUSED) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper font data 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_icu_le_shaper_font_data_t * 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_icu_le_shaper_font_data_create (hb_font_t *font) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LEErrorCode status = LE_NO_ERROR; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_icu_le_shaper_font_data_t *data = new PortableFontInstance (font->face, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) font->x_scale, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) font->y_scale, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != LE_NO_ERROR) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete (data); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete (data); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper shape_plan data 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_icu_le_shaper_shape_plan_data_t {}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_icu_le_shaper_shape_plan_data_t * 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *user_features, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_user_features) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (hb_icu_le_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_icu_le_shaper_shape_plan_data_destroy (hb_icu_le_shaper_shape_plan_data_t *data) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * shaper 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_bool_t 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_icu_le_shape (hb_shape_plan_t *shape_plan, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_font_t *font, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_t *buffer, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_feature_t *features, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_features) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LEFontInstance *font_instance = HB_SHAPER_DATA_GET (font); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_int32 script_code = hb_icu_script_from_script (shape_plan->props.script); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_int32 language_code = -1 /* TODO */; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_int32 typography_flags = 3; /* Needed for ligatures and kerning */ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LEErrorCode status = LE_NO_ERROR; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_engine *le = le_create ((const le_font *) font_instance, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_code, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) language_code, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typography_flags, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &status); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != LE_NO_ERROR) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { le_close (le); return false; } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)retry: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int scratch_size; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ALLOCATE_ARRAY(Type, name, len) \ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type *name = (Type *) scratch; \ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scratch += (len) * sizeof ((name)[0]); \ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scratch_size -= (len) * sizeof ((name)[0]); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ALLOCATE_ARRAY (LEUnicode, chars, buffer->len); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ALLOCATE_ARRAY (unsigned int, clusters, buffer->len); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* XXX Use UTF-16 decoder! */ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < buffer->len; i++) { 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chars[i] = buffer->info[i].codepoint; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clusters[i] = buffer->info[i].cluster; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int glyph_count = le_layoutChars (le, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chars, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->len, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->len, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_DIRECTION_IS_BACKWARD (buffer->props.direction), 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0., 0., 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &status); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != LE_NO_ERROR) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { le_close (le); return false; } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_glyphs = scratch_size / (sizeof (LEGlyphID) + 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof (le_int32) + 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof (float) * 2); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (glyph_count >= num_glyphs || glyph_count > buffer->allocated)) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->ensure (buffer->allocated * 2); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer->in_error) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { le_close (le); return false; } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto retry; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ALLOCATE_ARRAY (LEGlyphID, glyphs, glyph_count); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ALLOCATE_ARRAY (le_int32, indices, glyph_count); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ALLOCATE_ARRAY (float, positions, glyph_count * 2 + 2); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_getGlyphs (le, glyphs, &status); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_getCharIndices (le, indices, &status); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_getGlyphPositions (le, positions, &status); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ALLOCATE_ARRAY 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ok, we've got everything we need, now compose output buffer, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * very, *very*, carefully! */ 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = 0; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_info_t *info = buffer->info; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < glyph_count; i++) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glyphs[i] >= 0xFFFE) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info[j].codepoint = glyphs[i]; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info[j].cluster = clusters[indices[i]]; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* icu-le doesn't seem to have separate advance values. */ 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info[j].mask = positions[2 * i + 2] - positions[2 * i]; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info[j].var1.u32 = 0; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info[j].var2.u32 = -positions[2 * i + 1]; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->len = j; 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->clear_positions (); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < buffer->len; i++) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_info_t *info = &buffer->info[i]; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_glyph_position_t *pos = &buffer->pos[i]; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO vertical */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos->x_advance = info->mask; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos->x_offset = info->var1.u32; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos->y_offset = info->var2.u32; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) le_close (le); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)