1 /****************************************************************************
5 * FreeType's OpenType validation module implementation (body).
7 * Copyright (C) 2004-2023 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
19 #include <freetype/tttables.h>
20 #include <freetype/tttags.h>
21 #include <freetype/ftotval.h>
22 #include <freetype/internal/ftobjs.h>
23 #include <freetype/internal/services/svotval.h>
30 /**************************************************************************
32 * The macro FT_COMPONENT is used in trace mode. It is an implicit
33 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
34 * messages during execution.
37 #define FT_COMPONENT otvmodule
41 otv_load_table( FT_Face face,
43 FT_Byte* volatile* table,
47 FT_Memory memory = FT_FACE_MEMORY( face );
50 error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len );
51 if ( FT_ERR_EQ( error, Table_Missing ) )
56 if ( FT_QALLOC( *table, *table_len ) )
59 error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
67 otv_validate( FT_Face volatile face,
75 FT_Error error = FT_Err_Ok;
76 FT_Byte* volatile base;
77 FT_Byte* volatile gdef;
78 FT_Byte* volatile gpos;
79 FT_Byte* volatile gsub;
80 FT_Byte* volatile jstf;
81 FT_Byte* volatile math;
82 FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf;
84 FT_UInt num_glyphs = (FT_UInt)face->num_glyphs;
85 FT_ValidatorRec volatile valid;
88 base = gdef = gpos = gsub = jstf = math = NULL;
89 len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0;
92 * XXX: OpenType tables cannot handle 32-bit glyph index,
93 * although broken TrueType can have 32-bit glyph index.
95 if ( face->num_glyphs > 0xFFFFL )
97 FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08lx) ",
99 FT_TRACE1(( "are not handled by OpenType tables\n" ));
105 if ( ot_flags & FT_VALIDATE_BASE )
107 error = otv_load_table( face, TTAG_BASE, &base, &len_base );
112 if ( ot_flags & FT_VALIDATE_GDEF )
114 error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef );
119 if ( ot_flags & FT_VALIDATE_GPOS )
121 error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos );
126 if ( ot_flags & FT_VALIDATE_GSUB )
128 error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub );
133 if ( ot_flags & FT_VALIDATE_JSTF )
135 error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf );
140 if ( ot_flags & FT_VALIDATE_MATH )
142 error = otv_load_table( face, TTAG_MATH, &math, &len_math );
147 /* validate tables */
151 ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
152 if ( ft_setjmp( valid.jump_buffer ) == 0 )
153 otv_BASE_validate( base, &valid );
161 ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
162 if ( ft_setjmp( valid.jump_buffer ) == 0 )
163 otv_GPOS_validate( gpos, num_glyphs, &valid );
171 ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
172 if ( ft_setjmp( valid.jump_buffer ) == 0 )
173 otv_GSUB_validate( gsub, num_glyphs, &valid );
181 ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
182 if ( ft_setjmp( valid.jump_buffer ) == 0 )
183 otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid );
191 ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
192 if ( ft_setjmp( valid.jump_buffer ) == 0 )
193 otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid );
201 ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT );
202 if ( ft_setjmp( valid.jump_buffer ) == 0 )
203 otv_MATH_validate( math, num_glyphs, &valid );
209 *ot_base = (FT_Bytes)base;
210 *ot_gdef = (FT_Bytes)gdef;
211 *ot_gpos = (FT_Bytes)gpos;
212 *ot_gsub = (FT_Bytes)gsub;
213 *ot_jstf = (FT_Bytes)jstf;
218 FT_Memory memory = FT_FACE_MEMORY( face );
229 FT_Memory memory = FT_FACE_MEMORY( face );
232 FT_FREE( math ); /* Can't return this as API is frozen */
240 const FT_Service_OTvalidateRec otvalid_interface =
242 otv_validate /* validate */
247 const FT_ServiceDescRec otvalid_services[] =
249 { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface },
255 otvalid_get_service( FT_Module module,
256 const char* service_id )
260 return ft_service_list_lookup( otvalid_services, service_id );
264 FT_CALLBACK_TABLE_DEF
265 const FT_Module_Class otv_module_class =
268 sizeof ( FT_ModuleRec ),
273 NULL, /* module-specific interface */
275 (FT_Module_Constructor)NULL, /* module_init */
276 (FT_Module_Destructor) NULL, /* module_done */
277 (FT_Module_Requester) otvalid_get_service /* get_interface */