11512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* 21512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 1998-2004 David Turner and Werner Lemberg 31512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 2004,2007 Red Hat, Inc. 41512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 51512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library. 61512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 71512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Permission is hereby granted, without written agreement and without 81512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 91512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * software and its documentation for any purpose, provided that the 101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * all copies of this software. 121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DAMAGE. 181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Red Hat Author(s): Owen Taylor, Behdad Esfahbod 261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */ 271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-impl.h" 291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-buffer-private.h" 301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-gsub-private.h" 311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-gpos-private.h" 321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* Here is how the buffer works internally: 341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * There are two string pointers: in_string and out_string. They 361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * always have same allocated size, but different length and positions. 371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * As an optimization, both in_string and out_string may point to the 391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * same piece of memory, which is owned by in_string. This remains the 401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * case as long as: 411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * - copy_glyph() is called 431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * - replace_glyph() is called with inplace=TRUE 441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * - add_output_glyph() and add_output_glyphs() are not called 451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * In that case swap(), and copy_glyph(), and replace_glyph() are all 471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * mostly no-op. 481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * As soon an add_output_glyph[s]() or replace_glyph() with inplace=FALSE is 501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * called, out_string is moved over to an alternate buffer (alt_string), and 511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * its current contents (out_length entries) are copied to the alt buffer. 521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * This should all remain transparent to the user. swap() then switches 531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * in_string and alt_string. alt_string is not allocated until its needed, 541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * but after that it's grown with in_string unconditionally. 551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * The buffer->separate_out boolean keeps status of whether out_string points 571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * to in_string (FALSE) or alt_string (TRUE). 581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */ 591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* Internal API */ 611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error 63fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad EsfahbodHB_Buffer_ensure( HB_Buffer buffer, 641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt size ) 651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt new_allocated = buffer->allocated; 671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (size > new_allocated) 691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod while (size > new_allocated) 731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_allocated += (new_allocated >> 1) + 8; 741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( buffer->positions ) 761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( REALLOC_ARRAY( buffer->positions, new_allocated, HB_PositionRec ) ) 781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( REALLOC_ARRAY( buffer->in_string, new_allocated, HB_GlyphItemRec ) ) 821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( buffer->separate_out ) 851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) ) 871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string = buffer->alt_string; 901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string = buffer->in_string; 941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( buffer->alt_string ) 961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) ) 981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->allocated = new_allocated; 1031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 1061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error 109fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad EsfahbodHB_Buffer_duplicate_out_buffer( HB_Buffer buffer ) 1101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( !buffer->alt_string ) 1121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 1131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 1141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( buffer->alt_string, buffer->allocated, HB_GlyphItemRec ) ) 1161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 1171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string = buffer->alt_string; 1201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod memcpy( buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]) ); 1211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->separate_out = TRUE; 1221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 1241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* Public API */ 1271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1281512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Error 129fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad EsfahbodHB_Buffer_new( HB_Buffer *pbuffer ) 1301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Buffer buffer; 1321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 1331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC( buffer, sizeof( HB_BufferRec ) ) ) 1351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 1361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->allocated = 0; 1381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_string = NULL; 1391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->alt_string = NULL; 1401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->positions = NULL; 1411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 142fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad Esfahbod HB_Buffer_clear( buffer ); 1431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *pbuffer = buffer; 1451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 1471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodvoid 150fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad EsfahbodHB_Buffer_free( HB_Buffer buffer ) 1511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( buffer->in_string ); 1531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( buffer->alt_string ); 1541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string = NULL; 1551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( buffer->positions ); 1561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( buffer ); 1571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodvoid 160fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad EsfahbodHB_Buffer_clear( HB_Buffer buffer ) 1611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_length = 0; 1631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_length = 0; 1641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_pos = 0; 1651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_pos = 0; 1661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string = buffer->in_string; 1671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->separate_out = FALSE; 1681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->max_ligID = 0; 1691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1711512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Error 172fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad EsfahbodHB_Buffer_add_glyph( HB_Buffer buffer, 1731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt glyph_index, 1741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt properties, 1751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cluster ) 1761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 1781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_GlyphItem glyph; 1791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 180fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad Esfahbod error = HB_Buffer_ensure( buffer, buffer->in_length + 1 ); 1811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( error ) 1821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 1831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyph = &buffer->in_string[buffer->in_length]; 1851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyph->gindex = glyph_index; 1861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyph->properties = properties; 1871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyph->cluster = cluster; 1881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyph->component = 0; 1891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyph->ligID = 0; 1901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN; 1911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_length++; 1931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 1951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* HarfBuzz-Internal API */ 1981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1991512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 2001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_clear_output( HB_Buffer buffer ) 2011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 2021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_length = 0; 2031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_pos = 0; 2041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string = buffer->in_string; 2051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->separate_out = FALSE; 2061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 2071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2081512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 2091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_clear_positions( HB_Buffer buffer ) 2101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 2111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( !buffer->positions ) 2121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 2131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 2141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( buffer->positions, buffer->allocated, HB_PositionRec ) ) 2161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 2171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length); 2201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 2221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 2231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2241512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 2251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_swap( HB_Buffer buffer ) 2261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 2271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_GlyphItem tmp_string; 2281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int tmp_length; 2291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int tmp_pos; 2301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( buffer->separate_out ) 2321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 2331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod tmp_string = buffer->in_string; 2341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_string = buffer->out_string; 2351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string = tmp_string; 2361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->alt_string = buffer->out_string; 2371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod tmp_length = buffer->in_length; 2401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_length = buffer->out_length; 2411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_length = tmp_length; 2421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod tmp_pos = buffer->in_pos; 2441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_pos = buffer->out_pos; 2451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_pos = tmp_pos; 2461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 2471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* The following function copies `num_out' elements from `glyph_data' 2491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod to `buffer->out_string', advancing the in array pointer in the structure 2501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod by `num_in' elements, and the out array pointer by `num_out' elements. 2511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Finally, it sets the `length' field of `out' equal to 2521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod `pos' of the `out' structure. 2531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod If `component' is 0xFFFF, the component value from buffer->in_pos 2551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod will copied `num_out' times, otherwise `component' itself will 2561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod be used to fill the `component' fields. 2571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod If `ligID' is 0xFFFF, the ligID value from buffer->in_pos 2591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod will copied `num_out' times, otherwise `ligID' itself will 2601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod be used to fill the `ligID' fields. 2611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod The properties for all replacement glyphs are taken 2631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod from the glyph at position `buffer->in_pos'. 2641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod The cluster value for the glyph at position buffer->in_pos is used 2661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for all replacement glyphs */ 2671512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 2681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_add_output_glyphs( HB_Buffer buffer, 2691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort num_in, 2701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort num_out, 2711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort *glyph_data, 2721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort component, 2731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort ligID ) 2741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 2751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 2761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort i; 2771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt properties; 2781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cluster; 2791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 280fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad Esfahbod error = HB_Buffer_ensure( buffer, buffer->out_pos + num_out ); 2811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( error ) 2821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 2831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( !buffer->separate_out ) 2851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 286fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad Esfahbod error = HB_Buffer_duplicate_out_buffer( buffer ); 2871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( error ) 2881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 2891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod properties = buffer->in_string[buffer->in_pos].properties; 2921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cluster = buffer->in_string[buffer->in_pos].cluster; 2931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( component == 0xFFFF ) 2941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod component = buffer->in_string[buffer->in_pos].component; 2951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ligID == 0xFFFF ) 2961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ligID = buffer->in_string[buffer->in_pos].ligID; 2971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( i = 0; i < num_out; i++ ) 2991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 3001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_GlyphItem item = &buffer->out_string[buffer->out_pos + i]; 3011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->gindex = glyph_data[i]; 3031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->properties = properties; 3041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->cluster = cluster; 3051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->component = component; 3061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->ligID = ligID; 3071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN; 3081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 3091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_pos += num_in; 3111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_pos += num_out; 3121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_length = buffer->out_pos; 3141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 3161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 3171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3181512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 3191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_add_output_glyph( HB_Buffer buffer, 3201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt glyph_index, 3211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort component, 3221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort ligID ) 3231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 3241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort glyph_data = glyph_index; 3251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return _hb_buffer_add_output_glyphs ( buffer, 1, 1, 3271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod &glyph_data, component, ligID ); 3281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 3291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3301512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 3311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_copy_output_glyph ( HB_Buffer buffer ) 3321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 3331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 3341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 335fb47209c5b3aa992faf18d1a3f78b9d7682cf62fBehdad Esfahbod error = HB_Buffer_ensure( buffer, buffer->out_pos + 1 ); 3361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( error ) 3371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 3381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( buffer->separate_out ) 3401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 3411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos]; 3421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 3431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->in_pos++; 3451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_pos++; 3461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_length = buffer->out_pos; 3471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 3491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 3501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3511512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 3521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_replace_output_glyph( HB_Buffer buffer, 3531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt glyph_index, 3541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Bool inplace ) 3551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 3561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 3581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( inplace ) 3601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 3611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = _hb_buffer_copy_output_glyph ( buffer ); 3621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( error ) 3631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 3641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->out_string[buffer->out_pos-1].gindex = glyph_index; 3661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 3671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 3681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 3691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return _hb_buffer_add_output_glyph( buffer, glyph_index, 0xFFFF, 0xFFFF ); 3701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 3711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 3731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 3741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3751512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_UShort 3761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_hb_buffer_allocate_ligid( HB_Buffer buffer ) 3771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 3781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->max_ligID++; 3791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (HB_UNLIKELY (buffer->max_ligID == 0)) 3801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod buffer->max_ligID++; 3811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return buffer->max_ligID; 3831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 384