#include "otlparse.h" #include "otlutils.h" static void otl_string_ensure( OTL_String string, OTL_UInt count, OTL_Parser parser ) { count += string->length; if ( count > string->capacity ) { OTL_UInt old_count = string->capacity; OTL_UInt new_count = old_count; OTL_Memory memory = parser->memory; while ( new_count < count ) new_count += (new_count >> 1) + 16; if ( OTL_MEM_RENEW_ARRAY( string->glyphs, old_count, new_count ) ) otl_parser_error( parser, OTL_Parse_Err_Memory ); string->capacity = new_count; } } #define OTL_STRING_ENSURE(str,count,parser) \ OTL_BEGIN_STMNT \ if ( (str)->length + (count) > (str)>capacity ) \ otl_string_ensure( str, count, parser ); \ OTL_END_STMNT OTL_LOCALDEF( OTL_UInt ) otl_parser_get_gindex( OTL_Parser parser ) { OTL_String in = parser->str_in; if ( in->cursor >= in->num_glyphs ) otl_parser_error( parser, OTL_Err_Parser_Internal ); return in->str[ in->cursor ].gindex; } OTL_LOCALDEF( void ) otl_parser_error( OTL_Parser parser, OTL_ParseError error; ) { parser->error = error; otl_longjmp( parser->jump_buffer, 1 ); } #define OTL_PARSER_UNCOVERED(x) otl_parser_error( x, OTL_Parse_Err_UncoveredGlyph ); OTL_LOCAL( void ) otl_parser_check_property( OTL_Parser parser, OTL_UInt gindex, OTL_UInt flags, OTL_UInt *aproperty ); OTL_LOCALDEF( void ) otl_parser_replace_1( OTL_Parser parser, OTL_UInt gindex ) { OTL_String in = parser->str_in; OTL_String out = parser->str_out; OTL_StringGlyph glyph, in_glyph; /* sanity check */ if ( in == NULL || out == NULL || in->length == 0 || in->cursor >= in->length ) { /* report as internal error, since these should */ /* never happen !! */ otl_parser_error( parser, OTL_Err_Parse_Internal ); } OTL_STRING_ENSURE( out, 1, parser ); glyph = out->glyphs + out->length; in_glyph = in->glyphs + in->cursor; glyph->gindex = gindex; glyph->property = in_glyph->property; glyph->lig_component = in_glyph->lig_component; glyph->lig_id = in_glyph->lig_id; out->length += 1; out->cursor = out->length; in->cursor += 1; } OTL_LOCALDEF( void ) otl_parser_replace_n( OTL_Parser parser, OTL_UInt count, OTL_Bytes indices ) { OTL_UInt lig_component, lig_id, property; OTL_String in = parser->str_in; OTL_String out = parser->str_out; OTL_StringGlyph glyph, in_glyph; OTL_Bytes p = indices; /* sanity check */ if ( in == NULL || out == NULL || in->length == 0 || in->cursor >= in->length ) { /* report as internal error, since these should */ /* never happen !! */ otl_parser_error( parser, OTL_Err_Parse_Internal ); } OTL_STRING_ENSURE( out, count, parser ); glyph = out->glyphs + out->length; in_glyph = in->glyphs + in->cursor; glyph->gindex = gindex; lig_component = in_glyph->lig_component; lig_id = in_glyph->lid_id; property = in_glyph->property; for ( ; count > 0; count-- ) { glyph->gindex = OTL_NEXT_USHORT(p); glyph->property = property; glyph->lig_component = lig_component; glyph->lig_id = lig_id; out->length ++; } out->cursor = out->length; in->cursor += 1; }