hb-buffer.cc revision c54599ad269380c7aa28d885fcfd660fc2c10a7b
1a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod/* 22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 1998-2004 David Turner and Werner Lemberg 32409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2004,2007,2009,2010 Red Hat, Inc. 405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod * Copyright © 2011,2012 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" 317f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod#include "hb-utf-private.hh" 329f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 33f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod 34a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#ifndef HB_DEBUG_BUFFER 35a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#define HB_DEBUG_BUFFER (HB_DEBUG+0) 36a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#endif 37a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 38a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod/* Here is how the buffer works internally: 39a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 40910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * There are two info pointers: info and out_info. They always have 41910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * the same allocated size, but different lengths. 42a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 439d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As an optimization, both info and out_info may point to the 447e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod * same piece of memory, which is owned by info. This remains the 45cc1a8a938b4c13e76b58825a9e1951c4134e634aBehdad Esfahbod * case as long as out_len doesn't exceed i at any time. 46468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * In that case, swap_buffers() is no-op and the glyph operations operate 47910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * mostly in-place. 48a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod * 499d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As soon as out_info gets longer than info, out_info is moved over 50910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * to an alternate buffer (which we reuse the pos buffer for!), and its 51910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * current contents (out_len entries) are copied to the new place. 52468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * This should all remain transparent to the user. swap_buffers() then 53910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * switches info and out_info. 54a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */ 55a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 56c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod 57468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 58468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod/* Internal API */ 59468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 60468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool 61468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::enlarge (unsigned int size) 623567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 63468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (in_error)) 640594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 653567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 66468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int new_allocated = allocated; 67e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_position_t *new_pos = NULL; 68e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod hb_glyph_info_t *new_info = NULL; 69468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod bool separate_out = out_info != info; 703567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 71468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0])))) 72e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 733567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 7438b015e57ffa75d3b078a368c23685beb7c3f946Behdad Esfahbod while (size >= new_allocated) 7565e0063eae2f3adb25315b8bd7b0e7757aa960f3Behdad Esfahbod new_allocated += (new_allocated >> 1) + 32; 763567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 77468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0])); 78468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0])))) 79e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod goto done; 80e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 81468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0])); 82468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0])); 833567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 84e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahboddone: 853567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (unlikely (!new_pos || !new_info)) 860594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod in_error = true; 873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 883567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_pos)) 89468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos = new_pos; 903567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 913567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod if (likely (new_info)) 92468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info = new_info; 93468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 94468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = separate_out ? (hb_glyph_info_t *) pos : info; 95468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (likely (!in_error)) 96468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod allocated = new_allocated; 97468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 98468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return likely (!in_error); 99468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 100468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 101468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool 102468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::make_room_for (unsigned int num_in, 103468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int num_out) 104468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 1050594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod if (unlikely (!ensure (out_len + num_out))) return false; 106468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 107468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info == info && 108468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len + num_out > idx + num_in) 109468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod { 110468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod assert (have_output); 111468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 112468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = (hb_glyph_info_t *) pos; 113468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memcpy (out_info, info, out_len * sizeof (out_info[0])); 114468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 115468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 1160594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 117468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 118468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 119e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbodvoid * 120e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbodhb_buffer_t::get_scratch_buffer (unsigned int *size) 121e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod{ 1220594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_output = false; 1230594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_positions = false; 12447ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod 125e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod out_len = 0; 12647ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod out_info = info; 12747ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod 128e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod *size = allocated * sizeof (pos[0]); 129e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod return pos; 130e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod} 131e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod 132468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 13369cc492dc120847ed00cae65ec958593ebf550c5Behdad 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); 143d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod unicode = hb_unicode_funcs_get_default (); 144468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 14582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod clear (); 14682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod} 14782ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod 14882ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodvoid 14982ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodhb_buffer_t::clear (void) 15082ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod{ 15182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 15282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod return; 15382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod 154f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT; 155f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod props = default_props; 1560c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod flags = HB_BUFFER_FLAGS_DEFAULT; 157468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 15896fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod content_type = HB_BUFFER_CONTENT_TYPE_INVALID; 1590594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod in_error = false; 1600594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_output = false; 1610594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_positions = false; 1623567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 163468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx = 0; 164468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len = 0; 165468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = 0; 16647ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod out_info = info; 1673567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 168468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod serial = 0; 169f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod memset (allocated_var_bytes, 0, sizeof allocated_var_bytes); 170f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod memset (allocated_var_owner, 0, sizeof allocated_var_owner); 17105207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod 17205207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod memset (context, 0, sizeof context); 17305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod memset (context_len, 0, sizeof context_len); 1743567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1753567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 176468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 177468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::add (hb_codepoint_t codepoint, 178468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster) 1793567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{ 180468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *glyph; 181468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 182468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!ensure (len + 1))) return; 183468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 184468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph = &info[len]; 185468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 186468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memset (glyph, 0, sizeof (*glyph)); 187468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->codepoint = codepoint; 18866ac2ff32e24f0d5658ca172147613081a133847Behdad Esfahbod glyph->mask = 1; 189468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod glyph->cluster = cluster; 190468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 191468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len++; 1923567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod} 1936b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 194468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 1950bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbodhb_buffer_t::remove_output (void) 1960bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod{ 1970bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod if (unlikely (hb_object_is_inert (this))) 1980bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod return; 1990bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod 2000bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod have_output = false; 2010bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod have_positions = false; 2020bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod 2030bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod out_len = 0; 2040bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod out_info = info; 2050bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod} 2060bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod 2070bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbodvoid 208468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_output (void) 209c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{ 210468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 211468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 212468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 2130594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_output = true; 2140594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_positions = false; 215a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod 216468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = 0; 217468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = info; 218468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 219468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 220468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 221468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_positions (void) 222468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 223468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (hb_object_is_inert (this))) 224468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 225468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 2260594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_output = false; 2270594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_positions = true; 228468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 22947ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod out_len = 0; 23047ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod out_info = info; 23147ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod 232468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod memset (pos, 0, sizeof (pos[0]) * len); 233468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 234468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 235468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 236468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::swap_buffers (void) 237468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 238468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (in_error)) return; 239468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 240468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod assert (have_output); 2410594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod have_output = false; 242468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 243468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (out_info != info) 244e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod { 245468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t *tmp_string; 246468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod tmp_string = info; 247468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info = out_info; 248468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info = tmp_string; 249468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos = (hb_glyph_position_t *) out_info; 250468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 251468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 252468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int tmp; 253468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod tmp = len; 254468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod len = out_len; 255468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len = tmp; 256468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 257468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx = 0; 258468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 259e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod 26069cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod 261468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 2629ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbodhb_buffer_t::replace_glyphs (unsigned int num_in, 2639ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod unsigned int num_out, 2648e3715f8a16b315c1c7dd4b256e7f68a36c53e7cBehdad Esfahbod const uint32_t *glyph_data) 2659ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod{ 26669cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod if (unlikely (!make_room_for (num_in, num_out))) return; 2679ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod 268e88e14421a33ca5bdfd76bc0b2f801fcb6e78911Behdad Esfahbod merge_clusters (idx, idx + num_in); 2699ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod 270e88e14421a33ca5bdfd76bc0b2f801fcb6e78911Behdad Esfahbod hb_glyph_info_t orig_info = info[idx]; 2719ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod hb_glyph_info_t *pinfo = &out_info[out_len]; 2729ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod for (unsigned int i = 0; i < num_out; i++) 2739ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod { 2749ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod *pinfo = orig_info; 2759ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod pinfo->codepoint = glyph_data[i]; 2769ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod pinfo++; 2779ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod } 2789ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod 2799ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod idx += num_in; 2809ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod out_len += num_out; 2819ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod} 2829ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod 2839ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbodvoid 284468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::output_glyph (hb_codepoint_t glyph_index) 285468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 28669cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod if (unlikely (!make_room_for (0, 1))) return; 287468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 288468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 289468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len].codepoint = glyph_index; 290468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 291468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 292468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 293468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 294468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 295b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbodhb_buffer_t::output_info (hb_glyph_info_t &glyph_info) 296b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod{ 297b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod if (unlikely (!make_room_for (0, 1))) return; 298b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod 299b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod out_info[out_len] = glyph_info; 300b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod 301b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod out_len++; 302b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod} 303b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod 304b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbodvoid 305468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::copy_glyph (void) 306468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 30769cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod if (unlikely (!make_room_for (0, 1))) return; 308468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 309468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len] = info[idx]; 310468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 311468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 312468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 313468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 314468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 315468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::replace_glyph (hb_codepoint_t glyph_index) 316468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 31769cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod if (unlikely (out_info != info || out_len != idx)) { 31869cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod if (unlikely (!make_room_for (1, 1))) return; 31969cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod out_info[out_len] = info[idx]; 32069cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod } 321468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_info[out_len].codepoint = glyph_index; 322468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 323468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod idx++; 324468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod out_len++; 325468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 326468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 32769cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod 328468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 329468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::set_masks (hb_mask_t value, 330468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t mask, 331468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster_start, 332468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int cluster_end) 333468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 334468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_mask_t not_mask = ~mask; 335468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod value &= mask; 336468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 337468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!mask) 338468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 339468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 340468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (cluster_start == 0 && cluster_end == (unsigned int)-1) { 341468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int count = len; 342468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 343468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i].mask = (info[i].mask & not_mask) | value; 344468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 345468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 346468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 347468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int count = len; 348468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 349468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) 350468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i].mask = (info[i].mask & not_mask) | value; 351468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 352468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 353468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 354468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_range (unsigned int start, 355468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int end) 356468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 357468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int i, j; 358468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 359468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (start == end - 1) 360468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 361468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 362468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 363468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_info_t t; 364468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 365468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod t = info[i]; 366468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[i] = info[j]; 367468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod info[j] = t; 368468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 369468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 370468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (pos) { 371468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = start, j = end - 1; i < j; i++, j--) { 372468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod hb_glyph_position_t t; 373468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 374468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod t = pos[i]; 375468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos[i] = pos[j]; 376468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod pos[j] = t; 377468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 378468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 379468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 380468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 381468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 382468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse (void) 383468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 384468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!len)) 385468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 386468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 387468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (0, len); 388468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod} 389468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 390468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid 391468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_clusters (void) 392468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{ 393468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod unsigned int i, start, count, last_cluster; 394468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 395468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (unlikely (!len)) 396468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return; 397468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 398468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse (); 399468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod 400468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod count = len; 401468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod start = 0; 402468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod last_cluster = info[0].cluster; 403468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod for (i = 1; i < count; i++) { 404468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (last_cluster != info[i].cluster) { 405468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (start, i); 406468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod start = i; 407468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod last_cluster = info[i].cluster; 408468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 409468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod } 410468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod reverse_range (start, i); 411a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod} 412a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod 41302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodvoid 414d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodhb_buffer_t::merge_clusters (unsigned int start, 415d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod unsigned int end) 416d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod{ 417fe3dabc08df7501010564f8844bd4d11771cc6a4Behdad Esfahbod if (unlikely (end - start < 2)) 418cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod return; 419cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod 420cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod unsigned int cluster = info[start].cluster; 421d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod 422d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod for (unsigned int i = start + 1; i < end; i++) 423cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod cluster = MIN (cluster, info[i].cluster); 424cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod 425cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod /* Extend end */ 426cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod while (end < len && info[end - 1].cluster == info[end].cluster) 427cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod end++; 428cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod 429cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod /* Extend start */ 430cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod while (idx < start && info[start - 1].cluster == info[start].cluster) 431cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod start--; 432cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod 433cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod /* If we hit the start of buffer, continue in out-buffer. */ 434cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod if (idx == start) 435cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) 436cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod out_info[i - 1].cluster = cluster; 437cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod 438d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod for (unsigned int i = start; i < end; i++) 439cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod info[i].cluster = cluster; 440d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod} 441d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodvoid 442d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodhb_buffer_t::merge_out_clusters (unsigned int start, 443d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod unsigned int end) 444d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod{ 445fe3dabc08df7501010564f8844bd4d11771cc6a4Behdad Esfahbod if (unlikely (end - start < 2)) 44672c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod return; 44772c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod 448cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod unsigned int cluster = out_info[start].cluster; 449d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod 450d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod for (unsigned int i = start + 1; i < end; i++) 451cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod cluster = MIN (cluster, out_info[i].cluster); 45272c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod 45372c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod /* Extend start */ 45472c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod while (start && out_info[start - 1].cluster == out_info[start].cluster) 45572c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod start--; 45672c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod 4575ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod /* Extend end */ 4585ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster) 4595ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod end++; 4605ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod 461e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod /* If we hit the end of out-buffer, continue in buffer. */ 462e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod if (end == out_len) 463e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) 464e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod info[i].cluster = cluster; 465e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod 466d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod for (unsigned int i = start; i < end; i++) 467cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod out_info[i].cluster = cluster; 468d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod} 469d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod 470d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodvoid 47102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodhb_buffer_t::guess_properties (void) 47202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod{ 47396fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod if (unlikely (!len)) return; 47496fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE); 47596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod 47602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod /* If script is set to INVALID, guess from buffer contents */ 47702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod if (props.script == HB_SCRIPT_INVALID) { 47802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod for (unsigned int i = 0; i < len; i++) { 479208f70f0553d73d2908b21b9552298029482a8b9Behdad Esfahbod hb_script_t script = unicode->script (info[i].codepoint); 48002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod if (likely (script != HB_SCRIPT_COMMON && 48102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod script != HB_SCRIPT_INHERITED && 48202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod script != HB_SCRIPT_UNKNOWN)) { 48302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod props.script = script; 48402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod break; 48502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod } 48602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod } 48702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod } 48802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod 48902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod /* If direction is set to INVALID, guess from script */ 49002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod if (props.direction == HB_DIRECTION_INVALID) { 49102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod props.direction = hb_script_get_horizontal_direction (props.script); 49202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod } 49302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod 49402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod /* If language is not set, use default language from locale */ 49502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod if (props.language == HB_LANGUAGE_INVALID) { 49602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod /* TODO get_default_for_script? using $LANGUAGE */ 49702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod props.language = hb_language_get_default (); 49802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod } 49902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod} 50002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod 50102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod 502a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodstatic inline void 503a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahboddump_var_allocation (const hb_buffer_t *buffer) 504a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{ 505a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod char buf[80]; 506a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod for (unsigned int i = 0; i < 8; i++) 507b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod buf[i] = '0' + buffer->allocated_var_bytes[7 - i]; 508a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod buf[8] = '\0'; 509a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod DEBUG_MSG (BUFFER, buffer, 510a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod "Current var allocation: %s", 511a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod buf); 512a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod} 5133567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod 514f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner) 515f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{ 516b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod assert (byte_i < 8 && byte_i + count <= 8); 517a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 518a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod if (DEBUG (BUFFER)) 519a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod dump_var_allocation (this); 520a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod DEBUG_MSG (BUFFER, this, 521a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod "Allocating var bytes %d..%d for %s", 522a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod byte_i, byte_i + count - 1, owner); 523a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 524f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod for (unsigned int i = byte_i; i < byte_i + count; i++) { 525f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod assert (!allocated_var_bytes[i]); 526f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_bytes[i]++; 527f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_owner[i] = owner; 528f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod } 529f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod} 530f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 531f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner) 532f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{ 533b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod if (DEBUG (BUFFER)) 534b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod dump_var_allocation (this); 535b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod 536a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod DEBUG_MSG (BUFFER, this, 537a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod "Deallocating var bytes %d..%d for %s", 538a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod byte_i, byte_i + count - 1, owner); 539a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 540b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod assert (byte_i < 8 && byte_i + count <= 8); 541f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod for (unsigned int i = byte_i; i < byte_i + count; i++) { 542b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod assert (allocated_var_bytes[i]); 543b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod assert (0 == strcmp (allocated_var_owner[i], owner)); 544f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod allocated_var_bytes[i]--; 545f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod } 546f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod} 547f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 548965c280de09b49d711cb78d629da321c802084deBehdad Esfahbodvoid hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner) 549965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod{ 550965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod if (DEBUG (BUFFER)) 551965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod dump_var_allocation (this); 552965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod 553965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod DEBUG_MSG (BUFFER, this, 554965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod "Asserting var bytes %d..%d for %s", 555965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod byte_i, byte_i + count - 1, owner); 556965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod 557965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod assert (byte_i < 8 && byte_i + count <= 8); 558965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod for (unsigned int i = byte_i; i < byte_i + count; i++) { 559965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod assert (allocated_var_bytes[i]); 560965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod assert (0 == strcmp (allocated_var_owner[i], owner)); 561965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod } 562965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod} 563965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod 564a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodvoid hb_buffer_t::deallocate_var_all (void) 565a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{ 566a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes)); 567a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod memset (allocated_var_owner, 0, sizeof (allocated_var_owner)); 568a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod} 569f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod 5706b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */ 5716b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod 572b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t * 573c54599ad269380c7aa28d885fcfd660fc2c10a7bBehdad Esfahbodhb_buffer_create (void) 5749f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{ 575b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod hb_buffer_t *buffer; 576b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod 57747e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!(buffer = hb_object_create<hb_buffer_t> ())) 578f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod return hb_buffer_get_empty (); 5799f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod 580468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reset (); 5815ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 58211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod return buffer; 58311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 5847a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 58511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_t * 58680a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_get_empty (void) 58780a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod{ 588f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod static const hb_buffer_t _hb_buffer_nil = { 589f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod HB_OBJECT_HEADER_STATIC, 590f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod 591d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), 592f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod _HB_BUFFER_PROPS_DEFAULT, 5930c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod HB_BUFFER_FLAGS_DEFAULT, 594f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod 59596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod HB_BUFFER_CONTENT_TYPE_INVALID, 5960594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod true, /* in_error */ 5970594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod true, /* have_output */ 5980594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod true /* have_positions */ 59905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod 60005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod /* Zero is good enough for everything else. */ 601f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod }; 602f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod 603f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod return const_cast<hb_buffer_t *> (&_hb_buffer_nil); 60480a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod} 60580a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod 60680a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_t * 60711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_reference (hb_buffer_t *buffer) 60811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 60947e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod return hb_object_reference (buffer); 61011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 611f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 6127a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 61311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_destroy (hb_buffer_t *buffer) 6147a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{ 61547e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod if (!hb_object_destroy (buffer)) return; 61611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 6175ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 6185ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 6197e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod free (buffer->info); 6201b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod free (buffer->pos); 62111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 622b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod free (buffer); 6237a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 6247a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 6255fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t 6265fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_set_user_data (hb_buffer_t *buffer, 6275fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key, 6285fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod void * data, 62933ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod hb_destroy_func_t destroy, 63033ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod hb_bool_t replace) 6315fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 63233ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod return hb_object_set_user_data (buffer, key, data, destroy, replace); 6335fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 6345fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 6355fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid * 6365fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_get_user_data (hb_buffer_t *buffer, 6375fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod hb_user_data_key_t *key) 6385fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{ 6395fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod return hb_object_get_user_data (buffer, key); 6405fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod} 6415fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod 6425ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 6435ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 64496fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodhb_buffer_set_content_type (hb_buffer_t *buffer, 64596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod hb_buffer_content_type_t content_type) 64696fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod{ 64796fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod buffer->content_type = content_type; 64896fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod} 64996fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod 65096fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodhb_buffer_content_type_t 65196fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodhb_buffer_get_content_type (hb_buffer_t *buffer) 65296fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod{ 65396fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod return buffer->content_type; 65496fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod} 65596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod 65696fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod 65796fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodvoid 6585ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 6595ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_t *unicode) 6605ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 661e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 662e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 663e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 6640465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod if (!unicode) 665d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod unicode = hb_unicode_funcs_get_default (); 666d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod 6670465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod 6685ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_reference (unicode); 6695ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_unicode_funcs_destroy (buffer->unicode); 6705ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod buffer->unicode = unicode; 6715ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 6725ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 6735ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_unicode_funcs_t * 6745ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_unicode_funcs (hb_buffer_t *buffer) 6755ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 6765ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod return buffer->unicode; 6775ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 6785ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 6795ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid 6805ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_direction (hb_buffer_t *buffer, 6815ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod hb_direction_t direction) 6825ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 6835ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 684e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 685e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 686e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 6874e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.direction = direction; 6885ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 6895ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 6905ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_direction_t 6915ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_direction (hb_buffer_t *buffer) 6925ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{ 6934e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.direction; 6945ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod} 6955ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 696ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 697ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_script (hb_buffer_t *buffer, 698ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_script_t script) 699ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 700e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 701e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 702e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 7034e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.script = script; 704ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 705ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 706ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_script_t 707ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_script (hb_buffer_t *buffer) 708ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 7094e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.script; 710ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 711ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 712ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid 713ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_language (hb_buffer_t *buffer, 714ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod hb_language_t language) 715ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 716e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 717e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod return; 718e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod 7194e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod buffer->props.language = language; 720ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 721ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 722ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_language_t 723ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_language (hb_buffer_t *buffer) 724ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{ 7254e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod return buffer->props.language; 726ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod} 727ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod 7280c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodvoid 7290c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodhb_buffer_set_flags (hb_buffer_t *buffer, 7300c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod hb_buffer_flags_t flags) 7310c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod{ 7320c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 7330c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod return; 7340c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod 7350c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod buffer->flags = flags; 7360c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod} 7370c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod 7380c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodhb_buffer_flags_t 7390c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodhb_buffer_get_flags (hb_buffer_t *buffer) 7400c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod{ 7410c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod return buffer->flags; 7420c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod} 7430c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod 7445ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod 7457a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid 746c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_reset (hb_buffer_t *buffer) 747c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 748468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reset (); 7497a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod} 7507a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod 75182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodvoid 75282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodhb_buffer_clear (hb_buffer_t *buffer) 75382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod{ 75482ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod buffer->clear (); 75582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod} 75682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod 757a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbodhb_bool_t 75802a534b23f2d1e7475109563b9f61221ed020e8bRyan Lortiehb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) 759f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{ 760468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod return buffer->ensure (size); 761f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod} 762f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod 763aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_bool_t 764aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_buffer_allocation_successful (hb_buffer_t *buffer) 765aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod{ 766aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod return !buffer->in_error; 767aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod} 768aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod 769f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid 770f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbodhb_buffer_add (hb_buffer_t *buffer, 771f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod hb_codepoint_t codepoint, 772f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod unsigned int cluster) 7736b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{ 77466ac2ff32e24f0d5658ca172147613081a133847Behdad Esfahbod buffer->add (codepoint, cluster); 77505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod buffer->clear_context (1); 7769111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod} 7779111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod 778c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_bool_t 779c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_set_length (hb_buffer_t *buffer, 780c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod unsigned int length) 781c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{ 782e1ac38f8dd04c29d2d4140f5a492cdaf25d72901Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 783e1ac38f8dd04c29d2d4140f5a492cdaf25d72901Behdad Esfahbod return length == 0; 784e1ac38f8dd04c29d2d4140f5a492cdaf25d72901Behdad Esfahbod 785468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod if (!buffer->ensure (length)) 7860594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 787c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 788c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod /* Wipe the new space */ 789c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (length > buffer->len) { 790c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len)); 791c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod if (buffer->have_positions) 792c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len)); 793c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod } 794c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 795c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod buffer->len = length; 79605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod 79705207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod if (!length) 79805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod buffer->clear_context (0); 79905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod buffer->clear_context (1); 80005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod 8010594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 802c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod} 803c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod 80411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int 8053d14528b8b2e7da425a9df7057fc9fb326d8298cBehdad Esfahbodhb_buffer_get_length (hb_buffer_t *buffer) 80611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 8076960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod return buffer->len; 80811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 80911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 81011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 81111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_info_t * 81270566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_infos (hb_buffer_t *buffer, 81370566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 81411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 81570566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 81670566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 81770566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 8187e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod return (hb_glyph_info_t *) buffer->info; 81911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 82011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 82111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */ 82211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_position_t * 82370566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_positions (hb_buffer_t *buffer, 82470566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie unsigned int *length) 82511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{ 826314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod if (!buffer->have_positions) 827468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->clear_positions (); 82811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod 82970566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie if (length) 83070566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie *length = buffer->len; 83170566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie 8321b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod return (hb_glyph_position_t *) buffer->pos; 83311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod} 834fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod 835ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 836ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse (hb_buffer_t *buffer) 837ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 838468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reverse (); 839ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 840ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 841ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid 842ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse_clusters (hb_buffer_t *buffer) 843ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{ 844468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod buffer->reverse_clusters (); 845ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod} 846ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod 84702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodvoid 84802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodhb_buffer_guess_properties (hb_buffer_t *buffer) 84902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod{ 85002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod buffer->guess_properties (); 85102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod} 85202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod 8537f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbodtemplate <typename T> 8547f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbodstatic inline void 8557f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbodhb_buffer_add_utf (hb_buffer_t *buffer, 8567f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod const T *text, 8577f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod int text_length, 8587f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod unsigned int item_offset, 8597f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod int item_length) 8607f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod{ 8617f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || 8627f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); 8637f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod 8647f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod if (unlikely (hb_object_is_inert (buffer))) 8657f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod return; 8667f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod 8671f66c3c1a0eb869c0d85a015235313177e0cec62Behdad Esfahbod if (text_length == -1) 8681f66c3c1a0eb869c0d85a015235313177e0cec62Behdad Esfahbod text_length = hb_utf_strlen (text); 8697f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod 8707f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod if (item_length == -1) 8717f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod item_length = text_length - item_offset; 8727f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod 8737f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod buffer->ensure (buffer->len + item_length * sizeof (T) / 4); 8747f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod 875da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod /* If buffer is empty and pre-context provided, install it. 876da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod * This check is written this way, to make sure people can 877da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod * provide pre-context in one add_utf() call, then provide 878da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod * text in a follow-up call. See: 879da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod * 880da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13 881da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod */ 882da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod if (!buffer->len && item_offset > 0) 88305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod { 88405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod /* Add pre-context */ 88505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod buffer->clear_context (0); 88605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod const T *prev = text + item_offset; 88705207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod const T *start = text; 88805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH) 88905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod { 89005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod hb_codepoint_t u; 89105207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod prev = hb_utf_prev (prev, start, &u); 89205207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod buffer->context[0][buffer->context_len[0]++] = u; 89305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod } 89405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod } 89505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod 89605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod const T *next = text + item_offset; 8977f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod const T *end = next + item_length; 89805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod while (next < end) 89905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod { 9007f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod hb_codepoint_t u; 9017f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod const T *old_next = next; 9027f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod next = hb_utf_next (next, end, &u); 90366ac2ff32e24f0d5658ca172147613081a133847Behdad Esfahbod buffer->add (u, old_next - (const T *) text); 90405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod } 90505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod 90605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod /* Add post-context */ 90705207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod buffer->clear_context (1); 90805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod end = text + text_length; 90905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH) 91005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod { 91105207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod hb_codepoint_t u; 91205207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod next = hb_utf_next (next, end, &u); 91305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod buffer->context[1][buffer->context_len[1]++] = u; 9147f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod } 9157f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod 9167f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE; 917299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 918299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 919299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 920299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf8 (hb_buffer_t *buffer, 921299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const char *text, 922944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod int text_length, 923299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 924944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod int item_length) 925299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 9267f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, item_length); 927299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 928299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod 929299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 930299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf16 (hb_buffer_t *buffer, 931299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint16_t *text, 932944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod int text_length, 933299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 934944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod int item_length) 935299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 9367f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); 9370e0a4da9b7677a09e00d27313236e1f333864dd6Behdad Esfahbod} 9380e0a4da9b7677a09e00d27313236e1f333864dd6Behdad Esfahbod 939299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid 940299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf32 (hb_buffer_t *buffer, 941299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod const uint32_t *text, 942944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod int text_length, 943299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod unsigned int item_offset, 944944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod int item_length) 945299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{ 9467f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); 947299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod} 948acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 949acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 95039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodstatic int 95139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodcompare_info_codepoint (const hb_glyph_info_t *pa, 95239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod const hb_glyph_info_t *pb) 95339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod{ 95439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod return (int) pb->codepoint - (int) pa->codepoint; 95539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod} 95639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 95739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodstatic inline void 95839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodnormalize_glyphs_cluster (hb_buffer_t *buffer, 95939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod unsigned int start, 96039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod unsigned int end, 96139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod bool backward) 96239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod{ 96339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod hb_glyph_position_t *pos = buffer->pos; 96439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 96539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod /* Total cluster advance */ 96639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod hb_position_t total_x_advance = 0, total_y_advance = 0; 96739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod for (unsigned int i = start; i < end; i++) 96839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod { 96939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod total_x_advance += pos[i].x_advance; 97039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod total_y_advance += pos[i].y_advance; 97139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod } 97239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 97339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod hb_position_t x_advance = 0, y_advance = 0; 97439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod for (unsigned int i = start; i < end; i++) 97539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod { 97639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[i].x_offset += x_advance; 97739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[i].y_offset += y_advance; 97839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 97939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod x_advance += pos[i].x_advance; 98039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod y_advance += pos[i].y_advance; 98139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 98239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[i].x_advance = 0; 98339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[i].y_advance = 0; 98439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod } 98539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 98639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod if (backward) 98739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod { 98839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod /* Transfer all cluster advance to the last glyph. */ 98939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[end - 1].x_advance = total_x_advance; 99039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[end - 1].y_advance = total_y_advance; 99139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 99239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start); 99339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod } else { 99439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod /* Transfer all cluster advance to the first glyph. */ 99539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[start].x_advance += total_x_advance; 99639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[start].y_advance += total_y_advance; 99739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod for (unsigned int i = start + 1; i < end; i++) { 99839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[i].x_offset -= total_x_advance; 99939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod pos[i].y_offset -= total_y_advance; 100039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod } 100139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1); 100239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod } 100339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod} 100439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 100539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodvoid 100639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodhb_buffer_normalize_glyphs (hb_buffer_t *buffer) 100739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod{ 100839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod assert (buffer->have_positions); 10097d37280600c157f3c4eae8746e99511702a58e8fBehdad Esfahbod assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); 101039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 101139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); 101239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 101339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod unsigned int count = buffer->len; 101439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod if (unlikely (!count)) return; 101539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod hb_glyph_info_t *info = buffer->info; 101639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod 101739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod unsigned int start = 0; 101839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod unsigned int end; 101939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod for (end = start + 1; end < count; end++) 102039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod if (info[start].cluster != info[end].cluster) { 102139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod normalize_glyphs_cluster (buffer, start, end, backward); 102239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod start = end; 102339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod } 102439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod normalize_glyphs_cluster (buffer, start, end, backward); 102539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod} 1026f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1027f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1028f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod/* 1029f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod * Serialize 1030f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod */ 1031f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1032f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodstatic const char *serialize_formats[] = { 1033f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod "TEXT", 1034f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod "JSON", 1035f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod NULL 1036f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod}; 1037f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1038072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbodconst char ** 1039072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbodhb_buffer_serialize_list_formats (void) 1040072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod{ 1041072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod return serialize_formats; 1042072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod} 1043072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod 1044f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_format_t 1045f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_format_from_string (const char *str, int len) 1046f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{ 1047f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod /* Upper-case it. */ 1048f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020); 1049f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod} 1050f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1051f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodconst char * 1052f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) 1053f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{ 1054f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod switch (format) 1055f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1056f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0]; 1057f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1]; 1058f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod default: 1059f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL; 1060f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1061f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod} 1062f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1063f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodstatic unsigned int 1064f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, 1065f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int start, 1066f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int end, 1067f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char *buf, 1068f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int buf_size, 1069f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int *buf_consumed, 1070f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_font_t *font, 1071f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_buffer_serialize_flags_t flags) 1072f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{ 1073f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); 1074f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); 1075f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1076f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *buf_consumed = 0; 1077f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod for (unsigned int i = start; i < end; i++) 1078f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1079f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char b[1024]; 1080f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char *p = b; 1081f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1082f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod /* In the following code, we know b is large enough that no overflow can happen. */ 1083f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1084f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END 1085f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1086f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (i) 1087f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = ','; 1088f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1089f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = '{'; 1090f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1091f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod APPEND ("\"g\":"); 1092f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) 1093f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1094f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char g[128]; 1095f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g)); 1096f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = '"'; 1097f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod for (char *q = g; *q; q++) { 1098f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (*q == '"') 1099f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = '\\'; 1100f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = *q; 1101f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1102f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = '"'; 1103f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1104f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod else 1105f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); 1106f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1107f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { 1108f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster); 1109f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1110f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1111f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) 1112f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1113f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", 1114f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod pos[i].x_offset, pos[i].y_offset); 1115f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", 1116f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod pos[i].x_advance, pos[i].y_advance); 1117f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1118f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1119f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = '}'; 1120f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1121f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (buf_size > (p - b)) 1122f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1123f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int l = p - b; 1124f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod memcpy (buf, b, l); 1125f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod buf += l; 1126f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod buf_size -= l; 1127f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *buf_consumed += l; 1128f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *buf = '\0'; 1129f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } else 1130f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return i - start; 1131f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1132f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1133f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return end - start; 1134f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod} 1135f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1136f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodstatic unsigned int 1137f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, 1138f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int start, 1139f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int end, 1140f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char *buf, 1141f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int buf_size, 1142f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int *buf_consumed, 1143f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_font_t *font, 1144f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_buffer_serialize_flags_t flags) 1145f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{ 1146f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); 1147f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); 1148f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_direction_t direction = hb_buffer_get_direction (buffer); 1149f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1150f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *buf_consumed = 0; 1151f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod for (unsigned int i = start; i < end; i++) 1152f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1153f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char b[1024]; 1154f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char *p = b; 1155f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1156f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod /* In the following code, we know b is large enough that no overflow can happen. */ 1157f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1158f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (i) 1159f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = '|'; 1160f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1161f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) 1162f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1163f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_font_glyph_to_string (font, info[i].codepoint, p, 128); 1164f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += strlen (p); 1165f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1166f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod else 1167f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); 1168f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1169f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { 1170f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster); 1171f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1172f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1173f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) 1174f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1175f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (pos[i].x_offset || pos[i].y_offset) 1176f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset); 1177f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1178f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *p++ = '+'; 1179f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (HB_DIRECTION_IS_HORIZONTAL (direction) || pos[i].x_advance) 1180f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance); 1181f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (HB_DIRECTION_IS_VERTICAL (direction) || pos->y_advance) 1182f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance); 1183f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1184f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1185f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (buf_size > (p - b)) 1186f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1187f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int l = p - b; 1188f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod memcpy (buf, b, l); 1189f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod buf += l; 1190f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod buf_size -= l; 1191f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *buf_consumed += l; 1192f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *buf = '\0'; 1193f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } else 1194f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return i - start; 1195f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1196f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1197f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return end - start; 1198f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod} 1199f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1200f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod/* Returns number of items, starting at start, that were serialized. */ 1201f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodunsigned int 1202f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_glyphs (hb_buffer_t *buffer, 1203f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int start, 1204f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int end, 1205f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod char *buf, 1206f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int buf_size, 1207f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int *buf_consumed, 1208f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_font_t *font, /* May be NULL */ 1209f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_buffer_serialize_format_t format, 1210f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_buffer_serialize_flags_t flags) 1211f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{ 1212f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod assert (start <= end && end <= buffer->len); 1213f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1214f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod *buf_consumed = 0; 1215f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1216f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || 1217f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); 1218f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1219f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (unlikely (start == end)) 1220f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return 0; 1221f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1222f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod if (!font) 1223f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod font = hb_font_get_empty (); 1224f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1225f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod switch (format) 1226f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod { 1227f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod case HB_BUFFER_SERIALIZE_FORMAT_TEXT: 1228f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return _hb_buffer_serialize_glyphs_text (buffer, start, end, 1229f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod buf, buf_size, buf_consumed, 1230f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod font, flags); 1231f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1232f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod case HB_BUFFER_SERIALIZE_FORMAT_JSON: 1233f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return _hb_buffer_serialize_glyphs_json (buffer, start, end, 1234f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod buf, buf_size, buf_consumed, 1235f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod font, flags); 1236f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1237f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod default: 1238f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod case HB_BUFFER_SERIALIZE_FORMAT_INVALID: 1239f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return 0; 1240f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1241f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod } 1242f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod} 1243f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod 1244f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_bool_t 1245f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_deserialize_glyphs (hb_buffer_t *buffer, 1246f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod const char *buf, 1247f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int buf_len, 1248f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod unsigned int *buf_consumed, 1249f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_font_t *font, /* May be NULL */ 1250f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod hb_buffer_serialize_format_t format) 1251f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{ 1252f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod return false; 1253f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod} 1254