hb-buffer.cc revision a9ad3d3460ba863a8d8f3766ccbeab288c3c6822
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 37a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#ifndef HB_DEBUG_BUFFER 38a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#define HB_DEBUG_BUFFER (HB_DEBUG+0) 39a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#endif 40a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 41a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 423a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbodstatic hb_buffer_t _hb_buffer_nil = { 43fca368c4682624346a0aaee690e1ad6ed4c0b337Behdad Esfahbod HB_OBJECT_HEADER_STATIC, 445ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 45d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod &_hb_unicode_funcs_default, 46c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod { 47c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod HB_DIRECTION_INVALID, 48c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod HB_SCRIPT_INVALID, 49c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod NULL, 50c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2Behdad Esfahbod }, 51e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 52e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod TRUE, /* in_error */ 53e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod TRUE, /* have_output */ 54e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod TRUE /* have_positions */ 5511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}; 5611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 57a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod/* Here is how the buffer works internally: 58a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 59910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * There are two info pointers: info and out_info. They always have 60910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * the same allocated size, but different lengths. 61a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 629d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As an optimization, both info and out_info may point to the 637e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod * same piece of memory, which is owned by info. This remains the 64cc1a8a938b4c13e76b58825a9e1951c4134e634aBehdad Esfahbod * case as long as out_len doesn't exceed i at any time. 65468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * In that case, swap_buffers() is no-op and the glyph operations operate 66910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * mostly in-place. 67a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 689d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As soon as out_info gets longer than info, out_info is moved over 69910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * to an alternate buffer (which we reuse the pos buffer for!), and its 70910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * current contents (out_len entries) are copied to the new place. 71468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * This should all remain transparent to the user. swap_buffers() then 72910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * switches info and out_info. 73a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */ 74a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 75c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 76468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 77468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod/* Internal API */ 78468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 79468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool 80468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::enlarge (unsigned int size) 813567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 82468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (in_error)) 833567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return FALSE; 843567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 85468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int new_allocated = allocated; 86e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_position_t *new_pos = NULL; 87e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_info_t *new_info = NULL; 88468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod bool separate_out = out_info != info; 893567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 90468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0])))) 91e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 923567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 933567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod while (size > new_allocated) 9465e0063eae2f3adb25315b8bd7b0e7757aa960f3Behdad Esfahbod new_allocated += (new_allocated >> 1) + 32; 953567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 96468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0])); 97468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0])))) 98e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 99e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 100468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0])); 101468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0])); 1023567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 103e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahboddone: 1043567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!new_pos || !new_info)) 105468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod in_error = TRUE; 1063567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1073567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_pos)) 108468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos = new_pos; 1093567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1103567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_info)) 111468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info = new_info; 112468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 113468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = separate_out ? (hb_glyph_info_t *) pos : info; 114468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (likely (!in_error)) 115468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod allocated = new_allocated; 116468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 117468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return likely (!in_error); 118468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 119468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 120468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool 121468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::make_room_for (unsigned int num_in, 122468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int num_out) 123468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 124468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!ensure (out_len + num_out))) return FALSE; 125468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 126468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info == info && 127468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len + num_out > idx + num_in) 128468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 129468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod assert (have_output); 130468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 131468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = (hb_glyph_info_t *) pos; 132468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memcpy (out_info, info, out_len * sizeof (out_info[0])); 133468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 134468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 135468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return TRUE; 136468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 137468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 138468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 139468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod/* HarfBuzz-Internal API */ 140468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 141468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 142468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reset (void) 143468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 144468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 145468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 146468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 147468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_unicode_funcs_destroy (unicode); 1483a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod unicode = _hb_buffer_nil.unicode; 149468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 1503a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod props = _hb_buffer_nil.props; 151468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 152468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod in_error = FALSE; 153468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_output = FALSE; 154468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_positions = FALSE; 1553567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 156468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx = 0; 157468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len = 0; 158468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = 0; 1593567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 160468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod serial = 0; 161f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod memset (allocated_var_bytes, 0, sizeof allocated_var_bytes); 162f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod memset (allocated_var_owner, 0, sizeof allocated_var_owner); 163468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 164468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = info; 1653567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1663567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 167468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 168468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::add (hb_codepoint_t codepoint, 169468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t mask, 170468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster) 1713567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 172468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *glyph; 173468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 174468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!ensure (len + 1))) return; 175468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 176468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph = &info[len]; 177468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 178468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memset (glyph, 0, sizeof (*glyph)); 179468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->codepoint = codepoint; 180468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->mask = mask; 181468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->cluster = cluster; 182468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 183468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len++; 1843567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1856b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 186468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 187468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_output (void) 188c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{ 189468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 190468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 191468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 192468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_output = TRUE; 193468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_positions = FALSE; 194a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 195468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = 0; 196468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = info; 197468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 198468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 199468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 200468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_positions (void) 201468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 202468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 203468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 204468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 205468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_output = FALSE; 206468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_positions = TRUE; 207468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 208468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memset (pos, 0, sizeof (pos[0]) * len); 209468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 210468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 211468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 212468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::swap_buffers (void) 213468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 214468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (in_error)) return; 215468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 216468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod assert (have_output); 217468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 218468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info != info) 219e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 220468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *tmp_string; 221468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod tmp_string = info; 222468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info = out_info; 223468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = tmp_string; 224468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos = (hb_glyph_position_t *) out_info; 225468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 226468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 227468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int tmp; 228468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod tmp = len; 229468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len = out_len; 230468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = tmp; 231468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 232468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx = 0; 233468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 234e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod 235468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 236468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::replace_glyphs_be16 (unsigned int num_in, 237468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int num_out, 238468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod const uint16_t *glyph_data_be) 239468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 240468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!make_room_for (num_in, num_out)) return; 241468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 242468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t orig_info = info[idx]; 243468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 1; i < num_in; i++) 244468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 245468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *inf = &info[idx + i]; 246468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod orig_info.cluster = MIN (orig_info.cluster, inf->cluster); 247e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 248a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 249468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *pinfo = &out_info[out_len]; 250468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < num_out; i++) 251468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 252468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod *pinfo = orig_info; 253468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pinfo->codepoint = hb_be_uint16 (glyph_data_be[i]); 254468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pinfo++; 255468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 256468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 257468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx += num_in; 258468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len += num_out; 259468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 260468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 261468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 262468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::output_glyph (hb_codepoint_t glyph_index) 263468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 264468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!make_room_for (0, 1)) return; 265468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 266468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 267468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len].codepoint = glyph_index; 268468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 269468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 270468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 271468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 272468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 273468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::copy_glyph (void) 274468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 275468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!make_room_for (0, 1)) return; 276468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 277468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 278468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 279468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 280468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 281468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 282468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 283468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::replace_glyph (hb_codepoint_t glyph_index) 284468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 285468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 286468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len].codepoint = glyph_index; 287468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 288468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx++; 289468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 290468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 291468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 292468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 293468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::next_glyph (void) 294468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 295468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (have_output) 296468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 297468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info != info) 298468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 299468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!ensure (out_len + 1))) return; 300468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 301468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 302468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod else if (out_len != idx) 303468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 304468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 305468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 306468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 307468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 308468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx++; 309468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 310468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 311468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 312468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::set_masks (hb_mask_t value, 313468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t mask, 314468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster_start, 315468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster_end) 316468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 317468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t not_mask = ~mask; 318468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod value &= mask; 319468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 320468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!mask) 321468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 322468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 323468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (cluster_start == 0 && cluster_end == (unsigned int)-1) { 324468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int count = len; 325468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 326468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i].mask = (info[i].mask & not_mask) | value; 327468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 328468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 329468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 330468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int count = len; 331468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 332468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) 333468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i].mask = (info[i].mask & not_mask) | value; 334468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 335468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 336468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 337468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_range (unsigned int start, 338468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int end) 339468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 340468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int i, j; 341468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 342468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (start == end - 1) 343468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 344468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 345468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 346468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t t; 347468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 348468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod t = info[i]; 349468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i] = info[j]; 350468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[j] = t; 351468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 352468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 353468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (pos) { 354468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 355468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_position_t t; 356468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 357468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod t = pos[i]; 358468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos[i] = pos[j]; 359468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos[j] = t; 360468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 361468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 362468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 363468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 364468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 365468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse (void) 366468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 367468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!len)) 368468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 369468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 370468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (0, len); 371468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 372468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 373468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 374468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_clusters (void) 375468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 376468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int i, start, count, last_cluster; 377468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 378468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!len)) 379468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 380468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 381468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse (); 382468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 383468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod count = len; 384468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod start = 0; 385468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod last_cluster = info[0].cluster; 386468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = 1; i < count; i++) { 387468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (last_cluster != info[i].cluster) { 388468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (start, i); 389468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod start = i; 390468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod last_cluster = info[i].cluster; 391468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 392468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 393468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (start, i); 394a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 395a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 396a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodstatic inline void 397a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahboddump_var_allocation (const hb_buffer_t *buffer) 398a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{ 399a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod char buf[80]; 400a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod for (unsigned int i = 0; i < 8; i++) 401a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod buf[i] = '0' + buffer->allocated_var_bytes[i]; 402a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod buf[8] = '\0'; 403a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod DEBUG_MSG (BUFFER, buffer, 404a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod "Current var allocation: %s", 405a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod buf); 406a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod} 4073567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 408f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner) 409f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{ 410f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (byte_i < 8 && byte_i + count < 8); 411a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 412a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod if (DEBUG (BUFFER)) 413a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod dump_var_allocation (this); 414a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod DEBUG_MSG (BUFFER, this, 415a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod "Allocating var bytes %d..%d for %s", 416a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod byte_i, byte_i + count - 1, owner); 417a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 418f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod for (unsigned int i = byte_i; i < byte_i + count; i++) { 419f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (!allocated_var_bytes[i]); 420f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_bytes[i]++; 421f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_owner[i] = owner; 422f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod } 423f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod} 424f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 425f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner) 426f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{ 427a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod DEBUG_MSG (BUFFER, this, 428a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod "Deallocating var bytes %d..%d for %s", 429a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod byte_i, byte_i + count - 1, owner); 430a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 431f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (byte_i < 8 && byte_i + count < 8); 432f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod for (unsigned int i = byte_i; i < byte_i + count; i++) { 433f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (allocated_var_bytes[i] && allocated_var_owner[i] == owner); 434f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_bytes[i]--; 435f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod } 436a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 437a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod if (DEBUG (BUFFER)) 438a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod dump_var_allocation (this); 439f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod} 440f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 441a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodvoid hb_buffer_t::deallocate_var_all (void) 442a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{ 443a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes)); 444a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod memset (allocated_var_owner, 0, sizeof (allocated_var_owner)); 445a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod} 446f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 4476b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */ 4486b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 449b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t * 45011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_create (unsigned int pre_alloc_size) 4519f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 452b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_t *buffer; 453b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod 45447e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!(buffer = hb_object_create<hb_buffer_t> ())) 4553a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod return &_hb_buffer_nil; 4569f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 457468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reset (); 4585ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 459468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (pre_alloc_size && !buffer->ensure (pre_alloc_size)) { 460e87867cb88280e3f3a38d829e359cb686168b2cbBehdad Esfahbod hb_buffer_destroy (buffer); 4613a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod return &_hb_buffer_nil; 462e87867cb88280e3f3a38d829e359cb686168b2cbBehdad Esfahbod } 463e87867cb88280e3f3a38d829e359cb686168b2cbBehdad Esfahbod 46411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return buffer; 46511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 4667a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 46711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_t * 46880a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_get_empty (void) 46980a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod{ 4703a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod return &_hb_buffer_nil; 47180a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod} 47280a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod 47380a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_t * 47411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_reference (hb_buffer_t *buffer) 47511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 47647e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod return hb_object_reference (buffer); 47711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 478f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 4797a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 48011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_destroy (hb_buffer_t *buffer) 4817a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 48247e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!hb_object_destroy (buffer)) return; 48311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 4845ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 4855ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 4867e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod free (buffer->info); 4871b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod free (buffer->pos); 48811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 489b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer); 4907a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 4917a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 4925fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t 4935fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_set_user_data (hb_buffer_t *buffer, 4945fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key, 4955fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod void * data, 4965fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_destroy_func_t destroy) 4975fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 4985fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod return hb_object_set_user_data (buffer, key, data, destroy); 4995fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 5005fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 5015fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid * 5025fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_get_user_data (hb_buffer_t *buffer, 5035fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key) 5045fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 5055fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod return hb_object_get_user_data (buffer, key); 5065fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 5075fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 5085ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5095ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 5105ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 5115ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_t *unicode) 5125ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 513e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 514e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 515e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 5160465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod if (!unicode) 5173a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod unicode = _hb_buffer_nil.unicode; 5180465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod 5195ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_reference (unicode); 5205ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 5215ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod buffer->unicode = unicode; 5225ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 5235ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5245ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_unicode_funcs_t * 5255ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_unicode_funcs (hb_buffer_t *buffer) 5265ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 5275ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod return buffer->unicode; 5285ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 5295ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5305ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 5315ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_direction (hb_buffer_t *buffer, 5325ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_direction_t direction) 5335ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5345ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 535e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 536e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 537e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 5384e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.direction = direction; 5395ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 5405ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5415ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_direction_t 5425ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_direction (hb_buffer_t *buffer) 5435ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 5444e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.direction; 5455ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 5465ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 547ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 548ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_script (hb_buffer_t *buffer, 549ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_script_t script) 550ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 551e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 552e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 553e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 5544e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.script = script; 555ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 556ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 557ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_script_t 558ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_script (hb_buffer_t *buffer) 559ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 5604e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.script; 561ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 562ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 563ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 564ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_language (hb_buffer_t *buffer, 565ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_language_t language) 566ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 567e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 568e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 569e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 5704e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.language = language; 571ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 572ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 573ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_language_t 574ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_language (hb_buffer_t *buffer) 575ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 5764e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.language; 577ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 578ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 5795ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5807a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 581c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_reset (hb_buffer_t *buffer) 582c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 583468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reset (); 5847a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 5857a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 586a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbodhb_bool_t 58702a534b23f2d1e7475109563b9f61221ed020e8bRyan Lortiehb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) 588f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{ 589468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return buffer->ensure (size); 590f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 591f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 592aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_bool_t 593aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_buffer_allocation_successful (hb_buffer_t *buffer) 594aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod{ 595aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod return !buffer->in_error; 596aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod} 597aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod 598f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid 599f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbodhb_buffer_add (hb_buffer_t *buffer, 600f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_codepoint_t codepoint, 601f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_mask_t mask, 602f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod unsigned int cluster) 6036b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{ 604468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->add (codepoint, mask, cluster); 6059111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod} 6069111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod 607c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_bool_t 608c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_set_length (hb_buffer_t *buffer, 609c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod unsigned int length) 610c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 611468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!buffer->ensure (length)) 612c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return FALSE; 613c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 614c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod /* Wipe the new space */ 615c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (length > buffer->len) { 616c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); 617c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (buffer->have_positions) 618c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); 619c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod } 620c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 621c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod buffer->len = length; 622c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return TRUE; 623c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod} 624c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 62511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 6263d14528b8b2e7da425a9df7057fc9fb326d8298cBehdad Esfahbodhb_buffer_get_length (hb_buffer_t *buffer) 62711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 6286960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod return buffer->len; 62911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 63011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 63111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 63211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_info_t * 63370566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_infos (hb_buffer_t *buffer, 63470566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 63511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 63670566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 63770566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 63870566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 6397e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod return (hb_glyph_info_t *) buffer->info; 64011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 64111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 64211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 64311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_position_t * 64470566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_positions (hb_buffer_t *buffer, 64570566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 64611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 647314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (!buffer->have_positions) 648468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->clear_positions (); 64911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 65070566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 65170566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 65270566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 6531b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod return (hb_glyph_position_t *) buffer->pos; 65411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 655fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 656ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 657ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse (hb_buffer_t *buffer) 658ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 659468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reverse (); 660ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 661ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 662ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 663ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse_clusters (hb_buffer_t *buffer) 664ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 665468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reverse_clusters (); 666ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 667ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 668299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define ADD_UTF(T) \ 669299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod HB_STMT_START { \ 670299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *next = (const T *) text + item_offset; \ 671299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *end = next + item_length; \ 672299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod while (next < end) { \ 673299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t u; \ 674299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *old_next = next; \ 675299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod next = UTF_NEXT (next, end, u); \ 676f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_buffer_add (buffer, u, 1, old_next - (const T *) text); \ 677299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } \ 678299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } HB_STMT_END 679299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 680299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 681299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF8_COMPUTE(Char, Mask, Len) \ 682299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod if (Char < 128) { Len = 1; Mask = 0x7f; } \ 683299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \ 684299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \ 685299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \ 686299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else Len = 0; 687299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 688299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint8_t * 689299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf8_next (const uint8_t *text, 690299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint8_t *end, 691299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 692299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 693299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint8_t c = *text; 694299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int mask, len; 695299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 696243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod /* TODO check for overlong sequences? */ 6972163afbf35044f59dbf449254e65b8c9feb6cdebBehdad Esfahbod 698299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod UTF8_COMPUTE (c, mask, len); 69964d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (!len || (unsigned int) (end - text) < len)) { 700299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 701299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 702299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else { 703299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t result; 704299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int i; 705299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result = c & mask; 706299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod for (i = 1; i < len; i++) 707299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 70864d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely ((text[i] & 0xc0) != 0x80)) 709299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 710299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 711299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 712299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 713299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result <<= 6; 714299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result |= (text[i] & 0x3f); 715299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 716299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = result; 717299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + len; 718299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 719299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 720299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 721299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 722299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf8 (hb_buffer_t *buffer, 723299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const char *text, 72433d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 725299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 726299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 727299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 728299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf8_next (S, E, &(U)) 729299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint8_t); 730299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 731299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 732299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 733299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint16_t * 734299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf16_next (const uint16_t *text, 735299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *end, 736299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 737299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 738299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t c = *text++; 739299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 74064d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (c >= 0xd800 && c < 0xdc00)) { 741299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* high surrogate */ 742299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t l; 74369ea23cb5d47dd1cfd3129f68375021ef79bf63bBehdad Esfahbod if (text < end && ((l = *text), likely (l >= 0xdc00 && l < 0xe000))) { 744299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* low surrogate */ 745299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000); 746299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod text++; 747299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 748299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 749299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 750299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = c; 751299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 752299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text; 753299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 754299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 755299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 756299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf16 (hb_buffer_t *buffer, 757299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *text, 75833d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 759299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 760299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 761299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 762299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U)) 763299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint16_t); 764299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 765299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 766299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 767299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 768299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf32 (hb_buffer_t *buffer, 769299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint32_t *text, 77033d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 771299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 772299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 773299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 774299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1) 775299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint32_t); 776299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 777299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 778acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 779acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 780acdba3f90b232fc12fcb200dca2584481b339118Behdad EsfahbodHB_END_DECLS 781