hb-buffer.cc revision f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cab
1a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod/* 2a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Copyright (C) 1998-2004 David Turner and Werner Lemberg 3a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Copyright (C) 2004,2007 Red Hat, Inc. 49f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod * 5a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library. 69f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod * 7a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Permission is hereby granted, without written agreement and without 8a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 9a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * software and its documentation for any purpose, provided that the 10a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 11a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * all copies of this software. 12a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 13a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DAMAGE. 18a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 19a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * 25a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Red Hat Author(s): Owen Taylor, Behdad Esfahbod 269f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod */ 279f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 285c0adce1ccc739415c4b26ff13ffd2d77ea4bc6cBehdad Esfahbod#include "hb-buffer-private.h" 299f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3088a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod#include <string.h> 3188a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod 32a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod/* Here is how the buffer works internally: 33a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 34a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * There are two string pointers: in_string and out_string. They 35a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * always have same allocated size, but different length and positions. 36a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 37a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * As an optimization, both in_string and out_string may point to the 38a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * same piece of memory, which is owned by in_string. This remains the 39e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * case as long as out_length doesn't exceed in_length at any time. 40e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * In that case, swap() is no-op and the glyph operations operate mostly 41e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * in-place. 42a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 43e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * As soon as out_string gets longer than in_string, out_string is moved over 44e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * to an alternate buffer (alt_string), and its current contents (out_length 45e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * entries) are copied to the alt buffer. This should all remain transparent 46e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * to the user. swap() then switches in_string and alt_string. alt_string is 47e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * not allocated until its needed, but after that it's grown with in_string 48e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod * unconditionally. 49a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */ 50a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 51c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod/* XXX err handling */ 52c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 536b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Internal API */ 546b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 5588a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbodstatic void 56c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbodhb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size) 57c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{ 58c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod hb_buffer_ensure (buffer, size); 59e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod if (buffer->out_string == buffer->in_string) 60e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 61e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod if (!buffer->alt_string) 62e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->alt_string = malloc (buffer->allocated * sizeof (buffer->alt_string[0])); 63e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod 64e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->out_string = buffer->alt_string; 65e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod memcpy (buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0])); 66e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 67a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 68a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 696b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */ 706b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 71b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t * 72f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodhb_buffer_new (unsigned int allocation_size) 739f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 74b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_t *buffer; 75b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod 76b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod buffer = malloc (sizeof (hb_buffer_t)); 77b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod if (HB_UNLIKELY (!buffer)) 78b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod return NULL; 799f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 807a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->allocated = 0; 817a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->in_string = NULL; 827a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->alt_string = NULL; 837a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->positions = NULL; 849f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 85b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_clear (buffer); 867a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 87f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod if (allocation_size) 88f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod hb_buffer_ensure(buffer, allocation_size); 89f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 90b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod return buffer; 91a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 929f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 937a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 94c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbodhb_buffer_free (hb_buffer_t *buffer) 957a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 96b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer->in_string); 97b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer->alt_string); 98b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer->positions); 99b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer); 1007a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 1017a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 1027a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 103c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbodhb_buffer_clear (hb_buffer_t *buffer) 1047a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 1057a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->in_length = 0; 1067a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->out_length = 0; 1077a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->in_pos = 0; 1087a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->out_pos = 0; 1097a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->out_string = buffer->in_string; 110c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->max_lig_id = 0; 1117a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 1127a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 113b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodvoid 114f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodhb_buffer_ensure (hb_buffer_t *buffer, unsigned int size) 115f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{ 116f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod unsigned int new_allocated = buffer->allocated; 117f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 118f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod if (size > new_allocated) 119f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod { 120f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod while (size > new_allocated) 121f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod new_allocated += (new_allocated >> 1) + 8; 122f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 123f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod if (buffer->positions) 124f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->positions = realloc (buffer->positions, new_allocated * sizeof (buffer->positions[0])); 125f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 126f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod if (buffer->out_string != buffer->in_string) 127f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod { 128f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->in_string = realloc (buffer->in_string, new_allocated * sizeof (buffer->in_string[0])); 129f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->alt_string = realloc (buffer->alt_string, new_allocated * sizeof (buffer->alt_string[0])); 130f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->out_string = buffer->alt_string; 131f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod } 132f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod else 133f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod { 134f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->in_string = realloc (buffer->in_string, new_allocated * sizeof (buffer->in_string[0])); 135f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->out_string = buffer->in_string; 136f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 137f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod if (buffer->alt_string) 138f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod { 139f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod free (buffer->alt_string); 140f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->alt_string = NULL; 141f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod } 142f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod } 143f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 144f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod buffer->allocated = new_allocated; 145f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod } 146f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 147f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 148f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid 1493015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbodhb_buffer_add_glyph (hb_buffer_t *buffer, 1503015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod hb_codepoint_t glyph_index, 1513015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int properties, 1523015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int cluster) 1536b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{ 154c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod hb_glyph_info_t *glyph; 1555c0adce1ccc739415c4b26ff13ffd2d77ea4bc6cBehdad Esfahbod 156b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_ensure (buffer, buffer->in_length + 1); 1576b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 1586b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph = &buffer->in_string[buffer->in_length]; 1596b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->gindex = glyph_index; 1606b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->properties = properties; 1616b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->cluster = cluster; 1626b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->component = 0; 1636b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod glyph->ligID = 0; 164c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod glyph->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; 1656b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 166b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod buffer->in_length++; 1676b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod} 1686b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 1696b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* HarfBuzz-Internal API */ 1706b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 1716b347138b597c41af24453f630336ba2fc033dc5Behdad EsfahbodHB_INTERNAL void 172c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_clear_output (hb_buffer_t *buffer) 1737a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 1747a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->out_length = 0; 1757a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->out_pos = 0; 1767a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod buffer->out_string = buffer->in_string; 1777a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 1787a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 179c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad EsfahbodHB_INTERNAL void 180c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_clear_positions (hb_buffer_t *buffer) 18106003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod{ 18215c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod _hb_buffer_clear_output (buffer); 18315c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod 184c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod if (HB_UNLIKELY (!buffer->positions)) 185c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod { 186c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->positions = calloc (buffer->allocated, sizeof (buffer->positions[0])); 187c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod return; 188c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod } 18906003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod 19006003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length); 19106003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod} 19206003908ccf2473366816935dd1b144cde587be9Behdad Esfahbod 1936b347138b597c41af24453f630336ba2fc033dc5Behdad EsfahbodHB_INTERNAL void 194c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_swap (hb_buffer_t *buffer) 1959f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 196c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod unsigned int tmp; 1979f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 198e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod if (buffer->out_string != buffer->in_string) 199e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 200e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod hb_glyph_info_t *tmp_string; 201e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod tmp_string = buffer->in_string; 202e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->in_string = buffer->out_string; 203e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->out_string = tmp_string; 204e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->alt_string = buffer->out_string; 205e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 2069f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 207c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod tmp = buffer->in_length; 2089f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod buffer->in_length = buffer->out_length; 209c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->out_length = tmp; 2109f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 211c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod tmp = buffer->in_pos; 212a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod buffer->in_pos = buffer->out_pos; 213c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->out_pos = tmp; 2149f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 2159f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 2169f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod/* The following function copies `num_out' elements from `glyph_data' 2179f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod to `buffer->out_string', advancing the in array pointer in the structure 2189f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod by `num_in' elements, and the out array pointer by `num_out' elements. 2199f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod Finally, it sets the `length' field of `out' equal to 2209f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod `pos' of the `out' structure. 2219f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 2229f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod If `component' is 0xFFFF, the component value from buffer->in_pos 2239f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod will copied `num_out' times, otherwise `component' itself will 2249f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod be used to fill the `component' fields. 2259f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 2269f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod If `ligID' is 0xFFFF, the ligID value from buffer->in_pos 2279f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod will copied `num_out' times, otherwise `ligID' itself will 2289f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod be used to fill the `ligID' fields. 2299f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 2309f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod The properties for all replacement glyphs are taken 2319f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod from the glyph at position `buffer->in_pos'. 2329f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 2339f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod The cluster value for the glyph at position buffer->in_pos is used 2349f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod for all replacement glyphs */ 235c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad EsfahbodHB_INTERNAL void 2363015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod_hb_buffer_add_output_glyphs (hb_buffer_t *buffer, 2373015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int num_in, 2383015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int num_out, 23988a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod const uint16_t *glyph_data_be, 2403015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned short component, 2413015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned short ligID) 2429f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 2433015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int i; 2443015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int properties; 2453015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned int cluster; 2469f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 247e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod if (buffer->out_string == buffer->in_string && 248e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->out_pos + num_out > buffer->in_pos + num_in) 249e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 250e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod hb_buffer_ensure_separate (buffer, buffer->out_pos + num_out); 251e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 252a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 2539f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod properties = buffer->in_string[buffer->in_pos].properties; 2549f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod cluster = buffer->in_string[buffer->in_pos].cluster; 255c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod if (component == 0xFFFF) 2569f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod component = buffer->in_string[buffer->in_pos].component; 257c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod if (ligID == 0xFFFF) 2589f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod ligID = buffer->in_string[buffer->in_pos].ligID; 2599f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 260c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod for (i = 0; i < num_out; i++) 2619f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod { 262c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod hb_glyph_info_t *info = &buffer->out_string[buffer->out_pos + i]; 263c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->gindex = hb_be_uint16_t (glyph_data_be[i]); 264c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->properties = properties; 265c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->cluster = cluster; 266c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->component = component; 267c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->ligID = ligID; 268c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; 2699f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod } 2709f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 2719f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod buffer->in_pos += num_in; 2729f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod buffer->out_pos += num_out; 2739f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod buffer->out_length = buffer->out_pos; 2749f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 2759f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 27688a5f5a49b6809d88560791f9cf6b8f78f22a4adBehdad Esfahbod 277c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad EsfahbodHB_INTERNAL void 2783015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod_hb_buffer_add_output_glyph (hb_buffer_t *buffer, 2793015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod hb_codepoint_t glyph_index, 2803015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned short component, 2813015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod unsigned short ligID) 2829f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 283c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod hb_glyph_info_t *info; 284c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 285e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod if (buffer->out_string != buffer->in_string) 286e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 287e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod hb_buffer_ensure (buffer, buffer->out_pos + 1); 288e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos]; 289e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 290e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod else if (buffer->out_pos != buffer->in_pos) 291e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos]; 2929f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 293c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info = &buffer->out_string[buffer->out_pos]; 294c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->gindex = glyph_index; 295c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod if (component != 0xFFFF) 296c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->component = component; 297c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod if (ligID != 0xFFFF) 298c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->ligID = ligID; 299c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN; 300c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 301c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->in_pos++; 302c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->out_pos++; 303c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod buffer->out_length = buffer->out_pos; 3049f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 3059f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 306c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad EsfahbodHB_INTERNAL void 307c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_next_glyph (hb_buffer_t *buffer) 30815c3e75b39797a153b6bc0598f87b27c4a487228Behdad Esfahbod{ 309e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod if (buffer->out_string != buffer->in_string) 310e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 311e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod hb_buffer_ensure (buffer, buffer->out_pos + 1); 312e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos]; 313e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 314e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod else if (buffer->out_pos != buffer->in_pos) 315e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos]; 316a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 317a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod buffer->in_pos++; 318a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod buffer->out_pos++; 3199f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod buffer->out_length = buffer->out_pos; 320a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 321a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 322c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad EsfahbodHB_INTERNAL void 3233015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod_hb_buffer_replace_glyph (hb_buffer_t *buffer, 3243015c4175179a1816aad2a4950da9a3b8baf2578Behdad Esfahbod hb_codepoint_t glyph_index) 325a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod{ 326e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod _hb_buffer_add_output_glyph (buffer, glyph_index, 0xFFFF, 0xFFFF); 3279f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 3289f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 3293015c4175179a1816aad2a4950da9a3b8baf2578Behdad EsfahbodHB_INTERNAL unsigned short 330c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod_hb_buffer_allocate_lig_id (hb_buffer_t *buffer) 3319f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 332c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod return ++buffer->max_lig_id; 3339f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod} 334