hb-buffer.cc revision 243673d601588a6f704ceafbff5dd5cdf66c47b7
1a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod/* 22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 1998-2004 David Turner and Werner Lemberg 32409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2004,2007,2009,2010 Red Hat, Inc. 42409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 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 = { 38fca368c4682624346a0aaee690e1ad6ed4c0b337Behdad Esfahbod HB_OBJECT_HEADER_STATIC, 395ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 40d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod &_hb_unicode_funcs_default, 41c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod { 42c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod HB_DIRECTION_INVALID, 43c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod HB_SCRIPT_INVALID, 44c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod NULL, 45c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod }, 46e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 47e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod TRUE, /* in_error */ 48e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod TRUE, /* have_output */ 49e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod TRUE /* have_positions */ 5011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}; 5111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 52a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod/* Here is how the buffer works internally: 53a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 54910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * There are two info pointers: info and out_info. They always have 55910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * the same allocated size, but different lengths. 56a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 579d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As an optimization, both info and out_info may point to the 587e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod * same piece of memory, which is owned by info. This remains the 59cc1a8a938b4c13e76b58825a9e1951c4134e634aBehdad Esfahbod * case as long as out_len doesn't exceed i at any time. 60910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * In that case, swap() is no-op and the glyph operations operate 61910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * mostly in-place. 62a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 639d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As soon as out_info gets longer than info, out_info is moved over 64910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * to an alternate buffer (which we reuse the pos buffer for!), and its 65910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * current contents (out_len entries) are copied to the new place. 66910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * This should all remain transparent to the user. swap() then 67910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * switches info and out_info. 68a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */ 69a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 70c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 713567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodstatic hb_bool_t 723567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_enlarge (hb_buffer_t *buffer, unsigned int size) 733567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 743567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (buffer->in_error)) 753567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return FALSE; 763567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 773567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod unsigned int new_allocated = buffer->allocated; 78e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_position_t *new_pos = NULL; 79e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_info_t *new_info = NULL; 80e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod bool separate_out = buffer->out_info != buffer->info; 813567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 82080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (buffer->info[0])))) 83e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 843567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 853567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod while (size > new_allocated) 8665e0063eae2f3adb25315b8bd7b0e7757aa960f3Behdad Esfahbod new_allocated += (new_allocated >> 1) + 32; 873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 88b5dd44e24669cd35affcd92788d39ff56cac94dbBehdad Esfahbod ASSERT_STATIC (sizeof (buffer->info[0]) == sizeof (buffer->pos[0])); 89080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (buffer->info[0])))) 90e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 91e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 92e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod new_pos = (hb_glyph_position_t *) realloc (buffer->pos, new_allocated * sizeof (buffer->pos[0])); 93e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod new_info = (hb_glyph_info_t *) realloc (buffer->info, new_allocated * sizeof (buffer->info[0])); 943567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 95e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahboddone: 963567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!new_pos || !new_info)) 973567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->in_error = TRUE; 983567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 993567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_pos)) 1003567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->pos = new_pos; 1013567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1023567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_info)) 1033567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->info = new_info; 1043567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 10588474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod buffer->out_info = separate_out ? (hb_glyph_info_t *) buffer->pos : buffer->info; 1063567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (!buffer->in_error)) 1073567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->allocated = new_allocated; 1083567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1093567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return likely (!buffer->in_error); 1103567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1113567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1123567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodstatic inline hb_bool_t 1133567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_ensure (hb_buffer_t *buffer, unsigned int size) 1143567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 1153567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return likely (size <= buffer->allocated) ? TRUE : _hb_buffer_enlarge (buffer, size); 1163567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1176b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 118acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbodstatic inline hb_bool_t 1193567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size) 120c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{ 121e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (!size || !_hb_buffer_ensure (buffer, size))) return FALSE; 122a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 1239d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info == buffer->info) 124e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 125e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod assert (buffer->have_output); 126e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod 12788474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod buffer->out_info = (hb_glyph_info_t *) buffer->pos; 12829427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod memcpy (buffer->out_info, buffer->info, buffer->out_len * sizeof (buffer->out_info[0])); 129e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 130a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 131a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod return TRUE; 132a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 133a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 1343567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1356b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */ 1366b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 137b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t * 13811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_create (unsigned int pre_alloc_size) 1399f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 140b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_t *buffer; 141b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod 14247e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!(buffer = hb_object_create<hb_buffer_t> ())) 14311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return &_hb_buffer_nil; 1449f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 14511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod if (pre_alloc_size) 1463567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod _hb_buffer_ensure (buffer, pre_alloc_size); 1479f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 148c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod hb_buffer_reset (buffer); 1495ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 15011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return buffer; 15111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 1527a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 15311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_t * 15411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_reference (hb_buffer_t *buffer) 15511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 15647e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod return hb_object_reference (buffer); 15711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 158f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 1597a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 16011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_destroy (hb_buffer_t *buffer) 1617a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 16247e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!hb_object_destroy (buffer)) return; 16311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 1645ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 1655ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1667e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod free (buffer->info); 1671b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod free (buffer->pos); 16811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 169b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer); 1707a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 1717a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 1725fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t 1735fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_set_user_data (hb_buffer_t *buffer, 1745fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key, 1755fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod void * data, 1765fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_destroy_func_t destroy) 1775fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 1785fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod return hb_object_set_user_data (buffer, key, data, destroy); 1795fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 1805fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 1815fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid * 1825fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_get_user_data (hb_buffer_t *buffer, 1835fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key) 1845fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 1855fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod return hb_object_get_user_data (buffer, key); 1865fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 1875fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 1885ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 1895ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 1905ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 1915ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_t *unicode) 1925ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 193e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 194e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 195e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 1960465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod if (!unicode) 197e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod unicode = _hb_buffer_nil.unicode; 1980465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod 1995ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_reference (unicode); 2005ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 2015ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod buffer->unicode = unicode; 2025ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 2035ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2045ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_unicode_funcs_t * 2055ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_unicode_funcs (hb_buffer_t *buffer) 2065ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 2075ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod return buffer->unicode; 2085ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 2095ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2105ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 2115ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_direction (hb_buffer_t *buffer, 2125ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_direction_t direction) 2135ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2145ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 215e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 216e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 217e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 2184e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.direction = direction; 2195ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 2205ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2215ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_direction_t 2225ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_direction (hb_buffer_t *buffer) 2235ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 2244e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.direction; 2255ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 2265ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 227ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 228ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_script (hb_buffer_t *buffer, 229ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_script_t script) 230ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 231e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 232e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 233e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 2344e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.script = script; 235ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 236ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 237ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_script_t 238ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_script (hb_buffer_t *buffer) 239ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2404e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.script; 241ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 242ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 243ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 244ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_language (hb_buffer_t *buffer, 245ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_language_t language) 246ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 247e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 248e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 249e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 2504e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.language = language; 251ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 252ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 253ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_language_t 254ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_language (hb_buffer_t *buffer) 255ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 2564e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.language; 257ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 258ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 2595ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 2607a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 261c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_reset (hb_buffer_t *buffer) 262c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 263e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 264e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 265e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 266c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 267c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->unicode = _hb_buffer_nil.unicode; 268c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod 269c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->props = _hb_buffer_nil.props; 270c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod 271e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod buffer->in_error = FALSE; 272e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod buffer->have_output = FALSE; 273314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod buffer->have_positions = FALSE; 274c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod 275c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->i = 0; 2766960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod buffer->len = 0; 27729427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len = 0; 2782fc56edff6d64f190271454ccb1b5fd347d4f172Behdad Esfahbod 279c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->serial = 0; 2802fc56edff6d64f190271454ccb1b5fd347d4f172Behdad Esfahbod 281c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod buffer->out_info = buffer->info; 2827a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 2837a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 284a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbodhb_bool_t 28502a534b23f2d1e7475109563b9f61221ed020e8bRyan Lortiehb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) 286f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{ 2873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return _hb_buffer_ensure (buffer, size); 288f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 289f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 290aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_bool_t 291aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_buffer_allocation_successful (hb_buffer_t *buffer) 292aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod{ 293aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod return !buffer->in_error; 294aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod} 295aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod 296f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid 297f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbodhb_buffer_add (hb_buffer_t *buffer, 298f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_codepoint_t codepoint, 299f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_mask_t mask, 300f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod unsigned int cluster) 3016b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{ 30288474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *glyph; 3035c0adce1ccc739415c4b26ff13ffd2d77ea4bc6cBehdad Esfahbod 3043567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->len + 1))) return; 3056b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 3066960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod glyph = &buffer->info[buffer->len]; 307f6a23a0b9171958f76c1d0473b09fc08d2b3a0d0Behdad Esfahbod 308f6a23a0b9171958f76c1d0473b09fc08d2b3a0d0Behdad Esfahbod memset (glyph, 0, sizeof (*glyph)); 309f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod glyph->codepoint = codepoint; 310468769b8f5332940278244e744ec2bd5a5dc5ee9Behdad Esfahbod glyph->mask = mask; 3116b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->cluster = cluster; 3126b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 3136960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod buffer->len++; 3146b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod} 3156b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 3163567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod/* HarfBuzz-Internal API */ 3173567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 3183567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbodvoid 3193567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod_hb_buffer_clear_output (hb_buffer_t *buffer) 3203567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 321e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 322e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 323e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 3243567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->have_output = TRUE; 3253567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->have_positions = FALSE; 3268f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 3273567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->out_len = 0; 3283567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod buffer->out_info = buffer->info; 3293567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 3303567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 331081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 3328f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod_hb_buffer_clear_positions (hb_buffer_t *buffer) 3338f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod{ 334e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 335e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 336e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 3378f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod buffer->have_output = FALSE; 3388f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod buffer->have_positions = TRUE; 3398f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 3408f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod memset (buffer->pos, 0, sizeof (buffer->pos[0]) * buffer->len); 3418f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod} 3428f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod 3438f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbodvoid 344c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_swap (hb_buffer_t *buffer) 3459f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 346e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (buffer->in_error)) return; 3479f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 348e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod assert (buffer->have_output); 349e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod 3509d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 351e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 35288474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *tmp_string; 3537e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod tmp_string = buffer->info; 3549d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod buffer->info = buffer->out_info; 3559d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod buffer->out_info = tmp_string; 35688474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod buffer->pos = (hb_glyph_position_t *) buffer->out_info; 357e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 3589f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 359e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod unsigned int tmp; 3606960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod tmp = buffer->len; 36129427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->len = buffer->out_len; 36229427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len = tmp; 3639f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 36436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i = 0; 3659f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 3669f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 367081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 368dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod_hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer, 369dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod unsigned int num_in, 370dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod unsigned int num_out, 371dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod const uint16_t *glyph_data_be) 37225e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod{ 3739d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info || 37436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_len + num_out > buffer->i + num_in) 37525e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod { 3763567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure_separate (buffer, buffer->out_len + num_out))) 377a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod return; 37825e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod } 37925e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 380fe263272a2b26204bc39829a94d90ab537517f3fBehdad Esfahbod hb_glyph_info_t orig_info = buffer->info[buffer->i]; 38125e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 382fe263272a2b26204bc39829a94d90ab537517f3fBehdad Esfahbod for (unsigned int i = 0; i < num_out; i++) 38325e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod { 38488474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i]; 385fe263272a2b26204bc39829a94d90ab537517f3fBehdad Esfahbod *info = orig_info; 38625e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod info->codepoint = hb_be_uint16 (glyph_data_be[i]); 38725e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod } 38825e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod 38936b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i += num_in; 39029427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len += num_out; 39125e7ef704633447f109b148620336c42d6fb310eBehdad Esfahbod} 39288a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod 393081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 394dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod_hb_buffer_replace_glyph (hb_buffer_t *buffer, 395dd2ffd282c059194fd87fb1664e2e0cdb56a87a0Behdad Esfahbod hb_codepoint_t glyph_index) 3969f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 39788474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t *info; 398c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 3999d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 400e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 4013567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return; 40236b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 403e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 40436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod else if (buffer->out_len != buffer->i) 40536b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 4069f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 40729427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod info = &buffer->out_info[buffer->out_len]; 408f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod info->codepoint = glyph_index; 409c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 41036b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i++; 41129427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len++; 4129f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 4139f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 414081819ea8b98c0a4b4dffe8d4aca3512f9798719Behdad Esfahbodvoid 415c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_next_glyph (hb_buffer_t *buffer) 41615c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod{ 417314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (buffer->have_output) 418e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod { 4199d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod if (buffer->out_info != buffer->info) 420314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod { 4213567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return; 42236b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 423314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod } 42436b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod else if (buffer->out_len != buffer->i) 42536b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->out_info[buffer->out_len] = buffer->info[buffer->i]; 426e4679d9fae43f3219c476c5b9e411d1f5d0d5baeBehdad Esfahbod 42729427c5c51ac70aca53ed523fa5ddb3de4355fb0Behdad Esfahbod buffer->out_len++; 428e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 429a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 43036b73c80df91e96492357c6da945e081e9046a93Behdad Esfahbod buffer->i++; 431a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 432a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 4331ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbodvoid 43457ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod_hb_buffer_reset_masks (hb_buffer_t *buffer, 43557ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod hb_mask_t mask) 4361ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod{ 4371ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4381ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 439961f9baa7bc3556f1e4e7135859cebe1351f73a4Behdad Esfahbod buffer->info[i].mask = mask; 4401ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod} 4411ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 4421ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbodvoid 44357ac0ecb7843533b2e6e6d6c8a12b2a44437cc1cBehdad Esfahbod_hb_buffer_add_masks (hb_buffer_t *buffer, 444bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod hb_mask_t mask) 445bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod{ 446bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod unsigned int count = buffer->len; 447bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 448bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod buffer->info[i].mask |= mask; 449bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod} 450bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod 451bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbodvoid 452bd7378b2ef9793de4e7f57b920f29f48ac9d0c25Behdad Esfahbod_hb_buffer_set_masks (hb_buffer_t *buffer, 45381c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t value, 45481c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t mask, 45581c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod unsigned int cluster_start, 45681c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod unsigned int cluster_end) 4571ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod{ 45881c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod hb_mask_t not_mask = ~mask; 4595c1c8c9c50ddbe66ea595afb245a208b7775b27cBehdad Esfahbod value &= mask; 46081c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod 4613506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod if (!mask) 4623506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod return; 4633506b2e78db27e7835bd2c09c053a9807c9cac40Behdad Esfahbod 4641ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod if (cluster_start == 0 && cluster_end == (unsigned int)-1) { 4651ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4661ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 46781c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value; 4681ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod return; 4691ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod } 4701ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 47134db6f031d7ac009f554386ef990bad44886b9eeBehdad Esfahbod /* XXX can't bsearch since .cluster may not be sorted. */ 4721ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod /* Binary search to find the start position and go from there. */ 4731ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int min = 0, max = buffer->len; 4741ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod while (min < max) 4751ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod { 4761ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int mid = min + ((max - min) / 2); 4771ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod if (buffer->info[mid].cluster < cluster_start) 4781ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod min = mid + 1; 4791ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod else 4801ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod max = mid; 4811ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod } 4821ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod unsigned int count = buffer->len; 4831ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod for (unsigned int i = min; i < count && buffer->info[i].cluster < cluster_end; i++) 48481c5e8724b740c6e42ed3a45e0574c7c5f3ad8e6Behdad Esfahbod buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value; 4851ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod} 4861ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64Behdad Esfahbod 48711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 4883567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod/* Public API again */ 4893567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 490c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_bool_t 491c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_set_length (hb_buffer_t *buffer, 492c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod unsigned int length) 493c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 49402a534b23f2d1e7475109563b9f61221ed020e8bRyan Lortie if (!_hb_buffer_ensure (buffer, length)) 495c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return FALSE; 496c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 497c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod /* Wipe the new space */ 498c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (length > buffer->len) { 499c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); 500c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (buffer->have_positions) 501c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); 502c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod } 503c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 504c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod buffer->len = length; 505c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return TRUE; 506c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod} 507c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 50811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 5093d14528b8b2e7da425a9df7057fc9fb326d8298cBehdad Esfahbodhb_buffer_get_length (hb_buffer_t *buffer) 51011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 5116960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod return buffer->len; 51211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 51311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 51411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 51511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_info_t * 51670566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_infos (hb_buffer_t *buffer, 51770566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 51811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 51970566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 52070566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 52170566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 5227e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod return (hb_glyph_info_t *) buffer->info; 52311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 52411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 52511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 52611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_position_t * 52770566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_positions (hb_buffer_t *buffer, 52870566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 52911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 530314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (!buffer->have_positions) 5318f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod _hb_buffer_clear_positions (buffer); 53211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 53370566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 53470566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 53570566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 5361b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod return (hb_glyph_position_t *) buffer->pos; 53711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 538fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 539fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 540ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodstatic void 541ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodreverse_range (hb_buffer_t *buffer, 542ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int start, 543ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int end) 544fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod{ 545fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod unsigned int i, j; 546fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 547ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 54888474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_info_t t; 549fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5507e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod t = buffer->info[i]; 5517e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod buffer->info[i] = buffer->info[j]; 5527e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod buffer->info[j] = t; 553fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 554fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5551b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod if (buffer->pos) { 556ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = 0, j = end - 1; i < j; i++, j--) { 55788474c6fdaf35c56368694a5b164f4988a004d49Behdad Esfahbod hb_glyph_position_t t; 558fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 5591b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod t = buffer->pos[i]; 5601b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos[i] = buffer->pos[j]; 5611b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod buffer->pos[j] = t; 562fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 563fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod } 564fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod} 565299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 566ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 567ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse (hb_buffer_t *buffer) 568ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 5696960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod if (unlikely (!buffer->len)) 570ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod return; 571ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5726960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod reverse_range (buffer, 0, buffer->len); 573ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 574ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 575ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 576ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse_clusters (hb_buffer_t *buffer) 577ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 578ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod unsigned int i, start, count, last_cluster; 579ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5806960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod if (unlikely (!buffer->len)) 581ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod return; 582ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 583ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod hb_buffer_reverse (buffer); 584ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 5856960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod count = buffer->len; 586ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod start = 0; 5877e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod last_cluster = buffer->info[0].cluster; 588ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod for (i = 1; i < count; i++) { 5897e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod if (last_cluster != buffer->info[i].cluster) { 590ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod reverse_range (buffer, start, i); 591ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod start = i; 5927e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod last_cluster = buffer->info[i].cluster; 593ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod } 594ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod } 595ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod reverse_range (buffer, start, i); 596ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 597ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 598299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 599299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define ADD_UTF(T) \ 600299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod HB_STMT_START { \ 601299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *next = (const T *) text + item_offset; \ 602299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *end = next + item_length; \ 603299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod while (next < end) { \ 604299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t u; \ 605299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *old_next = next; \ 606299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod next = UTF_NEXT (next, end, u); \ 607f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_buffer_add (buffer, u, 1, old_next - (const T *) text); \ 608299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } \ 609299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } HB_STMT_END 610299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 611299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 612299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF8_COMPUTE(Char, Mask, Len) \ 613299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod if (Char < 128) { Len = 1; Mask = 0x7f; } \ 614299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \ 615299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \ 616299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \ 617299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else Len = 0; 618299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 619299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint8_t * 620299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf8_next (const uint8_t *text, 621299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint8_t *end, 622299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 623299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 624299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint8_t c = *text; 625299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int mask, len; 626299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 627243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod /* TODO check for overlong sequences? */ 6282163afbf35044f59dbf449254e65b8c9feb6cdebBehdad Esfahbod 629299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod UTF8_COMPUTE (c, mask, len); 63064d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (!len || (unsigned int) (end - text) < len)) { 631299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 632299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 633299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else { 634299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t result; 635299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int i; 636299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result = c & mask; 637299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod for (i = 1; i < len; i++) 638299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 63964d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely ((text[i] & 0xc0) != 0x80)) 640299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 641299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 642299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 643299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 644299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result <<= 6; 645299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result |= (text[i] & 0x3f); 646299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 647299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = result; 648299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + len; 649299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 650299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 651299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 652299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 653299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf8 (hb_buffer_t *buffer, 654299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const char *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) hb_utf8_next (S, E, &(U)) 660299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint8_t); 661299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 662299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 663299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 664299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint16_t * 665299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf16_next (const uint16_t *text, 666299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *end, 667299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 668299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 669299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t c = *text++; 670299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 67164d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (c >= 0xd800 && c < 0xdc00)) { 672299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* high surrogate */ 673299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t l; 67469ea23cb5d47dd1cfd3129f68375021ef79bf63bBehdad Esfahbod if (text < end && ((l = *text), likely (l >= 0xdc00 && l < 0xe000))) { 675299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* low surrogate */ 676299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000); 677299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod text++; 678299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 679299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 680299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 681299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = c; 682299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 683299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text; 684299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 685299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 686299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 687299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf16 (hb_buffer_t *buffer, 688299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *text, 68933d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 690299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 691299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 692299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 693299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U)) 694299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint16_t); 695299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 696299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 697299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 698299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 699299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf32 (hb_buffer_t *buffer, 700299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint32_t *text, 70133d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 702299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 703299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 704299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 705299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1) 706299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint32_t); 707299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 708299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 709acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 710acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 711acdba3f90b232fc12fcb200dca2584481b339118Behdad EsfahbodHB_END_DECLS 712