hb-buffer.cc revision c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2
1a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod/* 2a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Copyright (C) 1998-2004 David Turner and Werner Lemberg 322da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod * Copyright (C) 2004,2007,2009,2010 Red Hat, Inc. 4c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod * Copyright (C) 2011 Google, Inc. 59f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod * 68f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 79f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod * 8a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Permission is hereby granted, without written agreement and without 9a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 10a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * software and its documentation for any purpose, provided that the 11a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 12a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * all copies of this software. 13a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 14a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DAMAGE. 19a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 20a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 26a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Red Hat Author(s): Owen Taylor, Behdad Esfahbod 27c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod * Google Author(s): Behdad Esfahbod 289f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod */ 299f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3022da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-buffer-private.hh" 319f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3288a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod#include <string.h> 3388a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod 34acdba3f90b232fc12fcb200dca2584481b339118Behdad EsfahbodHB_BEGIN_DECLS 35acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 36f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod 3711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodstatic hb_buffer_t _hb_buffer_nil = { 385ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod HB_REFERENCE_COUNT_INVALID, /* ref_count */ 395ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 40c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod &_hb_unicode_funcs_nil, /* unicode */ 41c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod { 42c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod HB_DIRECTION_INVALID, 43c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod HB_SCRIPT_INVALID, 44c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod NULL, 45c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod }, 4611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}; 4711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 48a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod/* Here is how the buffer works internally: 49a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 50910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * There are two info pointers: info and out_info. They always have 51910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * the same allocated size, but different lengths. 52a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 539d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As an optimization, both info and out_info may point to the 547e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod * same piece of memory, which is owned by info. This remains the 55cc1a8a938b4c13e76b58825a9e1951c4134e634aBehdad Esfahbod * case as long as out_len doesn't exceed i at any time. 56910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * In that case, swap() is no-op and the glyph operations operate 57910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * mostly in-place. 58a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 599d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As soon as out_info gets longer than info, out_info is moved over 60910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * to an alternate buffer (which we reuse the pos buffer for!), and its 61910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * current contents (out_len entries) are copied to the new place. 62910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * This should all remain transparent to the user. swap() then 63910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * switches info and out_info. 64a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */ 65a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 66c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 673567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodstatic hb_bool_t 683567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_enlarge (hb_buffer_t *buffer, unsigned int size) 693567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 703567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (buffer->in_error)) 713567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return FALSE; 723567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 733567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod unsigned int new_allocated = buffer->allocated; 7488474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_position_t *new_pos; 7588474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *new_info; 763567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod bool separate_out; 773567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 783567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod separate_out = buffer->out_info != buffer->info; 793567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 803567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod while (size > new_allocated) 813567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod new_allocated += (new_allocated >> 1) + 8; 823567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 83b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod ASSERT_STATIC (sizeof (buffer->info[0]) == sizeof (buffer->pos[0])); 84b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod bool overflows = new_allocated >= ((unsigned int) -1) / sizeof (buffer->info[0]); 85b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod 86b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod if (unlikely (overflows)) { 87b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod new_pos = NULL; 88b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod new_info = NULL; 89b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod } else { 90b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod new_pos = (hb_glyph_position_t *) realloc (buffer->pos, new_allocated * sizeof (buffer->pos[0])); 91b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod new_info = (hb_glyph_info_t *) realloc (buffer->info, new_allocated * sizeof (buffer->info[0])); 92b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod } 933567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 943567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!new_pos || !new_info)) 953567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->in_error = TRUE; 963567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 973567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_pos)) 983567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->pos = new_pos; 993567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1003567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_info)) 1013567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->info = new_info; 1023567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 10388474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod buffer->out_info = separate_out ? (hb_glyph_info_t *) buffer->pos : buffer->info; 1043567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (!buffer->in_error)) 1053567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->allocated = new_allocated; 1063567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1073567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return likely (!buffer->in_error); 1083567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1093567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1103567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodstatic inline hb_bool_t 1113567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_ensure (hb_buffer_t *buffer, unsigned int size) 1123567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 1133567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return likely (size <= buffer->allocated) ? TRUE : _hb_buffer_enlarge (buffer, size); 1143567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1156b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 116acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbodstatic inline hb_bool_t 1173567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size) 118c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{ 1193567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, size))) return FALSE; 120a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 1219d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info == buffer->info) 122e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 123e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod assert (buffer->have_output); 124e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod 12588474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod buffer->out_info = (hb_glyph_info_t *) buffer->pos; 12629427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod memcpy (buffer->out_info, buffer->info, buffer->out_len * sizeof (buffer->out_info[0])); 127e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 128a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 129a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod return TRUE; 130a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 131a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 1323567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1336b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */ 1346b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 135b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t * 13611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_create (unsigned int pre_alloc_size) 1379f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 138b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_t *buffer; 139b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod 1405fc22e647c8a2bf6d3cb59185e351ac625e7e322Behdad Esfahbod if (!HB_OBJECT_DO_CREATE (hb_buffer_t, buffer)) 14111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return &_hb_buffer_nil; 1429f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 14311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod if (pre_alloc_size) 1443567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod _hb_buffer_ensure (buffer, pre_alloc_size); 1459f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 146c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod hb_buffer_reset (buffer); 1475ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 14811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return buffer; 14911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 1507a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 15111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_t * 15211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_reference (hb_buffer_t *buffer) 15311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 15411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod HB_OBJECT_DO_REFERENCE (buffer); 15511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 156f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 15711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 15811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_get_reference_count (hb_buffer_t *buffer) 15911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 16011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod HB_OBJECT_DO_GET_REFERENCE_COUNT (buffer); 161a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 1629f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 1637a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 16411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_destroy (hb_buffer_t *buffer) 1657a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 16611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod HB_OBJECT_DO_DESTROY (buffer); 16711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 1685ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 1695ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1707e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod free (buffer->info); 1711b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod free (buffer->pos); 17211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 173b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer); 1747a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 1757a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 1765ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1775ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 1785ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 1795ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_t *unicode) 1805ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 1810465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod if (!unicode) 1820465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod unicode = &_hb_unicode_funcs_nil; 1830465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod 1845ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_reference (unicode); 1855ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 1865ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod buffer->unicode = unicode; 1875ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 1885ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1895ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_unicode_funcs_t * 1905ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_unicode_funcs (hb_buffer_t *buffer) 1915ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 1925ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod return buffer->unicode; 1935ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 1945ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1955ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 1965ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_direction (hb_buffer_t *buffer, 1975ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_direction_t direction) 1985ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1995ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 2004e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.direction = direction; 2015ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 2025ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2035ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_direction_t 2045ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_direction (hb_buffer_t *buffer) 2055ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 2064e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.direction; 2075ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 2085ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 209ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 210ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_script (hb_buffer_t *buffer, 211ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_script_t script) 212ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2134e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.script = script; 214ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 215ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 216ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_script_t 217ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_script (hb_buffer_t *buffer) 218ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2194e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.script; 220ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 221ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 222ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 223ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_language (hb_buffer_t *buffer, 224ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_language_t language) 225ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2264e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.language = language; 227ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 228ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 229ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_language_t 230ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_language (hb_buffer_t *buffer) 231ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2324e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.language; 233ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 234ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 2355ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2367a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 237c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_reset (hb_buffer_t *buffer) 238c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 239c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 240c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->unicode = _hb_buffer_nil.unicode; 241c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod 242c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->props = _hb_buffer_nil.props; 243c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod 244e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod buffer->have_output = FALSE; 245314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod buffer->have_positions = FALSE; 246a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod buffer->in_error = FALSE; 247c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod 248c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->i = 0; 2496960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod buffer->len = 0; 25029427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len = 0; 2512fc56edff6d64f190271454ccb1b5fd347d4f172Behdad Esfahbod 252c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->serial = 0; 2532fc56edff6d64f190271454ccb1b5fd347d4f172Behdad Esfahbod 254c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->out_info = buffer->info; 2557a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 2567a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 257a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbodhb_bool_t 258f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodhb_buffer_ensure (hb_buffer_t *buffer, unsigned int size) 259f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{ 2603567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return _hb_buffer_ensure (buffer, size); 261f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 262f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 263f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid 2643015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbodhb_buffer_add_glyph (hb_buffer_t *buffer, 265f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod hb_codepoint_t codepoint, 266468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod hb_mask_t mask, 2673015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int cluster) 2686b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{ 26988474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *glyph; 2705c0adce1ccc739415c4b26ff13ffd2d77ea4bc6cBehdad Esfahbod 2713567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->len + 1))) return; 2726b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 2736960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod glyph = &buffer->info[buffer->len]; 274f6a23a0b9171958f76c1d0473b09fc08d2b3a0d0Behdad Esfahbod 275f6a23a0b9171958f76c1d0473b09fc08d2b3a0d0Behdad Esfahbod memset (glyph, 0, sizeof (*glyph)); 276f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod glyph->codepoint = codepoint; 277468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod glyph->mask = mask; 2786b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->cluster = cluster; 2796b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 2806960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod buffer->len++; 2816b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod} 2826b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 2833567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod/* HarfBuzz-Internal API */ 2843567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 2853567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodvoid 2863567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_clear_output (hb_buffer_t *buffer) 2873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 2883567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->have_output = TRUE; 2893567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->have_positions = FALSE; 2908f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 2913567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->out_len = 0; 2923567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->out_info = buffer->info; 2933567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 2943567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 295081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 2968f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod_hb_buffer_clear_positions (hb_buffer_t *buffer) 2978f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod{ 2988f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod buffer->have_output = FALSE; 2998f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod buffer->have_positions = TRUE; 3008f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 3018f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod memset (buffer->pos, 0, sizeof (buffer->pos[0]) * buffer->len); 3028f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod} 3038f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 3048f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbodvoid 305c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_swap (hb_buffer_t *buffer) 3069f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 307c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod unsigned int tmp; 3089f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 309e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod assert (buffer->have_output); 310e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod 311a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod if (unlikely (buffer->in_error)) return; 312a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 3139d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 314e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 31588474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *tmp_string; 3167e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod tmp_string = buffer->info; 3179d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod buffer->info = buffer->out_info; 3189d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod buffer->out_info = tmp_string; 31988474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod buffer->pos = (hb_glyph_position_t *) buffer->out_info; 320e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 3219f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3226960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod tmp = buffer->len; 32329427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->len = buffer->out_len; 32429427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len = tmp; 3259f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 32636b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i = 0; 3279f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 3289f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 329081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 330dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod_hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer, 331dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod unsigned int num_in, 332dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod unsigned int num_out, 333dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod const uint16_t *glyph_data_be) 33425e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod{ 3359d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info || 33636b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_len + num_out > buffer->i + num_in) 33725e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod { 3383567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure_separate (buffer, buffer->out_len + num_out))) 339a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod return; 34025e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod } 34125e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 342fe263272a2b26204bc39829a94d90ab537517f3fBehdad Esfahbod hb_glyph_info_t orig_info = buffer->info[buffer->i]; 34325e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 344fe263272a2b26204bc39829a94d90ab537517f3fBehdad Esfahbod for (unsigned int i = 0; i < num_out; i++) 34525e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod { 34688474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i]; 347fe263272a2b26204bc39829a94d90ab537517f3fBehdad Esfahbod *info = orig_info; 34825e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->codepoint = hb_be_uint16 (glyph_data_be[i]); 34925e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod } 35025e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 35136b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i += num_in; 35229427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len += num_out; 35325e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod} 35488a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod 355081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 356dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod_hb_buffer_replace_glyph (hb_buffer_t *buffer, 357dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod hb_codepoint_t glyph_index) 3589f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 35988474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *info; 360c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 3619d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 362e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 3633567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return; 36436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 365e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 36636b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod else if (buffer->out_len != buffer->i) 36736b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 3689f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 36929427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod info = &buffer->out_info[buffer->out_len]; 370f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod info->codepoint = glyph_index; 371c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 37236b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i++; 37329427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len++; 3749f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 3759f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 376081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 377c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_next_glyph (hb_buffer_t *buffer) 37815c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod{ 379314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (buffer->have_output) 380e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod { 3819d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 382314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod { 3833567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return; 38436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 385314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod } 38636b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod else if (buffer->out_len != buffer->i) 38736b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 388e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod 38929427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len++; 390e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 391a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 39236b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i++; 393a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 394a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 3951ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbodvoid 39657ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod_hb_buffer_reset_masks (hb_buffer_t *buffer, 39757ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod hb_mask_t mask) 3981ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod{ 3991ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4001ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 401961f9baa7bc3556f1e4e7135859cebe1351f73a4Behdad Esfahbod buffer->info[i].mask = mask; 4021ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod} 4031ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 4041ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbodvoid 40557ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod_hb_buffer_add_masks (hb_buffer_t *buffer, 406bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod hb_mask_t mask) 407bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod{ 408bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod unsigned int count = buffer->len; 409bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 410bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod buffer->info[i].mask |= mask; 411bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod} 412bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod 413bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbodvoid 414bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod_hb_buffer_set_masks (hb_buffer_t *buffer, 41581c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t value, 41681c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t mask, 41781c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod unsigned int cluster_start, 41881c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod unsigned int cluster_end) 4191ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod{ 42081c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t not_mask = ~mask; 4215c1c8c9c50ddbe66ea595afb245a208b7775b27cBehdad Esfahbod value &= mask; 42281c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod 4233506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod if (!mask) 4243506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod return; 4253506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod 4261ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod if (cluster_start == 0 && cluster_end == (unsigned int)-1) { 4271ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4281ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 42981c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value; 4301ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod return; 4311ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod } 4321ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 43334db6f031d7ac009f554386ef990bad44886b9eeBehdad Esfahbod /* XXX can't bsearch since .cluster may not be sorted. */ 4341ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod /* Binary search to find the start position and go from there. */ 4351ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int min = 0, max = buffer->len; 4361ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod while (min < max) 4371ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod { 4381ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int mid = min + ((max - min) / 2); 4391ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod if (buffer->info[mid].cluster < cluster_start) 4401ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod min = mid + 1; 4411ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod else 4421ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod max = mid; 4431ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod } 4441ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4451ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = min; i < count && buffer->info[i].cluster < cluster_end; i++) 44681c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value; 4471ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod} 4481ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 44911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 4503567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod/* Public API again */ 4513567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 452c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_bool_t 453c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_set_length (hb_buffer_t *buffer, 454c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod unsigned int length) 455c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 456c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (!hb_buffer_ensure (buffer, length)) 457c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return FALSE; 458c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 459c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod /* Wipe the new space */ 460c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (length > buffer->len) { 461c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); 462c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (buffer->have_positions) 463c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); 464c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod } 465c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 466c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod buffer->len = length; 467c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return TRUE; 468c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod} 469c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 47011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 4713d14528b8b2e7da425a9df7057fc9fb326d8298cBehdad Esfahbodhb_buffer_get_length (hb_buffer_t *buffer) 47211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 4736960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod return buffer->len; 47411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 47511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 47611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 47711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_info_t * 47811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_get_glyph_infos (hb_buffer_t *buffer) 47911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 4807e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod return (hb_glyph_info_t *) buffer->info; 48111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 48211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 48311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 48411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_position_t * 48511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_get_glyph_positions (hb_buffer_t *buffer) 48611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 487314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (!buffer->have_positions) 4888f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod _hb_buffer_clear_positions (buffer); 48911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 4901b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod return (hb_glyph_position_t *) buffer->pos; 49111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 492fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 493fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 494ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodstatic void 495ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodreverse_range (hb_buffer_t *buffer, 496ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int start, 497ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int end) 498fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod{ 499fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod unsigned int i, j; 500fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 501ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 50288474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t t; 503fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5047e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod t = buffer->info[i]; 5057e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod buffer->info[i] = buffer->info[j]; 5067e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod buffer->info[j] = t; 507fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 508fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5091b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod if (buffer->pos) { 510ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = 0, j = end - 1; i < j; i++, j--) { 51188474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_position_t t; 512fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5131b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod t = buffer->pos[i]; 5141b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos[i] = buffer->pos[j]; 5151b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos[j] = t; 516fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 517fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 518fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod} 519299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 520ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 521ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse (hb_buffer_t *buffer) 522ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 5236960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod if (unlikely (!buffer->len)) 524ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod return; 525ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5266960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod reverse_range (buffer, 0, buffer->len); 527ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 528ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 529ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 530ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse_clusters (hb_buffer_t *buffer) 531ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 532ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int i, start, count, last_cluster; 533ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5346960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod if (unlikely (!buffer->len)) 535ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod return; 536ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 537ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod hb_buffer_reverse (buffer); 538ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5396960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod count = buffer->len; 540ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod start = 0; 5417e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod last_cluster = buffer->info[0].cluster; 542ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = 1; i < count; i++) { 5437e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod if (last_cluster != buffer->info[i].cluster) { 544ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod reverse_range (buffer, start, i); 545ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod start = i; 5467e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod last_cluster = buffer->info[i].cluster; 547ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod } 548ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod } 549ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod reverse_range (buffer, start, i); 550ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 551ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 552299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 553299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define ADD_UTF(T) \ 554299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod HB_STMT_START { \ 555299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *next = (const T *) text + item_offset; \ 556299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *end = next + item_length; \ 557299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod while (next < end) { \ 558299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t u; \ 559299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *old_next = next; \ 560299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod next = UTF_NEXT (next, end, u); \ 561009aad567863c05ee2ec4a3ee76fe0ee79c767bbBehdad Esfahbod hb_buffer_add_glyph (buffer, u, 1, old_next - (const T *) text); \ 562299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } \ 563299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } HB_STMT_END 564299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 565299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 566299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF8_COMPUTE(Char, Mask, Len) \ 567299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod if (Char < 128) { Len = 1; Mask = 0x7f; } \ 568299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \ 569299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \ 570299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \ 571299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else Len = 0; 572299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 573299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint8_t * 574299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf8_next (const uint8_t *text, 575299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint8_t *end, 576299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 577299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 578299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint8_t c = *text; 579299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int mask, len; 580299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 5812163afbf35044f59dbf449254e65b8c9feb6cdebBehdad Esfahbod /* TODO check for overlong sequences? also: optimize? */ 5822163afbf35044f59dbf449254e65b8c9feb6cdebBehdad Esfahbod 583299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod UTF8_COMPUTE (c, mask, len); 58464d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (!len || (unsigned int) (end - text) < len)) { 585299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 586299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 587299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else { 588299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t result; 589299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int i; 590299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result = c & mask; 591299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod for (i = 1; i < len; i++) 592299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 59364d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely ((text[i] & 0xc0) != 0x80)) 594299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 595299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 596299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 597299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 598299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result <<= 6; 599299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result |= (text[i] & 0x3f); 600299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 601299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = result; 602299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + len; 603299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 604299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 605299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 606299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 607299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf8 (hb_buffer_t *buffer, 608299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const char *text, 60933d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 610299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 611299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 612299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 613299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf8_next (S, E, &(U)) 614299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint8_t); 615299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 616299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 617299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 618299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint16_t * 619299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf16_next (const uint16_t *text, 620299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *end, 621299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 622299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 623299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t c = *text++; 624299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 62564d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (c >= 0xd800 && c < 0xdc00)) { 626299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* high surrogate */ 627299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t l; 62869ea23cb5d47dd1cfd3129f68375021ef79bf63bBehdad Esfahbod if (text < end && ((l = *text), likely (l >= 0xdc00 && l < 0xe000))) { 629299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* low surrogate */ 630299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000); 631299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod text++; 632299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 633299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 634299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 635299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = c; 636299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 637299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text; 638299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 639299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 640299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 641299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf16 (hb_buffer_t *buffer, 642299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *text, 64333d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 644299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 645299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 646299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 647299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U)) 648299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint16_t); 649299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 650299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 651299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 652299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 653299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf32 (hb_buffer_t *buffer, 654299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint32_t *text, 65533d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 656299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 657299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 658299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 659299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1) 660299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint32_t); 661299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 662299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 663acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 664acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 665acdba3f90b232fc12fcb200dca2584481b339118Behdad EsfahbodHB_END_DECLS 666