hb-buffer.cc revision bd7378b2ef9793de4e7f57b920f29f48ac9d0c25
1a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod/* 2a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Copyright (C) 1998-2004 David Turner and Werner Lemberg 322da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod * Copyright (C) 2004,2007,2009,2010 Red Hat, Inc. 49f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod * 5c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 69f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod * 7a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Permission is hereby granted, without written agreement and without 8a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 9a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * software and its documentation for any purpose, provided that the 10a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 11a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * all copies of this software. 12a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 13a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DAMAGE. 18a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 19a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 25a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Red Hat Author(s): Owen Taylor, Behdad Esfahbod 269f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod */ 279f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 2822da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-buffer-private.hh" 299f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3088a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod#include <string.h> 3188a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod 32acdba3f90b232fc12fcb200dca2584481b339118Behdad EsfahbodHB_BEGIN_DECLS 33acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 34f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod 3511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodstatic hb_buffer_t _hb_buffer_nil = { 365ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod HB_REFERENCE_COUNT_INVALID, /* ref_count */ 375ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 385ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod &_hb_unicode_funcs_nil /* unicode */ 3911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}; 4011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 41a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod/* Here is how the buffer works internally: 42a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 43910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * There are two info pointers: info and out_info. They always have 44910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * the same allocated size, but different lengths. 45a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 469d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As an optimization, both info and out_info may point to the 477e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod * same piece of memory, which is owned by info. This remains the 4829427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod * case as long as out_len doesn't exceed len at any time. 49910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * In that case, swap() is no-op and the glyph operations operate 50910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * mostly in-place. 51a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 529d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As soon as out_info gets longer than info, out_info is moved over 53910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * to an alternate buffer (which we reuse the pos buffer for!), and its 54910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * current contents (out_len entries) are copied to the new place. 55910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * This should all remain transparent to the user. swap() then 56910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * switches info and out_info. 57a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */ 58a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 59c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 603567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodstatic hb_bool_t 613567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_enlarge (hb_buffer_t *buffer, unsigned int size) 623567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 633567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (buffer->in_error)) 643567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return FALSE; 653567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 663567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod unsigned int new_allocated = buffer->allocated; 673567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod hb_internal_glyph_position_t *new_pos; 683567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod hb_internal_glyph_info_t *new_info; 693567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod bool separate_out; 703567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 713567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod separate_out = buffer->out_info != buffer->info; 723567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 733567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod while (size > new_allocated) 743567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod new_allocated += (new_allocated >> 1) + 8; 753567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 763567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod new_pos = (hb_internal_glyph_position_t *) realloc (buffer->pos, new_allocated * sizeof (buffer->pos[0])); 773567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod new_info = (hb_internal_glyph_info_t *) realloc (buffer->info, new_allocated * sizeof (buffer->info[0])); 783567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 793567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!new_pos || !new_info)) 803567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->in_error = TRUE; 813567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 823567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_pos)) 833567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->pos = new_pos; 843567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 853567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_info)) 863567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->info = new_info; 873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 883567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->out_info = separate_out ? (hb_internal_glyph_info_t *) buffer->pos : buffer->info; 893567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (!buffer->in_error)) 903567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->allocated = new_allocated; 913567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 923567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return likely (!buffer->in_error); 933567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 943567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 953567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodstatic inline hb_bool_t 963567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_ensure (hb_buffer_t *buffer, unsigned int size) 973567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 983567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return likely (size <= buffer->allocated) ? TRUE : _hb_buffer_enlarge (buffer, size); 993567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1006b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 101acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbodstatic inline hb_bool_t 1023567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size) 103c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{ 1043567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, size))) return FALSE; 105a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 1069d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info == buffer->info) 107e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 108e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod assert (buffer->have_output); 109e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod 1101b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->out_info = (hb_internal_glyph_info_t *) buffer->pos; 11129427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod memcpy (buffer->out_info, buffer->info, buffer->out_len * sizeof (buffer->out_info[0])); 112e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 113a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 114a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod return TRUE; 115a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 116a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 1173567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1186b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */ 1196b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 120b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t * 12111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_create (unsigned int pre_alloc_size) 1229f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 123b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_t *buffer; 124b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod 1255fc22e647c8a2bf6d3cb59185e351ac625e7e322Behdad Esfahbod if (!HB_OBJECT_DO_CREATE (hb_buffer_t, buffer)) 12611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return &_hb_buffer_nil; 1279f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 12811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod if (pre_alloc_size) 1293567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod _hb_buffer_ensure (buffer, pre_alloc_size); 1309f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 1315ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod buffer->unicode = &_hb_unicode_funcs_nil; 1325ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 13311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return buffer; 13411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 1357a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 13611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_t * 13711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_reference (hb_buffer_t *buffer) 13811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 13911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod HB_OBJECT_DO_REFERENCE (buffer); 14011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 141f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 14211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 14311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_get_reference_count (hb_buffer_t *buffer) 14411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 14511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod HB_OBJECT_DO_GET_REFERENCE_COUNT (buffer); 146a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 1479f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 1487a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 14911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_destroy (hb_buffer_t *buffer) 1507a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 15111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod HB_OBJECT_DO_DESTROY (buffer); 15211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 1535ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 1545ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1557e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod free (buffer->info); 1561b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod free (buffer->pos); 15711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 158b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer); 1597a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 1607a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 1615ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1625ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 1635ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 1645ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_t *unicode) 1655ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 1660465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod if (!unicode) 1670465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod unicode = &_hb_unicode_funcs_nil; 1680465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod 1695ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_reference (unicode); 1705ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 1715ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod buffer->unicode = unicode; 1725ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 1735ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1745ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_unicode_funcs_t * 1755ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_unicode_funcs (hb_buffer_t *buffer) 1765ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 1775ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod return buffer->unicode; 1785ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 1795ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1805ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 1815ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_direction (hb_buffer_t *buffer, 1825ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_direction_t direction) 1835ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1845ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 1854e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.direction = direction; 1865ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 1875ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1885ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_direction_t 1895ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_direction (hb_buffer_t *buffer) 1905ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 1914e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.direction; 1925ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 1935ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 194ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 195ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_script (hb_buffer_t *buffer, 196ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_script_t script) 197ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 1984e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.script = script; 199ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 200ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 201ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_script_t 202ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_script (hb_buffer_t *buffer) 203ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2044e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.script; 205ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 206ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 207ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 208ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_language (hb_buffer_t *buffer, 209ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_language_t language) 210ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2114e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.language = language; 212ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 213ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 214ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_language_t 215ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_language (hb_buffer_t *buffer) 216ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2174e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.language; 218ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 219ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 2205ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2217a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 222c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbodhb_buffer_clear (hb_buffer_t *buffer) 2237a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 224e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod buffer->have_output = FALSE; 225314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod buffer->have_positions = FALSE; 226a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod buffer->in_error = FALSE; 2276960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod buffer->len = 0; 22829427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len = 0; 22936b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i = 0; 2309d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod buffer->out_info = buffer->info; 231c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->max_lig_id = 0; 2327a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 2337a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 234a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbodhb_bool_t 235f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodhb_buffer_ensure (hb_buffer_t *buffer, unsigned int size) 236f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{ 2373567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return _hb_buffer_ensure (buffer, size); 238f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 239f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 240f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid 2413015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbodhb_buffer_add_glyph (hb_buffer_t *buffer, 242f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod hb_codepoint_t codepoint, 243468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod hb_mask_t mask, 2443015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int cluster) 2456b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{ 246f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod hb_internal_glyph_info_t *glyph; 2475c0adce1ccc739415c4b26ff13ffd2d77ea4bc6cBehdad Esfahbod 2483567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->len + 1))) return; 2496b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 2506960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod glyph = &buffer->info[buffer->len]; 251f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod glyph->codepoint = codepoint; 252468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod glyph->mask = mask; 2536b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->cluster = cluster; 2546b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->component = 0; 255f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod glyph->lig_id = 0; 256f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod glyph->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; 2576b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 2586960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod buffer->len++; 2596b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod} 2606b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 26111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodvoid 26211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_clear_positions (hb_buffer_t *buffer) 26306003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod{ 26415c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod _hb_buffer_clear_output (buffer); 265e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod buffer->have_output = FALSE; 266314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod buffer->have_positions = TRUE; 26715c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod 2681b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod if (unlikely (!buffer->pos)) 269c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod { 2701b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos = (hb_internal_glyph_position_t *) calloc (buffer->allocated, sizeof (buffer->pos[0])); 271c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod return; 272c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod } 27306003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod 2746960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod memset (buffer->pos, 0, sizeof (buffer->pos[0]) * buffer->len); 27506003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod} 27606003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod 2773567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod/* HarfBuzz-Internal API */ 2783567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 2793567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodvoid 2803567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_clear_output (hb_buffer_t *buffer) 2813567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 2823567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->have_output = TRUE; 2833567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->have_positions = FALSE; 2843567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->out_len = 0; 2853567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->out_info = buffer->info; 2863567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 2873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 288081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 289c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_swap (hb_buffer_t *buffer) 2909f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 291c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod unsigned int tmp; 2929f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 293e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod assert (buffer->have_output); 294e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod 295a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod if (unlikely (buffer->in_error)) return; 296a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 2979d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 298e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 299f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod hb_internal_glyph_info_t *tmp_string; 3007e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod tmp_string = buffer->info; 3019d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod buffer->info = buffer->out_info; 3029d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod buffer->out_info = tmp_string; 3031b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos = (hb_internal_glyph_position_t *) buffer->out_info; 304e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 3059f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3066960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod tmp = buffer->len; 30729427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->len = buffer->out_len; 30829427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len = tmp; 3099f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 31036b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i = 0; 3119f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 3129f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3139f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod/* The following function copies `num_out' elements from `glyph_data' 3149d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod to `buffer->out_info', advancing the in array pointer in the structure 3159f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod by `num_in' elements, and the out array pointer by `num_out' elements. 3169f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod Finally, it sets the `length' field of `out' equal to 3179f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod `pos' of the `out' structure. 3189f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 31936b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod If `component' is 0xFFFF, the component value from buffer->i 3209f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod will copied `num_out' times, otherwise `component' itself will 3219f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod be used to fill the `component' fields. 3229f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 32336b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod If `lig_id' is 0xFFFF, the lig_id value from buffer->i 324f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod will copied `num_out' times, otherwise `lig_id' itself will 325f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod be used to fill the `lig_id' fields. 3269f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 327468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod The mask for all replacement glyphs are taken 32836b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod from the glyph at position `buffer->i'. 3299f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 33036b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod The cluster value for the glyph at position buffer->i is used 3319f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod for all replacement glyphs */ 33225e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 333081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 3343015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod_hb_buffer_add_output_glyphs (hb_buffer_t *buffer, 3353015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int num_in, 3363015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int num_out, 33725e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod const hb_codepoint_t *glyph_data, 3383015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned short component, 339f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod unsigned short lig_id) 3409f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 3413015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int i; 342468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod unsigned int mask; 3433015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int cluster; 3449f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3459d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info || 34636b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_len + num_out > buffer->i + num_in) 347e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 3483567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure_separate (buffer, buffer->out_len + num_out))) 349a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod return; 350e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 351a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 35236b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod mask = buffer->info[buffer->i].mask; 35336b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod cluster = buffer->info[buffer->i].cluster; 354c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod if (component == 0xFFFF) 35536b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod component = buffer->info[buffer->i].component; 356f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod if (lig_id == 0xFFFF) 35736b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod lig_id = buffer->info[buffer->i].lig_id; 3589f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 359c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod for (i = 0; i < num_out; i++) 3609f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod { 36129427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod hb_internal_glyph_info_t *info = &buffer->out_info[buffer->out_len + i]; 36225e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->codepoint = glyph_data[i]; 363468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod info->mask = mask; 364c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->cluster = cluster; 365c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->component = component; 366f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod info->lig_id = lig_id; 367f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; 3689f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod } 3699f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 37036b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i += num_in; 37129427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len += num_out; 3729f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 3739f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 37425e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbodvoid 37525e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod_hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer, 37625e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod unsigned int num_in, 37725e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod unsigned int num_out, 37825e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod const uint16_t *glyph_data_be, 37925e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod unsigned short component, 38025e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod unsigned short lig_id) 38125e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod{ 38225e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod unsigned int i; 38325e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod unsigned int mask; 38425e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod unsigned int cluster; 38525e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 3869d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info || 38736b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_len + num_out > buffer->i + num_in) 38825e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod { 3893567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure_separate (buffer, buffer->out_len + num_out))) 390a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod return; 39125e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod } 39225e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 39336b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod mask = buffer->info[buffer->i].mask; 39436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod cluster = buffer->info[buffer->i].cluster; 39525e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod if (component == 0xFFFF) 39636b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod component = buffer->info[buffer->i].component; 39725e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod if (lig_id == 0xFFFF) 39836b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod lig_id = buffer->info[buffer->i].lig_id; 39925e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 40025e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod for (i = 0; i < num_out; i++) 40125e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod { 40229427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod hb_internal_glyph_info_t *info = &buffer->out_info[buffer->out_len + i]; 40325e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->codepoint = hb_be_uint16 (glyph_data_be[i]); 40425e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->mask = mask; 40525e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->cluster = cluster; 40625e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->component = component; 40725e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->lig_id = lig_id; 40825e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; 40925e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod } 41025e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 41136b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i += num_in; 41229427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len += num_out; 41325e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod} 41488a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod 415081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 4163015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod_hb_buffer_add_output_glyph (hb_buffer_t *buffer, 4173015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod hb_codepoint_t glyph_index, 4183015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned short component, 419f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod unsigned short lig_id) 4209f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 421f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod hb_internal_glyph_info_t *info; 422c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 4239d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 424e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 4253567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return; 42636b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 427e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 42836b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod else if (buffer->out_len != buffer->i) 42936b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 4309f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 43129427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod info = &buffer->out_info[buffer->out_len]; 432f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod info->codepoint = glyph_index; 433c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod if (component != 0xFFFF) 434c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->component = component; 435f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod if (lig_id != 0xFFFF) 436f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod info->lig_id = lig_id; 437f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; 438c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 43936b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i++; 44029427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len++; 4419f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 4429f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 443081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 444c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_next_glyph (hb_buffer_t *buffer) 44515c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod{ 446314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (buffer->have_output) 447e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod { 4489d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 449314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod { 4503567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return; 45136b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 452314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod } 45336b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod else if (buffer->out_len != buffer->i) 45436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 455e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod 45629427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len++; 457e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 458a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 45936b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i++; 460a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 461a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 4621ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbodvoid 46357ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod_hb_buffer_reset_masks (hb_buffer_t *buffer, 46457ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod hb_mask_t mask) 4651ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod{ 4661ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4671ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 468961f9baa7bc3556f1e4e7135859cebe1351f73a4Behdad Esfahbod buffer->info[i].mask = mask; 4691ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod} 4701ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 4711ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbodvoid 47257ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod_hb_buffer_add_masks (hb_buffer_t *buffer, 473bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod hb_mask_t mask) 474bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod{ 475bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod unsigned int count = buffer->len; 476bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 477bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod buffer->info[i].mask |= mask; 478bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod} 479bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod 480bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbodvoid 481bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod_hb_buffer_set_masks (hb_buffer_t *buffer, 48281c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t value, 48381c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t mask, 48481c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod unsigned int cluster_start, 48581c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod unsigned int cluster_end) 4861ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod{ 48781c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t not_mask = ~mask; 4885c1c8c9c50ddbe66ea595afb245a208b7775b27cBehdad Esfahbod value &= mask; 48981c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod 4903506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod if (!mask) 4913506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod return; 4923506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod 4931ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod if (cluster_start == 0 && cluster_end == (unsigned int)-1) { 4941ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4951ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 49681c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value; 4971ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod return; 4981ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod } 4991ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 50034db6f031d7ac009f554386ef990bad44886b9eeBehdad Esfahbod /* XXX can't bsearch since .cluster may not be sorted. */ 5011ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod /* Binary search to find the start position and go from there. */ 5021ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int min = 0, max = buffer->len; 5031ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod while (min < max) 5041ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod { 5051ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int mid = min + ((max - min) / 2); 5061ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod if (buffer->info[mid].cluster < cluster_start) 5071ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod min = mid + 1; 5081ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod else 5091ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod max = mid; 5101ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod } 5111ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 5121ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = min; i < count && buffer->info[i].cluster < cluster_end; i++) 51381c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value; 5141ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod} 5151ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 51611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 5173567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod/* Public API again */ 5183567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 51911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 5203d14528b8b2e7da425a9df7057fc9fb326d8298cBehdad Esfahbodhb_buffer_get_length (hb_buffer_t *buffer) 52111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 5226960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod return buffer->len; 52311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 52411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 52511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 52611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_info_t * 52711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_get_glyph_infos (hb_buffer_t *buffer) 52811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 5297e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod return (hb_glyph_info_t *) buffer->info; 53011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 53111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 53211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 53311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_position_t * 53411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_get_glyph_positions (hb_buffer_t *buffer) 53511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 536314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (!buffer->have_positions) 53711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod hb_buffer_clear_positions (buffer); 53811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 5391b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod return (hb_glyph_position_t *) buffer->pos; 54011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 541fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 542fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 543ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodstatic void 544ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodreverse_range (hb_buffer_t *buffer, 545ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int start, 546ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int end) 547fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod{ 548fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod unsigned int i, j; 549fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 550ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 551fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod hb_internal_glyph_info_t t; 552fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5537e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod t = buffer->info[i]; 5547e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod buffer->info[i] = buffer->info[j]; 5557e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod buffer->info[j] = t; 556fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 557fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5581b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod if (buffer->pos) { 559ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = 0, j = end - 1; i < j; i++, j--) { 560fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod hb_internal_glyph_position_t t; 561fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5621b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod t = buffer->pos[i]; 5631b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos[i] = buffer->pos[j]; 5641b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos[j] = t; 565fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 566fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 567fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod} 568299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 569ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 570ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse (hb_buffer_t *buffer) 571ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 5726960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod if (unlikely (!buffer->len)) 573ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod return; 574ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5756960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod reverse_range (buffer, 0, buffer->len); 576ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 577ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 578ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 579ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse_clusters (hb_buffer_t *buffer) 580ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 581ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int i, start, count, last_cluster; 582ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5836960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod if (unlikely (!buffer->len)) 584ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod return; 585ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 586ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod hb_buffer_reverse (buffer); 587ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5886960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod count = buffer->len; 589ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod start = 0; 5907e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod last_cluster = buffer->info[0].cluster; 591ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = 1; i < count; i++) { 5927e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod if (last_cluster != buffer->info[i].cluster) { 593ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod reverse_range (buffer, start, i); 594ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod start = i; 5957e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod last_cluster = buffer->info[i].cluster; 596ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod } 597ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod } 598ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod reverse_range (buffer, start, i); 599ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 600ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 601299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 602299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define ADD_UTF(T) \ 603299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod HB_STMT_START { \ 604299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *next = (const T *) text + item_offset; \ 605299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *end = next + item_length; \ 606299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod while (next < end) { \ 607299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t u; \ 608299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *old_next = next; \ 609299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod next = UTF_NEXT (next, end, u); \ 610009aad567863c05ee2ec4a3ee76fe0ee79c767bbBehdad Esfahbod hb_buffer_add_glyph (buffer, u, 1, old_next - (const T *) text); \ 611299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } \ 612299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } HB_STMT_END 613299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 614299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 615299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF8_COMPUTE(Char, Mask, Len) \ 616299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod if (Char < 128) { Len = 1; Mask = 0x7f; } \ 617299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \ 618299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \ 619299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \ 620299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else Len = 0; 621299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 622299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint8_t * 623299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf8_next (const uint8_t *text, 624299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint8_t *end, 625299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 626299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 627299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint8_t c = *text; 628299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int mask, len; 629299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 6302163afbf35044f59dbf449254e65b8c9feb6cdebBehdad Esfahbod /* TODO check for overlong sequences? also: optimize? */ 6312163afbf35044f59dbf449254e65b8c9feb6cdebBehdad Esfahbod 632299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod UTF8_COMPUTE (c, mask, len); 63364d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (!len || (unsigned int) (end - text) < len)) { 634299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 635299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 636299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else { 637299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t result; 638299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int i; 639299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result = c & mask; 640299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod for (i = 1; i < len; i++) 641299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 64264d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely ((text[i] & 0xc0) != 0x80)) 643299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 644299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 645299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 646299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 647299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result <<= 6; 648299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result |= (text[i] & 0x3f); 649299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 650299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = result; 651299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + len; 652299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 653299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 654299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 655299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 656299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf8 (hb_buffer_t *buffer, 657299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const char *text, 65833d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 659299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 660299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 661299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 662299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf8_next (S, E, &(U)) 663299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint8_t); 664299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 665299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 666299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 667299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint16_t * 668299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf16_next (const uint16_t *text, 669299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *end, 670299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 671299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 672299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t c = *text++; 673299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 67464d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (c >= 0xd800 && c < 0xdc00)) { 675299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* high surrogate */ 676299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t l; 67764d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (text < end && ((l = *text), unlikely (l >= 0xdc00 && l < 0xe000))) { 678299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* low surrogate */ 679299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000); 680299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod text++; 681299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 682299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 683299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 684299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = c; 685299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 686299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text; 687299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 688299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 689299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 690299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf16 (hb_buffer_t *buffer, 691299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *text, 69233d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 693299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 694299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 695299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 696299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U)) 697299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint16_t); 698299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 699299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 700299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 701299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 702299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf32 (hb_buffer_t *buffer, 703299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint32_t *text, 70433d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 705299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 706299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 707299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 708299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1) 709299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint32_t); 710299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 711299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 712acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 713acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 714acdba3f90b232fc12fcb200dca2584481b339118Behdad EsfahbodHB_END_DECLS 715