hb-buffer.cc revision 3a81b1db89beba91fb91791918b9fdd9f8fc9fa0
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 373a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad 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. 60468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * In that case, swap_buffers() 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. 66468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * This should all remain transparent to the user. swap_buffers() then 67910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * switches info and out_info. 68a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */ 69a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 70c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 71468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 72468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod/* Internal API */ 73468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 74468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool 75468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::enlarge (unsigned int size) 763567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 77468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (in_error)) 783567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod return FALSE; 793567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 80468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int new_allocated = allocated; 81e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_position_t *new_pos = NULL; 82e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_info_t *new_info = NULL; 83468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod bool separate_out = out_info != info; 843567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 85468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0])))) 86e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 883567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod while (size > new_allocated) 8965e0063eae2f3adb25315b8bd7b0e7757aa960f3Behdad Esfahbod new_allocated += (new_allocated >> 1) + 32; 903567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 91468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0])); 92468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0])))) 93e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 94e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 95468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0])); 96468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0])); 973567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 98e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahboddone: 993567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!new_pos || !new_info)) 100468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod in_error = TRUE; 1013567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1023567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_pos)) 103468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos = new_pos; 1043567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 1053567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_info)) 106468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info = new_info; 107468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 108468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = separate_out ? (hb_glyph_info_t *) pos : info; 109468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (likely (!in_error)) 110468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod allocated = new_allocated; 111468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 112468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return likely (!in_error); 113468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 114468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 115468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool 116468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::make_room_for (unsigned int num_in, 117468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int num_out) 118468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 119468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!ensure (out_len + num_out))) return FALSE; 120468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 121468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info == info && 122468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len + num_out > idx + num_in) 123468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 124468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod assert (have_output); 125468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 126468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = (hb_glyph_info_t *) pos; 127468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memcpy (out_info, info, out_len * sizeof (out_info[0])); 128468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 129468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 130468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return TRUE; 131468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 132468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 133468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 134468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod/* HarfBuzz-Internal API */ 135468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 136468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 137468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reset (void) 138468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 139468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 140468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 141468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 142468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_unicode_funcs_destroy (unicode); 1433a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod unicode = _hb_buffer_nil.unicode; 144468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 1453a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod props = _hb_buffer_nil.props; 146468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 147468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod in_error = FALSE; 148468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_output = FALSE; 149468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_positions = FALSE; 1503567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 151468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx = 0; 152468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len = 0; 153468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = 0; 1543567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 155468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod serial = 0; 156f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod memset (allocated_var_bytes, 0, sizeof allocated_var_bytes); 157f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod memset (allocated_var_owner, 0, sizeof allocated_var_owner); 158468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 159468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = info; 1603567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1613567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 162468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 163468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::add (hb_codepoint_t codepoint, 164468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t mask, 165468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster) 1663567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 167468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *glyph; 168468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 169468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!ensure (len + 1))) return; 170468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 171468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph = &info[len]; 172468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 173468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memset (glyph, 0, sizeof (*glyph)); 174468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->codepoint = codepoint; 175468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->mask = mask; 176468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->cluster = cluster; 177468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 178468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len++; 1793567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1806b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 181468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 182468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_output (void) 183c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{ 184468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 185468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 186468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 187468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_output = TRUE; 188468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_positions = FALSE; 189a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 190468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = 0; 191468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = info; 192468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 193468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 194468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 195468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_positions (void) 196468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 197468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 198468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 199468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 200468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_output = FALSE; 201468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod have_positions = TRUE; 202468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 203468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memset (pos, 0, sizeof (pos[0]) * len); 204468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 205468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 206468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 207468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::swap_buffers (void) 208468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 209468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (in_error)) return; 210468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 211468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod assert (have_output); 212468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 213468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info != info) 214e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 215468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *tmp_string; 216468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod tmp_string = info; 217468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info = out_info; 218468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = tmp_string; 219468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos = (hb_glyph_position_t *) out_info; 220468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 221468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 222468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int tmp; 223468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod tmp = len; 224468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len = out_len; 225468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = tmp; 226468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 227468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx = 0; 228468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 229e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod 230468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 231468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::replace_glyphs_be16 (unsigned int num_in, 232468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int num_out, 233468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod const uint16_t *glyph_data_be) 234468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 235468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!make_room_for (num_in, num_out)) return; 236468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 237468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t orig_info = info[idx]; 238468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 1; i < num_in; i++) 239468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 240468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *inf = &info[idx + i]; 241468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod orig_info.cluster = MIN (orig_info.cluster, inf->cluster); 242e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod } 243a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 244468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *pinfo = &out_info[out_len]; 245468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < num_out; i++) 246468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 247468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod *pinfo = orig_info; 248468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pinfo->codepoint = hb_be_uint16 (glyph_data_be[i]); 249468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pinfo++; 250468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 251468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 252468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx += num_in; 253468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len += num_out; 254468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 255468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 256468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 257468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::output_glyph (hb_codepoint_t glyph_index) 258468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 259468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!make_room_for (0, 1)) return; 260468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 261468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 262468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len].codepoint = glyph_index; 263468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 264468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 265468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 266468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 267468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 268468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::copy_glyph (void) 269468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 270468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!make_room_for (0, 1)) return; 271468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 272468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 273468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 274468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 275468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 276468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 277468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 278468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::replace_glyph (hb_codepoint_t glyph_index) 279468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 280468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 281468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len].codepoint = glyph_index; 282468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 283468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx++; 284468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 285468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 286468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 287468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 288468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::next_glyph (void) 289468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 290468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (have_output) 291468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 292468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info != info) 293468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 294468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!ensure (out_len + 1))) return; 295468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 296468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 297468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod else if (out_len != idx) 298468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 299468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 300468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 301468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 302468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 303468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx++; 304468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 305468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 306468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 307468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::set_masks (hb_mask_t value, 308468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t mask, 309468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster_start, 310468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster_end) 311468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 312468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t not_mask = ~mask; 313468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod value &= mask; 314468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 315468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!mask) 316468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 317468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 318468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (cluster_start == 0 && cluster_end == (unsigned int)-1) { 319468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int count = len; 320468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 321468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i].mask = (info[i].mask & not_mask) | value; 322468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 323468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 324468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 325468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int count = len; 326468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 327468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) 328468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i].mask = (info[i].mask & not_mask) | value; 329468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 330468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 331468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 332468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_range (unsigned int start, 333468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int end) 334468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 335468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int i, j; 336468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 337468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (start == end - 1) 338468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 339468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 340468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 341468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t t; 342468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 343468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod t = info[i]; 344468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i] = info[j]; 345468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[j] = t; 346468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 347468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 348468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (pos) { 349468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 350468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_position_t t; 351468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 352468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod t = pos[i]; 353468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos[i] = pos[j]; 354468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos[j] = t; 355468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 356468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 357468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 358468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 359468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 360468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse (void) 361468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 362468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!len)) 363468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 364468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 365468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (0, len); 366468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 367468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 368468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 369468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_clusters (void) 370468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 371468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int i, start, count, last_cluster; 372468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 373468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!len)) 374468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 375468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 376468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse (); 377468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 378468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod count = len; 379468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod start = 0; 380468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod last_cluster = info[0].cluster; 381468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = 1; i < count; i++) { 382468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (last_cluster != info[i].cluster) { 383468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (start, i); 384468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod start = i; 385468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod last_cluster = info[i].cluster; 386468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 387468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 388468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (start, i); 389a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 390a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 3913567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 392f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner) 393f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{ 394f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (byte_i < 8 && byte_i + count < 8); 395f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod for (unsigned int i = byte_i; i < byte_i + count; i++) { 396f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (!allocated_var_bytes[i]); 397f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_bytes[i]++; 398f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_owner[i] = owner; 399f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod } 400f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod} 401f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 402f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner) 403f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{ 404f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (byte_i < 8 && byte_i + count < 8); 405f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod for (unsigned int i = byte_i; i < byte_i + count; i++) { 406f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (allocated_var_bytes[i] && allocated_var_owner[i] == owner); 407f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_bytes[i]--; 408f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod } 409f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod} 410f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 411f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 4126b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */ 4136b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 414b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t * 41511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_create (unsigned int pre_alloc_size) 4169f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 417b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_t *buffer; 418b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod 41947e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!(buffer = hb_object_create<hb_buffer_t> ())) 4203a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod return &_hb_buffer_nil; 4219f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 422468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reset (); 4235ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 424468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (pre_alloc_size && !buffer->ensure (pre_alloc_size)) { 425e87867cb88280e3f3a38d829e359cb686168b2cbBehdad Esfahbod hb_buffer_destroy (buffer); 4263a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod return &_hb_buffer_nil; 427e87867cb88280e3f3a38d829e359cb686168b2cbBehdad Esfahbod } 428e87867cb88280e3f3a38d829e359cb686168b2cbBehdad Esfahbod 42911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return buffer; 43011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 4317a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 43211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_t * 43380a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_get_empty (void) 43480a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod{ 4353a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod return &_hb_buffer_nil; 43680a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod} 43780a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod 43880a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_t * 43911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_reference (hb_buffer_t *buffer) 44011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 44147e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod return hb_object_reference (buffer); 44211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 443f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 4447a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 44511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_destroy (hb_buffer_t *buffer) 4467a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 44747e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!hb_object_destroy (buffer)) return; 44811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 4495ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 4505ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 4517e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod free (buffer->info); 4521b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod free (buffer->pos); 45311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 454b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer); 4557a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 4567a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 4575fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t 4585fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_set_user_data (hb_buffer_t *buffer, 4595fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key, 4605fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod void * data, 4615fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_destroy_func_t destroy) 4625fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 4635fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod return hb_object_set_user_data (buffer, key, data, destroy); 4645fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 4655fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 4665fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid * 4675fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_get_user_data (hb_buffer_t *buffer, 4685fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key) 4695fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 4705fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod return hb_object_get_user_data (buffer, key); 4715fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 4725fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 4735ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 4745ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 4755ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 4765ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_t *unicode) 4775ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 478e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 479e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 480e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 4810465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod if (!unicode) 4823a81b1db89beba91fb91791918b9fdd9f8fc9fa0Behdad Esfahbod unicode = _hb_buffer_nil.unicode; 4830465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod 4845ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_reference (unicode); 4855ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 4865ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod buffer->unicode = unicode; 4875ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 4885ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 4895ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_unicode_funcs_t * 4905ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_unicode_funcs (hb_buffer_t *buffer) 4915ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 4925ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod return buffer->unicode; 4935ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 4945ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 4955ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 4965ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_direction (hb_buffer_t *buffer, 4975ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_direction_t direction) 4985ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 4995ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 500e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 501e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 502e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 5034e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.direction = direction; 5045ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 5055ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5065ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_direction_t 5075ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_direction (hb_buffer_t *buffer) 5085ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 5094e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.direction; 5105ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 5115ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 512ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 513ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_script (hb_buffer_t *buffer, 514ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_script_t script) 515ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 516e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 517e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 518e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 5194e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.script = script; 520ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 521ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 522ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_script_t 523ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_script (hb_buffer_t *buffer) 524ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 5254e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.script; 526ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 527ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 528ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 529ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_language (hb_buffer_t *buffer, 530ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_language_t language) 531ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 532e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 533e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 534e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 5354e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.language = language; 536ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 537ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 538ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_language_t 539ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_language (hb_buffer_t *buffer) 540ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 5414e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.language; 542ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 543ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 5445ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 5457a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 546c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_reset (hb_buffer_t *buffer) 547c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 548468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reset (); 5497a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 5507a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 551a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbodhb_bool_t 55202a534b23f2d1e7475109563b9f61221ed020e8bRyan Lortiehb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) 553f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{ 554468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return buffer->ensure (size); 555f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 556f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 557aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_bool_t 558aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_buffer_allocation_successful (hb_buffer_t *buffer) 559aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod{ 560aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod return !buffer->in_error; 561aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod} 562aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod 563f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid 564f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbodhb_buffer_add (hb_buffer_t *buffer, 565f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_codepoint_t codepoint, 566f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_mask_t mask, 567f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod unsigned int cluster) 5686b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{ 569468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->add (codepoint, mask, cluster); 5709111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod} 5719111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod 572c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_bool_t 573c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_set_length (hb_buffer_t *buffer, 574c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod unsigned int length) 575c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 576468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!buffer->ensure (length)) 577c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return FALSE; 578c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 579c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod /* Wipe the new space */ 580c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (length > buffer->len) { 581c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); 582c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (buffer->have_positions) 583c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); 584c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod } 585c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 586c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod buffer->len = length; 587c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod return TRUE; 588c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod} 589c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 59011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 5913d14528b8b2e7da425a9df7057fc9fb326d8298cBehdad Esfahbodhb_buffer_get_length (hb_buffer_t *buffer) 59211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 5936960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod return buffer->len; 59411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 59511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 59611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 59711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_info_t * 59870566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_infos (hb_buffer_t *buffer, 59970566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 60011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 60170566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 60270566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 60370566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 6047e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod return (hb_glyph_info_t *) buffer->info; 60511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 60611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 60711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 60811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_position_t * 60970566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_positions (hb_buffer_t *buffer, 61070566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 61111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 612314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (!buffer->have_positions) 613468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->clear_positions (); 61411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 61570566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 61670566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 61770566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 6181b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod return (hb_glyph_position_t *) buffer->pos; 61911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 620fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 621ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 622ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse (hb_buffer_t *buffer) 623ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 624468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reverse (); 625ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 626ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 627ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 628ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse_clusters (hb_buffer_t *buffer) 629ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 630468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reverse_clusters (); 631ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 632ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 633299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define ADD_UTF(T) \ 634299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod HB_STMT_START { \ 635299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *next = (const T *) text + item_offset; \ 636299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *end = next + item_length; \ 637299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod while (next < end) { \ 638299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t u; \ 639299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const T *old_next = next; \ 640299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod next = UTF_NEXT (next, end, u); \ 641f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_buffer_add (buffer, u, 1, old_next - (const T *) text); \ 642299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } \ 643299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } HB_STMT_END 644299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 645299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 646299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF8_COMPUTE(Char, Mask, Len) \ 647299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod if (Char < 128) { Len = 1; Mask = 0x7f; } \ 648299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \ 649299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \ 650299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \ 651299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod else Len = 0; 652299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 653299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint8_t * 654299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf8_next (const uint8_t *text, 655299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint8_t *end, 656299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 657299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 658299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint8_t c = *text; 659299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int mask, len; 660299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 661243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod /* TODO check for overlong sequences? */ 6622163afbf35044f59dbf449254e65b8c9feb6cdebBehdad Esfahbod 663299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod UTF8_COMPUTE (c, mask, len); 66464d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (!len || (unsigned int) (end - text) < len)) { 665299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 666299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 667299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else { 668299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t result; 669299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int i; 670299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result = c & mask; 671299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod for (i = 1; i < len; i++) 672299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 67364d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely ((text[i] & 0xc0) != 0x80)) 674299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod { 675299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 676299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + 1; 677299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 678299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result <<= 6; 679299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod result |= (text[i] & 0x3f); 680299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 681299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = result; 682299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text + len; 683299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } 684299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 685299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 686299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 687299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf8 (hb_buffer_t *buffer, 688299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const char *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_utf8_next (S, E, &(U)) 694299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint8_t); 695299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 696299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 697299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 698299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodstatic inline const uint16_t * 699299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_utf16_next (const uint16_t *text, 700299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *end, 701299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod hb_codepoint_t *unicode) 702299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 703299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t c = *text++; 704299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 70564d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (c >= 0xd800 && c < 0xdc00)) { 706299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* high surrogate */ 707299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod uint16_t l; 70869ea23cb5d47dd1cfd3129f68375021ef79bf63bBehdad Esfahbod if (text < end && ((l = *text), likely (l >= 0xdc00 && l < 0xe000))) { 709299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod /* low surrogate */ 710299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000); 711299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod text++; 712299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 713299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = -1; 714299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod } else 715299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod *unicode = c; 716299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 717299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod return text; 718299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 719299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 720299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 721299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf16 (hb_buffer_t *buffer, 722299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *text, 72333d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 724299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 725299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 726299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 727299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U)) 728299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint16_t); 729299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 730299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 731299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 732299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 733299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf32 (hb_buffer_t *buffer, 734299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint32_t *text, 73533d13fdda99acaeffa9600737e8870278d053ebeBehdad Esfahbod unsigned int text_length HB_UNUSED, 736299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 737299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_length) 738299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 739299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1) 740299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod ADD_UTF (uint32_t); 741299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod#undef UTF_NEXT 742299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 743acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 744acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 745acdba3f90b232fc12fcb200dca2584481b339118Behdad EsfahbodHB_END_DECLS 746